JavaScript

10 Tailwind CSS Tips You Need to Know

10 Tailwind CSS Tips You Need to Know

Tailwind CSS has revolutionized how we write CSS. Its utility-first approach enables rapid UI development while keeping your styles maintainable. Here are 10 tips to help you get the most out of Tailwind.

1. Use @apply Sparingly

While @apply lets you extract repeated utility patterns, overusing it defeats Tailwind's purpose. Reserve it for truly reusable components:

css
/* Good: Extracting a button component */
.btn {
  @apply px-4 py-2 rounded-lg font-medium transition-colors;
}
.btn-primary {
  @apply bg-blue-600 text-white hover:bg-blue-700;
}

/* Better: Use a component in your framework instead */
/* React, Vue, etc. components are more flexible than CSS classes */
💡 Ask yourself: would I reach for a component instead? If yes, create a React/Vue/Svelte component rather than using @apply.

2. Master the Group Modifier

The group modifier lets you style child elements based on parent state. Perfect for cards, list items, and interactive components:

html
<!-- Card with hover effect on children -->
<div class="group cursor-pointer rounded-lg border p-4
            transition-shadow hover:shadow-lg">
  <h3 class="text-lg font-bold group-hover:text-blue-600">
    Card Title
  </h3>
  <p class="text-gray-600 group-hover:text-gray-800">
    Hover anywhere on the card to see the effect.
  </p>
  <span class="text-sm text-gray-400 group-hover:text-blue-500">
    Read more →
  </span>
</div>

3. Responsive Design with Mobile-First

Tailwind's breakpoints are mobile-first. Unprefixed utilities apply to all screens; prefixed utilities apply at that breakpoint and up:

html
<!-- Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  <div class="bg-white p-4 rounded-lg shadow">Card 1</div>
  <div class="bg-white p-4 rounded-lg shadow">Card 2</div>
  <div class="bg-white p-4 rounded-lg shadow">Card 3</div>
</div>

<!-- Different padding at different breakpoints -->
<section class="px-4 md:px-8 lg:px-16 xl:px-24">
  <!-- Content -->
</section>
Default breakpoints
sm: 640px and up
md: 768px and up
lg: 1024px and up
xl: 1280px and up
2xl: 1536px and up

You can customize these in tailwind.config.js under theme.screens.

4. Extend Theme Colors Properly

Add custom colors that integrate seamlessly with Tailwind's color system:

javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        // Full color scale for a brand color
        brand: {
          50: '#f0fdf4',
          100: '#dcfce7',
          200: '#bbf7d0',
          300: '#86efac',
          400: '#4ade80',
          500: '#7A8B6E',  // Your primary brand color
          600: '#6B7A5F',
          700: '#5C6B50',
          800: '#4D5C41',
          900: '#3E4D32',
          950: '#1a2e1a',
        },
      },
    },
  },
}

/* Now you can use: bg-brand-500, text-brand-700, border-brand-200, etc. */

5. Use Space Utilities for Consistent Gaps

Instead of adding margins to each child, use space-x and space-y on the parent:

html
<!-- Instead of margins on each button -->
<div class="flex space-x-4">
  <button class="btn">Save</button>
  <button class="btn">Cancel</button>
  <button class="btn">Delete</button>
</div>

<!-- Vertical spacing in a stack -->
<div class="flex flex-col space-y-6">
  <div>Section 1</div>
  <div>Section 2</div>
  <div>Section 3</div>
</div>

<!-- Note: space-* adds margin-left/top to all but the first child -->

6. Leverage Arbitrary Values

When you need a one-off value that's not in the default scale, use square brackets:

html
<!-- Arbitrary values for any utility -->
<div class="w-[327px] h-[200px] top-[117px] bg-[#1da1f2]">
  <!-- Matches a specific design spec -->
</div>

<!-- Works with any utility -->
<p class="text-[22px] leading-[1.4] tracking-[0.01em]">
  Custom typography
</p>

<!-- Even with calc() -->
<div class="h-[calc(100vh-80px)]">
  Full height minus header
</div>

<!-- And CSS variables -->
<div class="bg-[var(--brand-color)]">
  Using CSS custom property
</div>
⚠️ Use arbitrary values sparingly. If you find yourself repeating the same arbitrary value, add it to your tailwind.config.js instead.

7. Use Peer for Sibling-Based Styling

Like group but for siblings. Great for form validation and connected elements:

html
<!-- Show validation message when input is invalid -->
<div>
  <input type="email" class="peer border rounded px-3 py-2
                              invalid:border-red-500"
         required />
  <p class="mt-1 hidden text-sm text-red-500 peer-invalid:block">
    Please enter a valid email address
  </p>
</div>

<!-- Custom checkbox with peer -->
<label class="flex items-center gap-2 cursor-pointer">
  <input type="checkbox" class="peer sr-only" />
  <div class="w-5 h-5 border-2 rounded flex items-center justify-center
              peer-checked:bg-blue-500 peer-checked:border-blue-500">
    <svg class="w-3 h-3 text-white hidden peer-checked:block">
      <path d="M5 13l4 4L19 7" stroke="currentColor" fill="none"/>
    </svg>
  </div>
  <span>Remember me</span>
</label>

8. Dark Mode with One Attribute

Tailwind's dark mode is simple to implement with the dark: variant:

javascript
// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media' for system preference
  // ...
}
html
<!-- Toggle dark mode by adding 'dark' class to html element -->
<div class="bg-white dark:bg-gray-900
            text-gray-900 dark:text-gray-100
            border-gray-200 dark:border-gray-700">
  <h1 class="text-2xl font-bold">Automatic dark mode!</h1>
  <p class="text-gray-600 dark:text-gray-400">
    These colors adapt to the current theme.
  </p>
</div>

9. Use Container Queries (New!)

Tailwind 3.2+ supports container queries, letting elements respond to their container's size instead of the viewport:

html
<!-- Mark the container -->
<div class="@container">
  <!-- Elements respond to container width, not viewport -->
  <div class="@md:flex @md:gap-4">
    <img class="w-full @md:w-48" src="..." alt="..." />
    <div class="mt-4 @md:mt-0">
      <h2 class="text-lg @lg:text-xl">Card Title</h2>
      <p class="text-sm @lg:text-base">Description...</p>
    </div>
  </div>
</div>

Container queries are perfect for reusable components that need to adapt to their parent container, not the page width.

10. Optimize for Production

Tailwind automatically removes unused CSS in production, but you can optimize further:

javascript
// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx}',
    './templates/**/*.html',
  ],
  // Only include the variants you use
  // Tailwind v3 includes all variants by default

  // Remove unused plugins in production
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
  ],
}
bash
# Check your CSS bundle size
npx tailwindcss -o output.css --minify
ls -lh output.css  # Should be ~10-30KB gzipped for most sites

Bonus: Useful Tailwind Plugins

  • @tailwindcss/typography - Beautiful defaults for prose content
  • @tailwindcss/forms - Better form element styling
  • @tailwindcss/aspect-ratio - Aspect ratio utilities
  • @tailwindcss/container-queries - Container query support
  • tailwindcss-animate - Animation utilities

Master these tips and you'll be building beautiful, responsive UIs faster than ever. The key is practice - start applying these patterns in your next project!

Related Posts

Python Best Practices for 2024

Essential Python patterns and practices every developer should know. From type hints to dataclasses, level up your Python code.

1 min read

Go Language Fundamentals

A comprehensive introduction to the Go programming language. Learn the syntax, patterns, and idioms that make Go unique.

1 min read

Comments

Log in to leave a comment.

Log In

Loading comments...