Back to Top

Exploring Tailwind CSS Best Practices

Updated 23 October 2024

Let’s dive into some advanced topics and best practices of Tailwind. To help you harness the full potential of this groundbreaking CSS framework.

Whether you’re a seasoned developer or just getting started, there’s something here for everyone.

As we uncover the intricacies of Tailwind’s advanced features and it’s well-suited for headless development.

Tailwind Css

Some Useful Properties Provided By Tailwind

Tailwind CSS’s composability is its superpower, enabling developers to create intricate designs using a combination of utility classes. But did you know you can take it even further?

Utility Functions: Dive into the world of utility functions, which enable dynamic class generation based on user-defined parameters.

Start your headless eCommerce
now.
Find out More

From generating color palettes to creating responsive layouts on the fly, utility functions add a new dimension to Tailwinds’ versatility.

Forced-colors variant of tailwind

Force Color Property already presents simple CSS and Tailwind also added its feature as it’s one of its utility classes.

In Normal CSS, The <system-color> usually reflects the default color choices used for the different parts of a web page. 

User agents, such as web browsers, offer an accessibility feature known as ‘Forced Colors Mode.

This mode constrains the color palette to a limited set of colors. Which are determined by both the user’s preferences and the user agent’s default settings.

<ul class="flex font-bold text-xl text-slate-400 appearance-auto flex-col gap-4 p-10">
  <li class="list-disc">List Appearance</li>
  <li class="appearance-none forced-colors:appearance-auto">List Appearance</li>
</ul>

The purpose of this mode is to override the colors specified by the web author for certain properties. Ensuring a high-contrast and easily readable interface for users with visual impairments.

When Forced Colors Mode is active, the CSS function becomes particularly useful. It allows web authors to access the user agent’s color palette.

And apply these system-defined colors throughout the webpage.

By using it, developers can ensure that their page’s design harmoniously integrates with the restricted color scheme, maintaining both visual consistency and accessibility.

Now anyone can use this in Tailwind as well

And, For forced color adjustment tailwind as well provide forced-color-adjust utilities.

<ul class="forced-color-adjust-none">
  <li class="appearance-none forced-colors:appearance-auto ..."> Force Color On List Appearance</li
</ul>

Tailwind also added two new utilities to enhance your control over designs in Forced Colors Mode: forced-color-adjust-auto and forced-color-adjust-none.

While these utilities offer greater design flexibility, they should be used judiciously. It’s generally best to allow the user’s color preferences to take precedence for accessibility reasons.

However, there are cases where maintaining the original color is crucial.

For instance, when displaying product colors in an online store, the customer needs to see the exact color they are selecting to purchase.

In such scenarios, forced-color-adjust-none can ensure that the item’s color is accurately presented, regardless of the user’s Forced Colors Mode settings.

CSS Subgrid Support In Tailwind

Subgrid is a modern CSS feature that enables an element to align with its parent’s grid columns or rows, allowing for precise placement of its children within the overarching grid structure.

<div role="menu" class="grid grid-cols-[auto_1fr]">
  <div class="grid-cols-subgrid col-span-2">
    <svg class="mr-2">Icon1</svg>
    <span class="col-start-2">Account</span>
  </div>
  <div class="grid-cols-subgrid col-span-2">
    <svg class="mr-2">Icon2</svg>
    <span class="col-start-2">Settings</span>
  </div>
  <div class="grid-cols-subgrid col-span-2">
    <svg class="mr-2">Icon3</svg>
    <span class="col-start-2">Sign out</span>
  </div>
</div>

Tailwind Utility structure leveraging subgrid for components like navigation, menus, and other things to ensure alignment.

For instance, if one menu item includes an icon, the subgrid helps indent all other items accordingly, maintaining a clean and uniform text alignment across the board.

In a normal CSS, the subgrid property is already present for a very long, Applying display: grid to an element turns its direct children into grid items, which can be arranged on the grid.

However, sub-elements follow the normal document flow. To create a grid within a grid, you can designate a grid item as a grid container, creating a ‘nested’ grid.

These nested grids function independently and don’t inherit sizing from the parent grid, which can make alignment challenging.

By using the subgrid value on grid-template-columns or grid-template-rows, the nested grid can align directly with the parent grid’s tracks, ensuring a cohesive layout.

Tailwind’s New Size Utility Class

if constantly typing h-5 w-5 for avatars has become tedious, Tailwind CSS v3.4 brings a welcome change. Tailwind introduced the size-* utility, which simultaneously sets both width and height.

Though we debated the naming—size-* seemed lengthy compared to w-* or h-, and s- was too obscure—we’ve found that the clarity of size-* outweighs any brevity. Anyone can do it like this:

  <div class="grid-cols-subgrid col-span-2">
    <svg class="mr-2 size-10">Icon3</svg>
    <span class="col-start-2">Sign out</span>
  </div>

Instead of,

  <div class="grid-cols-subgrid col-span-2">
    <svg class="mr-2 h-10 w-10">Icon3</svg>
    <span class="col-start-2">Sign out</span>
  </div>

In practice, it’s a game-changer, offering convenience and simplicity, particularly when paired with variants or intricate arbitrary values.

Nested Styling In Tailwind

Tailwind Also Supports nested styling, By Applying ‘*’ you can apply any style over all of its child elements.

This new * variant targets direct children, enabling you to do things like flex *:justify-start to align all children to the start of the flex container.

While it’s generally better to style children directly. The * variant is invaluable when you lack control over the child elements or need to apply contextual styles.

It’s also combinable with other variants, such as hover:*:underline to underline children on hover.

Though this feature is powerful, use it wisely to avoid unintended consequences. We’re eager to see the creative—and hopefully not regrettable—ways it gets utilized.

<div
  role="menu"
  class="data-[slot=description]:*:grid-cols-subgrid data-[slot=description]:*:col-span-2 grid grid-cols-[auto_1fr]"
>
  <div data-slot="subgrid">
    <svg class="mr-2">Icon1</svg>
    <span class="col-start-2">Account</span>
  </div>
  <div data-slot="subgrid">
    <svg class="mr-2">Icon2</svg>
    <span class="col-start-2">Settings</span>
  </div>
  <div data-slot="subgrid">
    <svg class="mr-2">Icon3</svg>
    <span class="col-start-2">Sign out</span>
  </div>
</div>

:has() CSS Property Support

The :has() pseudo-class is a groundbreaking addition to CSS, allowing for styling based on child or sibling elements, and reducing the need for JavaScript.

It’s particularly useful in complex designs, like our text inputs with wrapper elements, where we can now style based on the :disabled state of an input.

With recent support in all major browsers, :has() is poised to transform CSS styling as we know it.

<label class="has-[:checked]:ring-purple-700 has-[:checked]:text-purple-950 has-[:checked]:bg-indigo-50 ..">
  Custom Radio
  <input type="radio" class="hidden" />
</label>

The :has() CSS property represents a significant advancement in styling capabilities, effectively acting like a conditional statement within CSS.

It allows developers to target and style parent elements based on the presence of specific child or sibling elements, thereby simplifying the process of creating dynamic, context-sensitive designs.

This property reduces the reliance on JavaScript for DOM manipulation and minimizes it. The need for extra classes or complex CSS selectors, streamlining the development process.

And offering a more powerful way to control the look and feel of web components based on their content structure.

Tailwinds dynamic viewports

The introduction of the vh unit was a game-changer for creating full-height layouts, but mobile browsers with their dynamic menu bars.

And taskbars dampened the excitement, as vh didn’t account for their variability.

Enter the new era with dvh, lvh, and svh units, specifically engineered to handle the quirks of mobile browser interfaces.

Tailwind CSS seamlessly integrates these units in the form of utility classes, making full-height designs on mobile as straightforward and reliable as we always hoped they’d be.

responsive-design-by-tailwind-and-material
<strong>Utility classes	        CSS Properties
h-svh	                height: 100svh
h-lvh	                height: 100lvh
h-dvh	                height: 100dvh
min-h-svh	        min-height: 100svh
min-h-lvh	        min-height: 100lvh
min-h-dvh	        min-height: 100dvh
max-h-svh	        max-height: 100svh
max-h-lvh	        max-height: 100lvh
max-h-dvh	        max-height: 100dvh</strong>

Dark Mode Design: Implementation and Optimization

Dark mode isn’t just a design trend—it’s a usability feature that enhances accessibility and reduces eye strain. With Tailwind CSS, implementing and optimizing dark mode has never been easier.

Tailwind CSS simplifies the implementation of dark mode on your website, a feature that’s increasingly essential with its integration into many operating systems.

By utilizing Tailwinds dark variant, you can easily define styles that activate when dark mode is preferred by the user’s system settings.

This default behavior aligns with the prefers-color-scheme media feature.

However, for a more hands-on approach, Tailwind also supports a ‘selector’ strategy, allowing for manual toggling of dark mode.

  <div class="grid-cols-subgrid p-4 rounded-md col-span-2">
    <svg class="mr-2 h-10 w-10">Icon3</svg>
    <span class="col-start-2 dark:text-blue-50 dark:bg-blue-700 
    text-blue-700 bg-blue-50">Sign out</span>
  </div>

To enable manual dark mode toggling, switch to the selector strategy.

This approach applies dark:{class} styles whenever the dark class exists in the HTML hierarchy, rather than relying on system preferences.

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: 'selector',
  //enabling selector strategy instead of class strategy
}

Remember to include any prefixes from your Tailwind configuration when adding the dark class. For instance, with a tw- prefix, use tw-dark to trigger dark mode.

You can apply dark: class on the HTML element through JavaScript, by reading a saved preference.

Such as from local storage or by system default settings, and adjusting the DOM to reflect its user’s choice.

About Its Optimisation

Tailwind CSS optimizes dark mode styling by generating classes on-demand, keeping stylesheets lean and load times fast.

Tailwinds Just-In-Time (JIT) mode ensures that only necessary styles are created, by avoiding extra bloat. This results in a seamless and efficient dark mode experience, both for developers and users.

Component-Based Design: Reusability and Flexibility

Tailwinds’ utility-first approach is flexible in adopting component-based design patterns for reusable and maintainable code.

In the realm of traditional templating languages like ERB or Twig, crafting a template partial for a basic element such as a button can sometimes seem unnecessary.

Especially when a single CSS class like btn could do the job.

Although it’s beneficial to use template partials for more elaborate components to keep your code organized. Tailwind CSS provides a streamlined alternative for simpler cases.

Tailwind’s @apply directive allows you to consolidate common utility patterns into custom CSS classes, bypassing the need for a template partial when it feels excessive for simple elements.

This can be particularly useful for creating reusable button styles without the overhead of a partial. Like this:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn-common {
    @apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
  }
}
<button class="btn-common">
  Save changes
</button>

Directives and functions in tailwinds

Some Other very useful directives and functions present in Tailwind are:

theme()

Anyone can use the theme() function to access your Tailwind config values using dot notation in your normal CSS files for core CSS. Like this:

.btn-blue {
  background-color: theme(colors.green.500);
  font-size:        theme(fontSize-2xl);
}

Hover and other states

Tailwind CSS also provides modifiers for likely about everything you’ll ever need, including:

Various states like :hover, :focus:first-child, and :required as pseudo-classes and ::before, ::after::placeholder, and ::selection as elements.

It also provides media queries responsive breakpoints like md:, sm:, lg:, etc.

And ltr and rtl directives as well for directions

Conclusion: Elevate Your Web Development with Tailwinds

Tailwind CSS continues to push the boundaries of modern web development, offering unparalleled flexibility, performance, and developer experience.

By mastering its advanced features and best practices, you’ll unlock new possibilities for crafting exceptional user interfaces and experiences.

It is among the best CSS libraries for headless development due to its utility-first approach.

For more, you can check out TaiwlindCss’s official documentation you want to set it up with next.js you can check our other blog regarding this: Tailwind implementation in Next.js: A Beginner’s Guide

Start your Headless Development with Webkul.
Happy Coding !!

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home