Skip to content

Tailwind CSS#

Utility-first CSS framework for rapid UI development in Jac applications.

Overview#

Tailwind CSS provides low-level utility classes that you can compose to build custom designs. This approach is perfect for: - Rapid UI development - Consistent design systems - Responsive designs - Modern, utility-based styling

Example#

See the complete working example: examples/css-styling/tailwind-example/

Quick Start#

1. Install Tailwind CSS#

Add to package.json:

{
  "devDependencies": {
    "@tailwindcss/vite": "^4.0.0"
  }
}

2. Configure Vite#

Update vite.config.js:

import { defineConfig } from "vite";
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [tailwindcss()],
  // ... other config
});

3. Add Tailwind Directives#

Create global.css:

@import "tailwindcss";

4. Import CSS in Jac#

# Pages
cl import from react {useState, useEffect}
cl import ".global.css";

cl {
    def app() -> any {
        return <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
            <h1 className="text-3xl font-bold">Hello, Tailwind!</h1>
        </div>;
    }
}

Using Utility Classes#

Spacing#

<div className="p-4 m-2 gap-4">
    {/* padding: 1rem, margin: 0.5rem, gap: 1rem */}
</div>

Colors#

<div className="bg-blue-500 text-white hover:bg-blue-600">
    {/* Blue background, white text, darker blue on hover */}
</div>

Layout#

<div className="flex items-center justify-center">
    {/* Flexbox with centered items */}
</div>

Responsive#

<div className="text-sm md:text-lg lg:text-xl">
    {/* Small on mobile, large on tablet, xl on desktop */}
</div>

Dynamic Classes#

Combine static and dynamic classes:

let countColorClass = "text-gray-800" if count == 0 else ("text-green-600" if count > 0 else "text-red-600");

return <div className={"text-6xl font-bold " + countColorClass + " transition-colors duration-300"}>
    {count}
</div>;

Common Utility Patterns#

Buttons#

<button className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
    Click Me
</button>

Cards#

<div className="bg-white rounded-lg shadow-lg p-6">
    <h2 className="text-2xl font-bold mb-4">Card Title</h2>
    <p className="text-gray-600">Card content</p>
</div>

Flexbox Layouts#

<div className="flex flex-col md:flex-row gap-4">
    <div className="flex-1">Column 1</div>
    <div className="flex-1">Column 2</div>
</div>

Grid Layouts#

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
</div>

Best Practices#

1. Use Responsive Prefixes#

Design mobile-first with responsive breakpoints:

<div className="text-sm md:text-base lg:text-lg">
    Responsive text
</div>

2. Combine Utilities#

Chain multiple utilities for complex styles:

<button className="bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 px-6 rounded-lg shadow-lg transition-all duration-200 transform hover:scale-105">
    Button
</button>

3. Use Hover/Focus States#

Leverage pseudo-class variants:

<button className="bg-blue-500 hover:bg-blue-600 focus:ring-2 focus:ring-blue-300">
    Interactive Button
</button>

4. Leverage Transitions#

Add smooth transitions:

<div className="transition-all duration-200 hover:scale-105">
    Hoverable element
</div>

5. Use Arbitrary Values#

For custom values:

<div className="w-[500px] h-[300px] bg-[#1da1f2]">
    Custom dimensions and color
</div>

Configuration#

Customize Tailwind in tailwind.config.js:

export default {
  theme: {
    extend: {
      colors: {
        'brand': '#your-color',
      },
      spacing: {
        '128': '32rem',
      },
    },
  },
}

Advantages#

  • Rapid development with utility classes
  • Consistent design system
  • Responsive by default
  • Small bundle size (unused classes are purged)
  • Great documentation and ecosystem
  • Highly customizable

Limitations#

  • Can get verbose with many classes
  • Learning curve for utility-first approach
  • Less semantic than component-based CSS
  • Requires build step
  • HTML can get cluttered

When to Use#

Choose Tailwind CSS when:

  • You want to build UIs quickly
  • You prefer utility classes over custom CSS
  • You need a consistent design system
  • You're building modern, responsive designs
  • You want a small bundle size
  • You prefer configuration over writing CSS

Purging Unused Classes#

Tailwind automatically removes unused classes in production builds, keeping bundle size small. No configuration needed with Vite plugin.

Customization#

Custom Colors#

// tailwind.config.js
export default {
  theme: {
    extend: {
      colors: {
        'brand-blue': '#1e40af',
        'brand-purple': '#7c3aed',
      },
    },
  },
}

Custom Spacing#

theme: {
  extend: {
    spacing: {
      '18': '4.5rem',
      '88': '22rem',
    },
  },
}

Next Steps#

Resources#