Tailwind CSS - Hover, Focus and Other States


In Tailwind CSS, you can easily apply styles for different user interactions using state-based utilities. By adding modifiers like hover:, focus:, and others to your class names, you can change how elements look when users hover over them, focus on them, or engage in other interactions.

Here's how it would look with the example code.

In Tailwind CSS, you use special prefixes like hover: to change styles based on user actions. For example, hover:border-blue-500 changes the border color to blue when hovering over the element.

Example

  
<!DOCTYPE html>
<html lang="en">
<head> 
     <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <h2 class="font-bold text-2xl mb-4">    
        Tailwind CSS Hover Effect
    </h2>
    <div class="bg-white border-2 border-gray-300 
                p-4 rounded-lg hover:border-blue-500">
        <h2 class="text-xl font-semibold">
            Border Change
        </h2>
        <p class="text-gray-600 mt-2">
            The border color changes on hover.
        </p>
    </div>
</body>

</html>

How does this compare to Traditional CSS?

When working with traditional CSS, you typically manage hover effects by defining styles in a stylesheet. For example, you might set the default border color with one class and then use another rule to change the border color when hovering over the element.

Example

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        .box {
                background-color: white;
                /* Default border color */
                border: 2px solid gray; 
                padding: 16px;
                border-radius: 8px;
            }

        .box:hover {
            /* Border color when hovered */
            border-color: blue; 
        }
    </style>
</head>

<body>
    <div class="box">
        <h2 class="text-xl font-semibold">
            Border Change
        </h2>
        <p class="text-gray-600 mt-2">
            The border color changes on hover.
        </p>
    </div>
</body>

</html>

In this example, the .box class sets the default styles, including the border color. The .box:hover updates the border color to blue when the element is hovered over.

In Tailwind CSS, you handle this differently by using utility classes directly in your HTML.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="bg-white border-2 border-gray-300 p-4 
        rounded-lg hover:border-blue-500">
        <h2 class="text-xl font-semibold">
            Border Change
        </h2>
        <p class="text-gray-600 mt-2">
            The border color changes on hover.
        </p>
    </div>
</body>

</html>

Here, border-2 border-gray-300 sets the default border style and hover:border-blue-500 changes the border color when you hover over the element.

Tailwind CSS makes it easy to manage hover effects directly in your HTML with utility classes. This approach keeps all the styling information in one place, simplifying the development process compared to managing styles through separate CSS rules.

Tailwind CSS includes various modifiers for styling elements based on different conditions:

  • Pseudo-classes: Adjust styles for states like :hover (on hover), :focus (when selected), :first-child (first child), and :required (required fields).
  • Pseudo-elements: Style specific parts of an element, such as ::before, ::after, ::placeholder, and ::selection.
  • Media and feature queries: Handle responsive design and user preferences, including screen sizes, dark mode, and reduced motion.
  • Attribute selectors: Style elements based on attributes, like [dir="rtl"] for right-to-left text and [open] for open elements.

Pseudo-Classes

In Tailwind CSS, pseudo-classes apply styles based on an element's state or interaction. They are prefixed with a colon (:), and they manage scenarios like hovering over an element, focussing on a form field, and more. Let's look at each of these in detail, along with some additional topics.

Hover, Focus, and Active

We can style our elements using the :hover, :focus, and :active modifiers to make them look better and work well in our project.

Check out this example to see how these states are applied:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <h2 class="text-xl font-bold mb-4">
        Tailwind CSS Hover, Focus, and Active States
    </h2>
    <input class="border p-2 hover:border-blue-500 
                  focus:outline-none focus:ring focus:ring-teal-400 
                  active:border-teal-600" placeholder="Interact with me!">
</body>

</html>

In this example, the input field's border color changes when you hover over it, displays a ring when it's focused, and turns into a cyan background with a red border when actively clicked. These visual changes show you how your interactions affect the element.

For a deeper understanding of additional pseudo-classes, such as :visited, :focus-within, and :focus-visible, visit our website. We provide a complete list of pseudo-class modifiers and additional resources to help you master Tailwind CSS.

First, Last, Odd, and Even

Tailwind CSS provides pseudo-classes like :first-child, :last-child, :odd, and :even to style elements based on their position in a container. These classes allow you to customize the appearance of elements that are the first or last in their parent, or those in odd or even positions.

Example: Card Layout

In a card layout, you may want to give extra spacing or different styles to the first and last cards. Here's how you can use the :first-child and :last-child pseudo-classes:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6">
    <div class="space-y-4"> 
        <div class="bg-white p-6 shadow-lg first:mt-2">
            <h3 class="text-lg font-bold">Card 1</h3>
            <p>It has no top margin due to first:mt-0.</p>
        </div>
         
        <div class="bg-white p-6 shadow-lg">
            <h3 class="text-lg font-bold">Card 2</h3>
            <p>It has standard top and bottom margins.</p>
        </div>
         
        <div class="bg-white p-6 shadow-lg last:mb-0">
            <h3 class="text-lg font-bold">Card 3</h3>
            <p>It has no bottom margin due to last:mb-0.</p>
        </div>
    </div>
</body>

</html>

In this example, the :first-child removes the top margin from the first card, and :last-child removes the bottom margin from the last card, creating a more cohesive layout.

Example: List of Products

When displaying a list of products, you might want to change the background color of list items to enhance readability. Here's how you can use the :odd and :even pseudo-classes:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6">
    <ul class="divide-y divide-gray-300">
        <li class="p-4 odd:bg-gray-100 even:bg-gray-200">
            <h4 class="text-md font-semibold text-gray-900">Horlicks</h4>
            <p class="text-gray-700">Health drinks in India</p>
        </li>
        <li class="p-4 odd:bg-gray-100 even:bg-gray-200">
            <h4 class="text-md font-semibold text-gray-900">Airtel</h4>
            <p class="text-gray-700">Mobile-based services</p>
        </li>
        <li class="p-4 odd:bg-gray-100 even:bg-gray-200">
            <h4 class="text-md font-semibold text-gray-900">LG</h4>
            <p class="text-gray-700">LG Electronics India</p>
        </li>
    </ul>
</body>

</html>

Here, the :odd and :even classes apply different background colors to alternate list items, making the list easier to read and visually appealing.

For additional pseudo-classes like :only-child and :first-of-type, visit our website for a complete list and more resources to improve your Tailwind CSS skills.

Form states

We can style form elements using Tailwind CSS to handle different states such as disabled, required, and invalid. See the example below:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6">
    <form class="space-y-4">
        <!-- Disabled Input -->
        <label class="block">
            <span class="block text-sm font-medium text-gray-700">
                Phone Number</span>
            <input 
                type="text" 
                value="123-456-7890" 
                disabled 
                class="mt-1 block w-full px-3 py-2 bg-gray-200 border 
                border-gray-400 rounded-md text-sm placeholder-gray-500
                disabled:bg-gray-100 disabled:text-gray-500 
                disabled:border-gray-300"
                placeholder="Phone number"
            />
        </label>

        <!-- Required Input -->
        <label class="block">
            <span class="block text-sm font-medium text-gray-700">
                Address</span>
            <input 
                type="text" 
                required 
                class="mt-1 block w-full px-3 py-2 bg-white border 
                border-gray-300 rounded-md text-sm placeholder-gray-400
                focus:outline-none focus:border-green-500 focus:ring-1
                focus:ring-green-500 required:border-red-500 
                required:text-red-600"
                placeholder="Enter your address"
            />
        </label>

        <!-- Invalid Input -->
        <label class="block">
            <span class="block text-sm font-medium text-gray-700">
                Zip Code</span>
            <input 
                type="text" 
                class="mt-1 block w-full px-3 py-2 bg-white border 
                    border-gray-300 rounded-md text-sm placeholder-gray-400
                    focus:outline-none focus:border-orange-500 focus:ring-1 
                    focus:ring-orange-500
                    invalid:border-orange-500 invalid:text-orange-600"
                placeholder="Enter your zip code"
                pattern="\d{5}">
        </label>
 
        <button type="submit" class="bg-blue-500 text-white px-4 py-2 
            rounded-md shadow-sm hover:bg-blue-600 focus:outline-none 
            focus:ring-2 focus:ring-blue-500">
                Submit
        </button>
    </form>
</body>

</html>

In this example, you'll see:

  • Disabled Input: Shows how to style an input field that is not editable, indicating its disabled state with a distinct background and border color.
  • Required Input: Highlights the input field that is mandatory to complete, with a red border and text color to emphasize its importance.
  • Invalid Input: Displays an input field that has failed validation, using an orange border and text color to signal an error.
  • Submit Button: Includes a button styled for interaction, with hover and focus effects for better user feedback.

Tailwind CSS also supports other form state modifiers like :read-only, :indeterminate, and :checked.

Styling based on parent state (group-{modifier})

In Tailwind CSS, you can style child elements based on their parent's state by using the group class. This is particularly useful when you want to change the appearance of child elements, like text or buttons, based on the state of the parent element, such as when it is hovered over.

In Tailwind CSS, you can use group-* classes to style child elements based on the state of their parent element. Here's how it works:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6">
    <div class="group p-6 bg-gray-200 border border-gray-400 
        rounded-lg hover:bg-cyan-500">
        <h2 class="text-gray-800 group-hover:text-white">
            Styling
        </h2>
        <p class="text-gray-600 group-hover:text-gray-300">
            Styling based on parent state.
        </p>
        <button class="bg-gray-800 text-white group-hover:bg-white 
            group-hover:text-gray-800 py-2 px-4 rounded">
            Click Me
        </button>
    </div>
</body>

</html>

In this example, when you hover over the whole box, the text and button inside it change color. We achieve this by applying the group class to the parent box and group-hover to the child elements.

Differentiating Nested Groups

With Tailwind CSS, you can style elements based on their parent group's state. Use group/{name} to name your groups, and then use group-hover/{name}: to control child elements based on the parent's state.

For example, you can create a card layout where additional details only appear when the card is hovered over:

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="bg-gray-100 p-4">
    <p class="text-center font-bold underline mb-6">
         Hover over the profiles to reveal more details...
     </p>
     <div class="flex overflow-x-auto space-x-6 pb-6">
        <!-- Profile Card 1 -->
        <div class="group bg-white p-6 border border-blue-300 rounded-lg 
            shadow-lg transition-transform transform hover:scale-105 hover:shadow-xl w-64">
            <div class="w-24 h-24 rounded-full mx-auto mb-4 border-4 border-blue-500 p-1">
                <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Jane Doe" class="w-full h-full rounded-full object-cover">
            </div>
            <h2 class="text-xl font-semibold text-center text-gray-800 
                mb-1">
                    Jane Doe
            </h2>
            <p class="text-gray-600 text-center mb-4">Web Developer</p>
            <button class="absolute inset-x-0 bottom-4 mx-auto px-4 py-2 
                bg-blue-600 text-white rounded-full shadow-md transition-transform 
                transform translate-y-10 opacity-0 group-hover:opacity-100 
                group-hover:translate-y-0">
                    View Profile
            </button>
        </div>

        <!-- Profile Card 2 -->
        <div class="group bg-white p-6 border border-green-300 rounded-lg 
            shadow-lg hover:scale-105 hover:shadow-xl w-64">
            <div class="w-24 h-24 rounded-full mx-auto mb-4 border-4 
                border-green-500 p-1">
                <img src="https://randomuser.me/api/portraits/men/45.jpg" 
                    alt="John Smith" class="w-full h-full rounded-full object-cover">
            </div>
            <h2 class="text-xl font-semibold text-center text-gray-800 mb-1">
                    John Smith</h2>
            <p class="text-gray-600 text-center mb-4">
                Graphic Designer
            </p>
            <button class="absolute inset-x-0 bottom-4 mx-auto px-4 py-2 
                bg-blue-600 text-white rounded-full shadow-md transition-transform 
                transform translate-y-10 opacity-0 group-hover:opacity-100 
                group-hover:translate-y-0">
                    View Profile
            </button>
        </div>

        <!-- Profile Card 3 -->
        <div class="group bg-white p-6 border border-red-300 rounded-lg 
            shadow-lg hover:scale-105 hover:shadow-xl w-64">
            <div class="w-24 h-24 rounded-full mx-auto mb-4 border-4 
                border-red-500 p-1">
                <img src="https://randomuser.me/api/portraits/men/46.jpg" 
                    alt="Alex Johnson" class="w-full h-full rounded-full object-cover">
            </div>
            <h2 class="text-xl font-semibold text-center text-gray-800 mb-1">
                    Alex Johnson</h2>
            <p class="text-gray-600 text-center mb-4">UX Designer</p>
            <button class="absolute inset-x-0 bottom-4 mx-auto px-4 py-2 
                bg-blue-600 text-white rounded-full shadow-md transition-transform 
                transform translate-y-10 opacity-0 group-hover:opacity-100 
                group-hover:translate-y-0">
                    View Profile
            </button>
        </div>
    </div>
</body>

</html>

In the above example, each card has a profile picture and details that change on hover. Tailwind's group class and group-hover utilities control the hover effects and styling.

Just add the right classes to your HTML, and Tailwind handles the rest.

Arbitrary groups

Arbitrary groups in Tailwind CSS allow you to create a custom group-* modifiers dynamically by defining your own CSS selectors within square brackets.This allows you to apply unique styles without using predefined classes.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="p-6">
  <div class="group custom-highlight p-4 
    bg-gray-100">
    <div class="hidden group-[.custom-highlight]:block 
        mt-4 p-2 bg-blue-100 text-blue-800 rounded">
          This content is visible when the outer 
          box has the 'custom-highlight' class!
    </div>
  </div>
</body>

</html>

For more precise control, Tailwind CSS allows you to use the & character to define where the .group class should be applied relative to your custom selector. This technique helps in creating more targeted styles.

Example

 <div class="group">
  <div class="group-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>

Styling Based on Sibling States with Tailwind CSS

In Tailwind CSS, you can style an element based on its sibling's state by adding the peer class to the sibling and using peer-* modifiers for styling. For example, you can use peer-invalid to change the appearance of a related element if the sibling input is invalid.

This example shows how to use Tailwind CSS's peer class to style elements based on a sibling's state. Click the checkbox to see the changes.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6">
  <h3 class="underline font-bold">
      Click the checkbox to see peer 
      styling in action.
  </h3>
  <div class="flex flex-col space-y-4">     
    <!-- Checkbox input to toggle the state -->
    <input type="checkbox" id="toggle" 
        class="peer hidden">
    <label for="toggle" class="cursor-pointer p-2 bg-sky-500 
        text-white rounded peer-checked:bg-teal-500
            peer-checked:text-black">
            Toggle me
    </label>
    
    <!-- Description that appears 
        when checkbox is checked -->
    <p class="hidden peer-checked:block text-green-700">
      Checkbox is checked!
    </p>
  </div>
</body>

</html>

This technique enables various styling effects, such as floating labels, all without JavaScript.

The peer class works with pseudo-classmodifiers like peer-focus, peer-required, and peer-disabled. However, note that the peer class can only affect elements that come after it. It cannot style preceding elements, as shown below:

Example

<!-- This will not work because the input is the previous sibling -->
<label>
  <span class="peer-invalid:text-red-500">Error Message</span>
  <input type="checkbox" class="peer" />
</label>

In this case, the span cannot be styled based on the checkbox state because it precedes the peer element.

Differentiating Peers

When working with multiple peer elements, you can differentiate them by giving each one a unique name. Use the peer/{name} class for the elements and apply styles with the peer-checked/{name} modifiers to target the selected state.

Example: Light/Dark Mode Switch

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <fieldset>
        <legend class="font-bold">Select View Mode</legend>
    
        <!-- Radio buttons for selecting view modes -->
        <input id="light" class="peer/light hidden" type="radio" 
            name="view" checked />
        <label for="light" class="cursor-pointer 
            peer-checked/light:text-indigo-600">
                Light Mode
        </label>
    
        <input id="dark" class="peer/dark hidden" type="radio" 
            name="view" />
        <label for="dark" class="cursor-pointer 
            peer-checked/dark:text-red-600">
                Dark Mode
        </label>
    
        <!-- Content sections -->
        <div class="hidden peer-checked/light:block text-gray-800 
            bg-gray-100 p-4 rounded border border-gray-300">
              You have selected Light Mode.
        </div>
        <div class="hidden peer-checked/dark:block text-gray-100 
            bg-gray-800 p-4 rounded border border-gray-300">
              You have selected Dark Mode.
        </div>
    </fieldset>
</body>

</html>

This example shows how to use unique names (light and dark) for styling elements based on the selected mode. When a radio button is selected, it updates the label and message accordingly, using the peer-checked/{name} class to apply styles.

Note: Each peer is named directly in the HTML. Tailwind automatically handles the necessary CSS, so no extra configuration is required.

Arbitrary peers

You can create custom peer-* modifiers with unique values in square brackets. This method allows for styling elements based on specific conditions or selectors.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
  <p class="mb-4">
    Click on the username input field.
  </p>
  <form class="group">
    <div class="flex flex-col space-y-4">
      <label for="username">Username:</label>
      <input id="username" name="username" type="text" 
        class="focus:ring-2 focus:ring-blue-500 border 
            border-gray-300 p-2 rounded" required />
        <!-- Message shown when input is focused -->
      <div class="hidden group-focus-within:block mt-2 
          p-2 bg-yellow-100 border border-yellow-300 rounded">
            This input is focused.
      </div>
    </div>
  </form>
</body>

</html>

In this example, the message appears when the <input> is focused.

For more precise control over styling, you can use the '&' character to place the .peer class exactly where you want it in the final CSS selector. This approach lets you target elements based on their state or their position relative to siblings.

<div>
  <!-- Input field with a peer class -->
  <input type="text" class="peer" />
  
  <!-- Message that appears based on the position of the peer element -->
  <div class="hidden peer-[:nth-of-type(3)_&]:block">
    <!-- Content shown when the input is the third child of its parent -->
    Content for the third input.
  </div>
</div>

In this example, the <div> only appears if the <input> is the third child of its parent. The peer-[:nth-of-type(3)_&]:block class uses & to place .peer correctly in the selector, enabling styles based on the state of the peer element.

Styling direct children (*-{modifier})

In Tailwind CSS, the '*' modifier allows you to apply styles to direct children of an element when you cannot modify the child elements directly. This method ensures consistent styling for all immediate children through their parent element.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div>
      <h2 class="font-bold mb-4 underline">Team Members</h2>
      <ul class="list-disc list-inside *:text-indigo-700 *:border 
            *:border-black *:bg-cyan-50 *:p-2">
        <li>Alice</li>
        <li>Bob</li>
        <li>Charlie</li>
      </ul>
    </div>
</body>

</html>

In this example, the *:text-blue-500, *:border, *:border-blue-200, *:bg-blue-50, *:p-2 classes style all <li> elements within the <ul>, ensuring consistent text color, border, background, and padding for all direct children.

Important: Keep in mind that applying styles to child elements directly will not override styles set on their parent elements because of CSS specificity.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <div>
    <h2 class="font-bold mb-4 underline">Team Members</h2>
    <ul class="list-disc list-inside *:text-indigo-700 *:border
          *:border-black *:bg-cyan-50 *:p-2">
      <li class="text-red-800">Alice</li>
      <li>Bob</li>
      <li>Charlie</li>
    </ul>
  </div>
</body>

</html>

In this example, the parent <ul>'s background color will override the background color set on individual <li> items. It means that the <li> items cannot change it with their own background color styles.

Styling based on descendants (has-{modifier})

The has-* modifier in Tailwind CSS allows you to style an element based on the state or content of its child elements. This means you can apply styles to a parent element depending on whether its descendants are in a specific state or contain certain elements.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>  

<body class="p-6 bg-gray-100">
  <div class="p-4 border rounded-lg ease-in-out
          has-[input:focus]:border-blue-500 
          has-[input:focus]:bg-blue-50
          border-gray-300 bg-white">
    <label class="block mb-2 text-gray-700">
        Username:
    </label>
    <input type="text" placeholder="Enter your username" 
            class="w-full p-2 border rounded-md">
  </div>
</body>

</html>

In the above example, has-[input:focus] changes the parent <div>'s border and background color when the input field is focused.

The has-*utility in Tailwind CSS allows styling a parent element based on the state or presence of child elements, like changing styles if an input is focused (has-[:focus]), if an image is present (has-[img]), or if a link is inside (has-[a]).

Styling based on the descendants of a group (group-has-{modifier})

To style the elements based on their descendants, use the group class on a parent element and the group-has-* modifiers for child elements.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-100">
  <div class="group p-6 bg-white border border-gray-200 rounded-lg shadow-lg max-w-sm mx-auto">
      <img src="https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909__340.png" alt="Profile Picture"
         class="w-32 h-32 rounded-full mx-auto mb-4 border-4
         border-gray-200">
    <h4 class="text-2xl font-bold text-center">Casey Jordan</h4>
    
    <svg class="hidden group-has-[a]:block w-8 h-8 text-blue-500 mx-auto mb-3" fill="currentColor" viewBox="0 0 24 24">
      <path d="M12 2L2 12h3v8h8v-8h3L12 2z"/>
    </svg>
    <p class="text-gray-600 text-center">
        Just happy to be here.
    </p>
    <a href="https://www.tutorialspoint.com" class="text-blue-600
            hover:underline block text-center mt-2">
        Visit my website
    </a>
    
    <!-- Toggle Button for Details -->
    <button class="mt-4 px-6 py-3 bg-green-600 text-white 
        rounded-md group-has-[.details:focus-within]:bg-green-800
            transition-colors">
        Show Details
    </button>
     
    <div class="details hidden mt-4 p-4 bg-gray-100 border 
        border-gray-300 rounded-md 
        group-has-[button:focus-within]:block">
        Here are some additional details that become 
        visible when the button is focused or clicked.
    </div>
  </div>
</body>

</html> 

In this example, the group class allows styles to be applied to child elements based on the state of the group. The group-has-[a]:block modifier shows the badge icon when a link is present, while the group-has-[button:focus-within]:bg-green-800 modifier changes the button color when the details section is visible, showing how group-has-* can dynamically style elements based on their descendants' state.

Styling based on the descendants of a peer (peer-has-{modifier})

You can style an element based on its sibling's descendants by adding a peer class to the sibling and using the peer-has-* modifier to target the element you want to style. This way, you can apply styles depending on what the sibling contains.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="p-4">
  <fieldset class="p-4 border border-gray-300 
                   rounded-lg bg-teal-100">
    <legend class="text-lg font-semibold">
        Select an Option
    </legend>
    <div class="flex flex-col space-y-2">
      <label class="flex items-center space-x-2 peer">
        <input type="radio" name="option" value="1" 
               class="peer-checked:bg-blue-500" />
        <span>Option 1</span>
      </label>
      <label class="flex items-center space-x-2 peer">
        <input type="radio" name="option" value="2" 
                     class="peer-checked:bg-blue-500" />
        <span>Option 2</span>
      </label>
      <div class="mt-4 text-blue-800 
                  peer-has-[input:checked]:block hidden">
            This message appears when any radio button 
            is selected.
      </div>
    </div>
  </fieldset>
</body>

</html>

In this example, the peer class links elements together. The peer-has-[input:checked]:block class makes the message visible only when a radio button is selected, based on the peer state.

Pseudo-elements

Pseudo-elements in Tailwind CSS style specific parts of an element's content, such as adding content before or after it, among other uses. We cover each topic in detail below.

Before and after

In Tailwind CSS, you can use before: and after: utilities to apply styles to the ::before and ::after pseudo-elements, enabling you to add decorative content or adjust layouts without modifying the HTML.

Here's an example showing how the :before pseudo-element can style elements.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 flex bg-gray-200">
  <div class="bg-white p-8 shadow-lg rounded-md w-full max-w-lg">
    <h3 class="font-bold underline mb-4">Asterisk added before label</h3>
    <label class="flex flex-col">
        <span class="before:content-['*'] before:ml-0.5 before:text-pink-500 
                     block text-sm font-medium text-slate-700">
                Email Address
      </span>
      <input type="email" name="email" class="mt-2 px-4 py-2
                   bg-gray-50 border border-gray-300 rounded-md  placeholder-gray-500" 
                   placeholder="you@example.com" />
    </label>
  </div>
</body>

</html>

This example uses the :before pseudo-element to add an asterisk before the label text. The before:content-['*'] class inserts the asterisk, while before:ml-0.5 adds margin and before:text-pink-500 sets its color.

Here's an example showing how the :after pseudo-element can style elements.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 flex bg-gray-200">
  <div class="bg-white p-8 shadow-lg rounded-md w-full max-w-lg">
    <h3 class="font-bold underline mb-4">Text with a suffix</h3>
    <div class="relative">
      <span class="after:content-[''] after:ml-2 after:text-green-500
                   block text-sm font-medium text-slate-700">
            Task Completed
      </span>
    </div>
  </div>
</body>

</html>

This example uses the :after pseudo-element to add a checkmark after the text. The after:content-[''] class inserts the checkmark, after:ml-2 adds margin to the right, and after:text-green-500 sets its color.

Note on pseudo-elements: Tailwind CSS automatically applies content: '' by default, so you usually don't need to specify it. If you've turned off Tailwind's default styles, you'll need to add content-[''] manually.

You don't always need pseudo-elements. For simpler tasks, using HTML elements like <span> can be easier and more straightforward.

Here's an example of using a <span> element to achieve similar effects to ::before or ::after pseudo-elements in Tailwind CSS:

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-200">
  <div class="bg-white p-8 shadow-lg rounded-md w-full max-w-lg">
    <h3 class="font-bold underline mb-4">Using Span for Decoration</h3>
    <p class="text-sm font-medium text-slate-700">
        Task
      <span class="relative inline-block ml-2">
        <span class="absolute -inset-1 bg-green-500 -skew-y-3"></span>
        <span class="relative text-white"></span>
      </span>
        Completed
    </p>
  </div>
</body>

</html>

Use ::before and ::after when you need to add content that should not be part of the HTML structure or be selectable by users.

If you've disabled the Tailwind's default styles, you'll need to manually add content-[''] for pseudo-elements to work correctly:

<div class="before:content-[''] before:block ...">
  <!-- Content here -->
</div>

Placeholder Text

In Tailwind CSS, you can style placeholder text in input and textarea fields using the placeholder modifier. By applying utility classes such as placeholder-{color}, you can easily adjust the color and style of the placeholder text to match your design needs.

Here's an example of how to style placeholder text using Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-300">
  <div class="bg-white p-6 shadow-lg rounded-lg w-full max-w-md">
    <label class="block mb-4">
      <span class="text-sm font-medium text-gray-800">
          Phone Number
      </span>
      <input type="tel" class="mt-2 px-3 py-2 border border-gray-300
                               rounded-md placeholder-gray-400 hover:placeholder-teal-400
                               focus:placeholder-red-500" 
        placeholder="Enter your phone number"/>
    </label>
  </div>
</body>

</html>

In this example, the placeholder text for the phone number input is gray by default, turns teal on hover, and becomes red when focused.

File input buttons

In Tailwind CSS, you can style file input buttons with the file modifier. This allows you to modify the appearance of file upload buttons, including their size, border, background color, and text.

Here's a simple example showing how to design file upload buttons in Tailwind CSS.

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-200">
  <div class="bg-white p-6 shadow-lg rounded-lg max-w-md">
    <label class="block mb-4">
      <span class="text-sm font-bold text-red-700">
          Upload your file
      </span>
      <input type="file" 
             class="mt-2 file:border file:border-red-900
                    file:py-2 file:px-5 file:rounded-2xl file:bg-red-500 
                    file:text-white file:font-serif file:cursor-pointer
                    hover:file:bg-red-600"/>
    </label>
  </div>
</body>

</html>

In this example, we styled the file input button with a red background, rounded corners, and padding. The file: modifier adjusts the border, background, and text color, with hover effects for better interactivity.

Tailwind CSS doesn't automatically apply borders to file input buttons. To include a border, use classes like file:border and file:border-solid, along with any border-width utilities. For example:

<input type="file" class="file:border file:border-solid ..."/>

List markers

In Tailwind CSS, you can style the markers or bullets in the lists using the marker modifier. This allows you to modify the appearance of list item markers (such as bullets or numbers) by adjusting their color, size, and other styles.

Here's a simple example showing how to style list item markers using Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-100">
  <div class="max-w-sm mx-auto bg-white p-6 shadow-xl rounded-lg">
    <h2 class="text-xl font-bold mb-4 underline">
        My Morning Routine
    </h2>
    <ul class="list-disc pl-5 marker:text-purple-600 
                text-stone-600 marker:text-lg space-y-2">
        <li>Wake up and make the bed</li>
        <li>Go for a 30-minute jog</li>
        <li>Prepare and eat a healthy breakfast</li>
        <li>Review the day's schedule</li>
    </ul>
  </div>
</body>

</html>

The example displays a styled to-do list with purple markers (marker:text-purple-600), larger marker text (marker:text-lg), and each item is spaced out. It shows how to style list markers with Tailwind CSS.

Additionally, the marker modifier can be applied to a parent element, so you can style all list items consistently without needing to repeat the styles for each item.

Highlight Text

In Tailwind CSS, you can style the text selected by users with the selection modifier, which changes the background and text color of the selected text. By applying utilities like selection:bg-{color} and selection:text-{color}, you can control how highlighted text appears, ensuring it aligns with your overall design.

Let's style and see how the selection modifier is used to highlight text using Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-100">
  <div class="max-w-lg mx-auto bg-white p-6 shadow-xl rounded-lg">
    <h2 class="text-xl font-bold mb-4">
        Highlight text with the mouse
    </h2>
    <p class="text-slate-800 selection:bg-cyan-400 
              selection:text-pink-700">
        This is an example of how text selection can be styled using
        Tailwind CSS. When you select this text, you will see the
        background color of the selected text changes to yellow 
        and the text color to blue.
    </p>
  </div>
</body>

</html>

The example shows how to style selected text using Tailwind CSS. When text is highlighted with the mouse, the background turns cyan and the text color changes to pink.

The selection modifier can be applied at any level in your HTML, affecting all nested elements. This makes it simple to ensure consistent selection colors throughout your site. For example:

<html>
<head>
    <!-- ... -->
</head>

<body class="selection:bg-pink-300">
    <!-- ... -->
</body>

</html>

First-line and first-letter

In Tailwind CSS, you use ::first-line and ::first-letter utilities to style the first line and first letter of a text block directly in your HTML, making it easy to apply unique styles like bold text or large letters.

Let's understand with the example how we can use these classes in Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script> 
</head> 

<body class="p-6 bg-gray-100 items-center">
    <div class="bg-white shadow-lg max-w-md rounded-lg p-6  ">
        <p class="first-line:font-semibold first-line:text-green-700 
                  first-letter:text-6xl first-letter:font-extrabold
                  first-letter:text-red-600 first-letter:mr-4
                  first-letter:float-left">
            Creativity is intelligence having fun. Albert Einstein
            once said, "Imagination is more important than knowledge." 
            This quote emphasizes the power of creative thinking
            and the importance of nurturing our imaginative abilities.
        </p>
    </div>
</body>

</html>

In the example above, we have applied Tailwind utilities like first-line:font-semibold and first-letter:text-5xl to style the text with bold green for the first line and a large, red, bold first letter.

Dialog backdrops

In Tailwind CSS, the backdrop modifier styles the semi-transparent area behind a <dialog> element, allowing you to modify the backdrop's appearance when the dialog is open.

Here's a simple example of how we can use these classes in Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script> 
</head> 
 
<body class="p-4">
  <button onclick="document.getElementById('myDialog').showModal()"
          class="bg-blue-500 text-white px-4 py-2 rounded">
      Open Dialog
  </button>
  <dialog id="myDialog" class="backdrop:bg-black/50 p-6 rounded-lg">
      <h2 class="text-xl font-semibold">
          Important Notice
      </h2>
      <p class="mt-2 text-slate-300">
          This is a dialog with a darkened backdrop to make the 
          content stand out more.
      </p>
      <button onclick="document.getElementById('myDialog').close()"
              class="mt-2 bg-red-500 text-white px-4 py-2 rounded">
          Close
      </button>
  </dialog>
</body>

</html>

In the above example, we have applied backdrop:bg-black/50, which adds a semi-transparent black background to the dialog's backdrop, creating a dimming effect to highlight the modal content.

Media and feature queries

Media and feature queries in Tailwind CSS adjust styles for different screen sizes and features. Using simple class prefixes like sm:, md:, lg:, and xl: you can easily create responsive designs that work well on any device.

Responsive breakpoints

In Tailwind CSS, you can use responsive breakpoints to apply different styles to elements based on screen size, ensuring your design looks great on all devices.

For example, by using responsive modifiers like md for medium screens and lg for large screens, you can adjust the number of columns in a grid layout or change font sizes and spacing, creating a flexible and adaptive user experience.

Let's understand with an example of a responsive product grid layout that adjusts based on screen size.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script> 
</head> 
 
<body class="p-4 bg-gray-300"> 
  <div class="grid grid-cols-1 sm:grid-cols-2 
              md:grid-cols-3 gap-4 p-2">
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Classic Watch
      </h3>
      <p class="text-gray-600">
          Timeless design
      </p>
    </div>
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Bluetooth Speaker
      </h3>
      <p class="text-gray-600">
          Powerful sound
      </p>
    </div>
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Wireless Earbuds
      </h3>
      <p class="text-gray-600">
          Noise-cancelling
      </p>
    </div>
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Smartphone Stand
      </h3>
      <p class="text-gray-600">
          Adjustable angle
      </p>
    </div>
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Portable Charger
      </h3>
      <p class="text-gray-600">
          High capacity
      </p>
    </div>
    <div class="bg-white shadow-lg p-4 rounded-lg">
      <h3 class="text-lg font-semibold">
          Ergonomic Mouse
      </h3>
      <p class="text-gray-600">
          Comfortable grip
      </p>
    </div>
  </div> 
</body>

</html>

In the above example, we have a responsive grid layout where: On mobile screens, the gallery displays 1 column (grid-cols-1). On small screens, it switches to 2 columns (sm:grid-cols-2), and on medium screens (e.g., tablets), it adjusts to 3 columns (md:grid-cols-3).

Prefers color scheme

The prefers-color-scheme media query in Tailwind CSS detects whether a user prefers a light or dark theme, typically set at the operating system level. Tailwind CSS uses this feature to help you create designs that automatically adjust to the user's theme preference.

By using default utilities for light mode and applying the dark modifier to override styles for dark mode, you ensure that your website remains readable in both modes.

Let's see a simple example of how to apply Tailwind CSS classes for both light and dark modes.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-200">
  <div class="grid grid-cols-2 space-x-4">
    <div class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8
                shadow-xl">
    <div>
        <span class="inline-flex p-2 bg-blue-500 rounded-md 
                     shadow-lg">
          <!-- icon (symbol) -->
          <svg class="h-6 w-6 text-white" fill="none" 
                      viewBox="0 0 24 24" stroke="currentColor" 
                      aria-hidden="true">
            <path stroke-linecap="round" stroke-linejoin="round"
                      stroke-width="2" d="M5 13l4 4L19 7"/>
          </svg>
        </span>
      </div>
      <h3 class="text-slate-900 dark:text-white mt-5 text-base
                 font-medium tracking-tight">
          Amazing Features
      </h3>
      <p class="text-slate-500 mt-2 text-sm">
        Explore the new features we've added to enhance your
        experience. This update is designed to improve
        functionality and performance.
      </p>
    </div>
    <!-- Card 2 -->
    <div class="bg-gray-800 dark:bg-gray-700 rounded-lg px-6 
        py-8 ">
      <div>
        <span class="inline-flex p-2 bg-blue-600 dark:bg-blue-700 
                     rounded-md shadow-lg">
          <!-- Example icon (symbol) -->
          <svg class="h-6 w-6 text-white" fill="none" 
                      viewBox="0 0 24 24" stroke="currentColor" 
                      aria-hidden="true">
            <path stroke-linecap="round" stroke-linejoin="round" 
                stroke-width="2" d="M5 13l4 4L19 7" />
          </svg>
        </span>
      </div>
      <h3 class="text-gray-100 dark:text-gray-200 mt-5 font-medium">
        Amazing Features
      </h3>
      <p class="text-gray-300 dark:text-gray-400 mt-2 text-sm">
        Explore the new features we've added to enhance your 
        experience. This update is designed to improve 
        functionality and performance.
      </p>
    </div>
  </div>
</body>

</html>

In the example above, we use Tailwind CSS classes to style content for both light and dark modes. For light mode, classes like bg-white and text-slate-500 are applied. For dark mode, classes such as dark:bg-slate-800 and dark:text-slate-400 are used.

Prefers reduced motion

In Tailwind CSS, the prefers-reduced-motion media query helps you adjust designs for users who prefer less movement on their screens.

Use the motion-reduce modifier to disable or minimize animations for users who want less motion. Conversely, the motion-safe modifier ensures animations are applied only for users who have not requested reduced motion, which simplifies your styling.

Here's a simple example to show how Tailwind CSS handles reduced motion preferences.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-100">
    <div class="fixed">
    <div class="motion-safe:animate-bounce motion-reduce:animate-none 
                rounded-lg px-4 py-2 shadow-lg bg-gradient-to-r from-teal-500 
                to-purple-500 text-white">
      <p class="text-sm">New message received!</p>
    </div>
  </div>
</body>

</html>

In this example, the message box will bounce if animations are allowed (motion-safe:animate-bounce), but it will remain still if reduced motion is preferred (motion-reduce:animate-none).This way, the design adjusts to the user's motion preference.

Using the motion-safe modifier helps you apply animations only when the user hasn't requested reduced motion, which is often more straightforward than managing multiple motion-reduce overrides.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4">
  <div class="grid grid-cols-2 gap-6">
    <div>
      <p class="underline font-bold mb-2">
            Using motion-reduce
      </p>
        <button class="bg-blue-500 text-white font-semibold py-2 
                       p-4 rounded-lg shadow-lg hover:bg-blue-400 
                       motion-reduce:hover:bg-blue-300 
                       motion-reduce:transition-none">
                Update Profile
        </button>
    </div>

    <div>
        <p class="underline font-bold mb-2">
            Using motion-safe
        </p>
        <button class="bg-blue-500 text-white font-semibold
                       py-2 px-4 rounded-lg shadow-lg transition-transform 
                       transform motion-safe:hover:bg-blue-400 
                       motion-safe:hover:-translate-y-1">
                Update Profile
        </button>
    </div>
  </div>
</body>

</html>

Prefers contrast

The prefers-contrast in Tailwind CSS adapts your website's styling based on how much color difference users need between text and background.

Use the contrast-more modifier to provide higher contrast for better readability, and the contrast-less modifier to offer a softer look for those who prefer less contrast.

Here's a simple example showing the use of prefers-contrast with Tailwind CSS./p>

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-100">
    <div class="flex justify-between">
    <!-- Left Section: Low Contrast -->
        <div class="w-1/2 p-6 bg-gray-300 text-gray-700 
                    rounded-lg shadow-lg contrast-less:bg-gray-200 
                    contrast-less:text-gray-600">
          <h2 class="text-xl font-semibold mb-2 
                     contrast-less:text-gray-800">
                Low Contrast Design
          </h2>
          <p class="contrast-less:text-gray-700">
                This section shows a low-contrast design with softer 
                colors and less intense visibility.
          </p>
          <button class="mt-3 px-4 py-2 bg-blue-300 text-gray-800 
                         rounded hover:bg-blue-400 contrast-less:bg-blue-200">
                Learn More
          </button>
        </div>
        
        <!-- Right Section: High Contrast -->
        <div class="w-1/2 p-6 bg-black text-white rounded-lg 
                    shadow-lg contrast-more:bg-black contrast-more:text-white">
          <h2 class="text-xl font-semibold mb-2 
                     contrast-more:text-yellow-300">
                High Contrast Design
          </h2>
          <p class="contrast-more:text-gray-300">
                This section shows a high-contrast design with bold 
                colors and strong visibility.
          </p>
          <button class="mt-3 px-4 py-2 bg-red-600 text-black 
                         rounded-md hover:bg-red-700 contrast-more:bg-red-500">
                Learn More
          </button>
        </div>
    </div>
</body>

</html>

In the example, we show lower and higher contrast. The left side uses lower contrast with muted colors, while the right side employs higher contrast with bolder, more distinct colors. This makes the text and elements on the right stand out more against the background.

Forced colors mode

Forced Colors Mode in Tailwind CSS is a feature that enables users to apply their own color preferences to a website. This mode overrides the default colors for elements such as text, backgrounds, and buttons, aligning them with the user's preferred color settings and ensuring sufficient contrast for readability.

Here's a simple example to show how you can use Tailwind CSS to handle forced colors mode.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-10">
    <h2 class="text-lg font-bold mb-4">Select Your Theme:</h2>

    <div class="overflow-x-auto">
      <form class="flex gap-6 min-w-max">
        <!-- Cyan Theme -->
        <label class="flex flex-col items-center gap-2 p-4 border border-gray-200 
                      rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-shadow duration-300">
          <input type="radio" name="theme" class="hidden peer" />
          <div class="relative border rounded-full w-20 h-20 flex items-center 
                      justify-center peer-checked:bg-cyan-100 peer-checked:border-cyan-800">
            <div class="absolute top-3 left-3 h-8 w-8 rounded-full bg-cyan-100 
                        border border-cyan-300 peer-checked:border-cyan-800"></div>
            <div class="h-8 w-8 rounded-full bg-cyan-500 z-10"></div>
          </div>
          <p class="text-center text-gray-700">Cyan</p>
        </label>

        <!-- Green Theme -->
        <label class="flex flex-col items-center gap-2 p-4 border border-gray-200 
                      rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-shadow duration-300">
          <input type="radio" name="theme" class="hidden peer" />
          <div class="relative border rounded-full w-20 h-20 flex items-center 
            justify-center peer-checked:bg-green-100 peer-checked:border-green-800">
            <div class="absolute top-3 left-3 h-8 w-8 rounded-full bg-green-100 
                        border border-green-300 peer-checked:border-green-800"></div>
            <div class="h-8 w-8 rounded-full bg-green-500 z-10"></div>
          </div>
          <p class="text-center text-gray-700">Green</p>
        </label>

        <!-- Red Theme -->
        <label class="flex flex-col items-center gap-2 p-4 border border-gray-200 
                      rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-shadow duration-300">
          <input type="radio" name="theme" class="hidden peer" />
          <div class="relative border rounded-full w-20 h-20 flex items-center 
                      justify-center peer-checked:bg-red-100 peer-checked:border-red-800">
            <div class="absolute top-3 left-3 h-8 w-8 rounded-full bg-red-100 
                        border border-red-300 peer-checked:border-red-800"></div>
            <div class="h-8 w-8 rounded-full bg-red-500 z-10"></div>
          </div>
          <p class="text-center text-gray-700">Red</p>
        </label>

        <!-- Purple Theme -->
        <label class="flex flex-col items-center gap-2 p-4 border border-gray-200 
                      rounded-lg shadow-md cursor-pointer hover:shadow-lg transition-shadow duration-300">
          <input type="radio" name="theme" class="hidden peer" />
          
          <div class="relative border rounded-full w-20 h-20 flex items-center 
                      justify-center peer-checked:bg-purple-100 peer-checked:border-purple-800">
            <div class="absolute top-3 left-3 h-8 w-8 rounded-full bg-purple-100 
                        border border-purple-300 peer-checked:border-purple-800"></div>
            <div class="h-8 w-8 rounded-full bg-purple-500 z-10"></div>
          </div>
          <p class="text-center text-gray-700">Purple</p>
        </label>

        <!-- Sky Theme -->
        <label class="flex flex-col items-center gap-2 p-4 border border-gray-200 
                      rounded-lg shadow-md cursor-pointer">
          <input type="radio" name="theme" class="hidden peer" />
          <div class="relative border rounded-full w-20 h-20 flex items-center 
                      justify-center peer-checked:bg-sky-100 peer-checked:border-sky-800">
            <div class="absolute top-3 left-3 h-8 w-8 rounded-full bg-sky-100 
                        border border-sky-300 peer-checked:border-sky-800"></div>
            <div class="h-8 w-8 rounded-full bg-sky-500 z-10"></div>
          </div>
          <p class="text-center text-gray-700">Sky</p>
        </label>
    </div>
</body>

</html>

In this example, we used Tailwind CSS to create a responsive form with theme selection cards and added a horizontal scrollbar to view all options. This shows how to implement a theme selector with different color options and showcases the use of Tailwind CSS utilities to manage layout and styling.

Viewport orientation

In Tailwind CSS, viewport orientation refers to how the device's screen is positionedeither vertical (portrait) or horizontal (landscape). By using Tailwind's portrait and landscape modifiers, you can apply specific styles based on the screen's orientation.

Let's look at a simple example to understand this better.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <h3 class="underline font-bold text-xl mb-4">
        Content changes based on screen orientation.
    </h3>
  <div class="container mx-auto">
    <!-- Content for portrait mode -->
    <div class="portrait:flex hidden items-center 
                justify-center h-64 bg-blue-200">
        <p class="text-lg font-semibold">
            You are viewing this in portrait mode.
        </p>
    </div>

    <!-- Content for landscape mode -->
    <div class="landscape:flex hidden items-center 
                justify-center h-64 bg-green-200">
        <p class="text-lg font-semibold">
            You are viewing this in landscape mode.
        </p>
    </div>
  </div>
</body>

</html>

In the above example, content visibility changes based on the width-to-height ratio of the viewport. The portrait:flex class shows content in portrait mode and hides it in landscape mode, while the landscape:flex class does the opposite.

Print styles

In Tailwind CSS, print styles allow you to control how content appears when printed. By using print modifiers like .print:hidden to hide content and .print:block to show content only in print, you ensure that your printed documents are neat.

Here's a simple example showing how these classes work.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <div>
    <!-- Content visible on screen, hidden during print -->
    <section class="print:hidden bg-teal-100 p-4 mb-4">
      <h1 class="text-2xl font-bold">
          Welcome to Our Website
      </h1>
      <p>
          This section is visible on the screen but 
          will not appear in the print version.
      </p>
    </section>

    <!-- Content visible only when printing -->
    <section class="hidden print:block bg-yellow-100 p-4">
      <h1 class="text-xl font-bold">
          Print Version
      </h1>
      <p>
          This section appears only in the print 
          version of the page.
      </p>
    </section>
  </div>
</body>

</html>

In the above example, the print:hidden section is visible on screen but hidden when printed, while the section with hidden print:block appears only in the print version, enabling different content display.

Supports rules

Tailwind CSS provides a feature called the supports-[] modifier that enables you to apply styles based on whether a specific CSS feature is supported by the user's browser.

The supports-[] modifier in Tailwind CSS generates @supports rules internally. This allows you to target specific CSS features and properties, applying styles only if the feature is supported by the user's browser.

Use the modifier with the syntax supports-[feature], where feature is a CSS property and value, or a condition using and/or.

Here's a simple example showing how to use the supports-[] modifier to apply styles based on feature support.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <div class="flex supports-[display:grid]:grid 
              supports-[display:grid]:gap-4 shadow-xl">
    <div class="bg-blue-100 p-4">
        Here's the first section;</div>
    <div class="bg-green-200 p-4">
        Welcome to second part!</div>
  </div>

  <div class="bg-black/75 supports-[backdrop-filter]:bg-black/25 
              supports-[backdrop-filter]:backdrop-blur-lg p-4 mt-4 shadow-2xl">
        This section will have a backdrop blur 
        effect if the browser supports `backdrop-filter`.
  </div>
</body>

</html>

In the example, the supports-[display:grid]:grid class applies a grid layout only if the browser supports CSS grids, otherwise , it defaults to flexbox.

Similarly, supports-[backdrop-filter]:bg-black/25 adds a semi-transparent background, and supports-[backdrop-filter]:backdrop-blur-lg adds a blur effect if the browser supports the backdrop-filter property.

You can also configure shortcuts for common @supports rules in your Tailwind CSS configuration to simplify usage.

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    supports: {
      grid: 'display: grid',
      'backdrop-filter': 'backdrop-filter: blur(5px)',
    },
  },
}

With this configuration, you can use these custom modifiers directly in your HTML.

<div class="supports-grid:grid">
  <!-- This div will use grid layout if the browser supports it -->
</div>

<div class="supports-backdrop-filter:bg-black/25 supports-backdrop-filter:backdrop-blur-lg">
  <!-- This div will apply backdrop blur if the browser supports backdrop-filter -->
</div>

You can use these custom supports-* modifiers in your project like this:

Attribute selectors

Attribute selectors in Tailwind CSS style elements based on their attributes, such as data-* attributes or specific values. We'll look at how to use these selectors effectively below.

ARIA states

In Tailwind CSS, ARIA attributes are used to style elements with aria-* modifiers. ARIA (Accessible Rich Internet Applications) attributes give extra information about elements, such as their state, which helps you adjust their appearance.

Using these modifiers, you can directly apply styles in your HTML based on common boolean ARIA attributes like aria-checked, aria-disabled, and aria-expanded.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <h3 class="underline font-bold mb-4">
       Buttons with `aria-disabled` set to true and false:
    </h3>
    <form class="space-y-4">
        <input type="text" aria-required="true" 
            class="border p-2 w-full" placeholder="Enter your name">
        
        <button aria-disabled="true" 
            class="bg-gray-500 text-white p-2 rounded cursor-not-allowed 
                aria-disabled:bg-slate-400">
                Submit (Disabled)
        </button>
         <button aria-disabled="false" 
            class="bg-slate-700 text-white p-2 rounded 
                aria-disabled:bg-gray-300">
                Submit (Enabled)
        </button>
    </form>
    <div aria-hidden="false" 
        class="mt-4 p-4 bg-yellow-200 aria-hidden:hidden">
            This message is visible when `aria-hidden` is false.
    </div>
</body>

</html>

In the above example, we have button styles differently based on the aria-disabled showing their enabled or disabled state. Additionally, a notification message is displayed only when aria-hidden is set to false.

By default, Tailwind CSS includes modifiers for common ARIA attributes:

Modifier CSS
aria-busy &[aria-busy="true"]
aria-checked &[aria-checked="true"]
aria-disabled &[aria-disabled="true"]
aria-expanded &[aria-expanded="true"]
aria-hidden &[aria-hidden="true"]
aria-pressed &[aria-pressed="true"]
aria-readonly &[aria-readonly="true"]
aria-required &[aria-required="true"]
aria-selected &[aria-selected="true"]

To create your own ARIA attribute modifiers, you can update the tailwind.config.js file. For example, if you want to add styles for additional ARIA states.

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      aria: {
        'valid': 'valid="true"',
        'loading': 'loading="true"',
      },
    },
  },
}

When you need to apply unique ARIA attributes or handle complex ARIA values, you can use square brackets to create CSS properties directly. This method enables you to add custom styles directly in HTML for specific attributes by passing predefined settings in your Tailwind configuration.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <table class="min-w-full border border-gray-200">
      <tr>
        <th aria-sort="ascending" class="aria-[sort=ascending]:bg-yellow-300 
                       aria-[sort=descending]:bg-blue-300 p-2">
              Name
          <span class="aria-[sort=ascending]:inline 
                       aria-[sort=descending]:hidden"></span>
          <span class="aria-[sort=ascending]:hidden 
                       aria-[sort=descending]:inline"></span>
        </th>
      </tr> 
    <tr>
        <td>John Doe</td>
    </tr>
    <tr>
        <td>Jane Smith</td>
    </tr> 
  </table>
</body>

</html>

And ARIA state modifiers can also be applied to parent and sibling elements using the group-aria-* and peer-aria-* modifiers.

<th aria-sort="ascending" class="group">
    <!-- Content -->
  <svg class="group-aria-[sort=ascending]:rotate-0 group-aria-[sort=descending]:rotate-180">
      <!-- SVG content -->
  </svg>
</th>

Data attributes

In Tailwind CSS, data attributes are used to conditionally apply styles based on the values of data-* attributes using data-* modifiers.

By default, Tailwind supports custom data-* attributes, allowing you to create styles that respond to specific values set in these attributes directly from your HTML.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-8 bg-gray-100">
    <div class="space-y-4">
     <!-- Tab with 'active' state -->
        <div data-tab="active" 
          class="data-[tab=active]:bg-blue-200 
              data-[tab=active]:text-blue-900 p-4 rounded-lg border 
              shadow-lg border-indigo-300">
          <h3 class="text-lg font-bold">Active Tab</h3>
          <p>With blue background and dark blue text.</p>
        </div>
        
         <!-- Tab with 'inactive' state -->
        <div data-tab="inactive" 
          class="data-[tab=inactive]:bg-gray-100 
              data-[tab=inactive]:text-gray-600 p-4 rounded-lg border 
              shadow-lg border-gray-300">
          <h3 class="text-lg font-bold">Inactive Tab</h3>
          <p>With white background and gray text.</p>
        </div>
    </div>
</body>

</html>

This example shows how to style elements conditionally using data-* attributes. Here, styles change based on whether the tab is "active" or "inactive". You can use similar techniques with different data-* modifiers to create various dynamic designs.

You can create specific shortcuts for common data attributes by configuring your tailwind.config.js. This makes your HTML more readable and manageable.

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      data: {
        roleAdmin: 'role="admin"',
        roleUser: 'role="user"',
        roleGuest: 'role="guest"',
      },
    },
  },
}

Now you can apply these data-* modifiers in your project designs.

Example

<!DOCTYPE html>
<html lang="en">
<head>  
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-50">
    <!-- User profile with role="admin" -->
    <div data-role="admin" 
        class="p-4 border rounded shadow-md data-role-admin:bg-blue-200">
        <h2 class="text-2xl font-semibold text-blue-800">Admin Profile</h2>
        <p class="text-gray-800">You have administrative privileges.</p>
    </div>
    
    <!-- User profile with role="user" -->
    <div data-role="user" 
        class="p-4 border rounded shadow-md data-role-user:bg-green-200 mt-4">
        <h2 class="text-2xl font-semibold text-green-800">User Profile</h2>
        <p class="text-gray-800">You have regular user privileges.</p>
    </div>
    
    <!-- User profile with role="guest" -->
    <div data-role="guest" 
        class="p-4 border rounded shadow-md data-role-guest:bg-yellow-200 mt-4">
        <h2 class="text-2xl font-semibold text-yellow-800">Guest Profile</h2>
        <p class="text-gray-800">You have limited access.</p>
    </div>
</body>

</html>

In this example, we first configure Tailwind CSS with data-* attributes and then show how to use these attributes in HTML for styling.

RTL support

Tailwind CSS provides RTL support for managing styles on websites with left-to-right (LTR) and right-to-left (RTL) text directions. The ltr and rtl modifiers allow you to apply specific styles based on the direction of text.

Here's an example of how to use these modifiers to style text directions.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-8">
  <!-- LTR Example -->
  <div class="p-4 bg-blue-200 ltr:ml-4 rtl:mr-4 mb-">
    <p>This is a left-to-right (LTR) text direction.</p>
  </div>

  <!-- RTL Example -->
  <div dir="rtl" class="p-4 bg-green-200 rtl:mr-7">
    <p>This is a right-to-left (RTL) text direction.</p>
  </div>
</body>

</html>

In this example, we have applied the ltr:ml-3 class, which adds a margin-left of 0.75 rem to the first container, and the rtl:mr-3 class, which adds a margin-right of 0.75 rem to the second container.

Make sure to set the dir attribute on your HTML tag to either ltr (left-to-right) or rtl (right-to-left). This helps the direction-based styles work correctly, especially when you're creating layouts that depend on the text direction.

Example

<!DOCTYPE html>
<html lang="en" dir="rtl">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-8 bg-gray-100">
<div class="bg-white p-6 rounded-lg shadow-md">
    <h2 class="text-xl font-bold mb-4">
        Heading Alignment Example
    </h2>
    <p class="text-gray-700 bg-yellow-200 p-4 rounded-lg">
        This text aligns to the right in 
        the right-to-left mode.
    </p>
</div>
</body>

</html>

Note: The ltr: and rtl: modifiers are useful only if your website needs to support both left-to-right and right-to-left text directions. If your site is meant for just one direction, you don't need these modifiers. Simply use the styles that fit your content.

Open/closed state

Tailwind CSS uses the open: modifier to style elements based on whether they are open or closed, such as <details> and <dialog>. This allows you to apply different styles when these elements are expanded or collapsed, making it easier to create dynamic and responsive designs.

Let's look at a simple example using the open: modifier with a <details> element to showcase how to style it differently when it is open.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="bg-gray-100 p-6">
  <div class="max-w-lg mx-auto p-6">
    <details class="open:bg-white open:ring-2 open:ring-blue-500 
                    open:shadow-lg p-6 rounded-lg">
      <summary class="text-lg font-semibold text-gray-800 
                      cursor-pointer select-none">
        What is Tailwind CSS?
      </summary>
      <div class="mt-4 text-gray-600">
        <p>Tailwind CSS is a utility-first CSS framework for 
            creating custom designs without having to leave 
            your HTML.
        </p>
      </div>
    </details>
  </div>
</body>

</html>

In the above example, we style a <details> element that shows additional information when opened. The open: modifier changes the background, adds a ring and shadow, and more, making it a clickable title that reveals the content below when clicked.

Custom modifiers

Custom modifiers in Tailwind CSS allow you to add your own variations to utility classes, giving you more control over styling. We'll show you how to create and use these custom modifiers effectively below.

Using Arbitrary Variants in Tailwind CSS

When using Tailwind CSS, there are times when you need to style elements based on specific conditions or selectors that the default variants don't cover. Tailwind addresses this with a feature called arbitrary variants, which allows you to create custom modifiers directly in your HTML.

These arbitrary variants are custom selectors enclosed in square brackets ([]), making it simple to apply styles based on particular conditions.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>
 
<body class="p-4 bg-gray-100">
    <table class="min-w-full mx-auto border border-gray-300 
                  shadow-xl text-xs">
        <thead>
            <tr class="bg-gray-200">
                <th class="p-2 text-left border-b border-gray-300">
                    Name
                </th>
                <th class="p-2 text-left border-b border-gray-300">
                    Age
                </th>
                <th class="p-2 text-left border-b border-gray-300">
                    Occupation
                </th>
            </tr>
        </thead>
        <tbody>
            <tr class="[&:nth-child(even)]:bg-blue-100">
                <td class="p-2 border-b border-gray-300">
                    John Doe
                </td>
                <td class="p-2 border-b border-gray-300">
                    30
                </td>
                <td class="p-2 border-b border-gray-300">
                    Software Engineer
                </td>
            </tr>
            <tr class="[&:nth-child(even)]:bg-blue-100">
                <td class="p-2 border-b border-gray-300">
                    Jane Smith
                </td>
                <td class="p-2 border-b border-gray-300">
                    25
                </td>
                <td class="p-2 border-b border-gray-300">
                    UI/UX Designer
                </td>
            </tr>
            <tr class="[&:nth-child(even)]:bg-blue-100">
                <td class="p-2 border-b border-gray-300">
                    Alice Johnson
                </td>
                <td class="p-2 border-b border-gray-300">
                    28
                </td>
                <td class="p-2 border-b border-gray-300">
                    Data Scientist
                </td>
            </tr>
            <tr class="[&:nth-child(even)]:bg-blue-100">
                <td class="p-2 border-b border-gray-300">
                    Michael Brown
                </td>
                <td class="p-2 border-b border-gray-300">
                    35
                </td>
                <td class="p-2 border-b border-gray-300">
                    Marketing Manager
                </td>
            </tr>
             <tr class="[&:nth-child(even)]:bg-blue-100">
                <td class="p-2 border-b border-gray-300">
                    Emily Davis
                </td>
                <td class="p-2 border-b border-gray-300">
                    32
                </td>
                <td class="p-2 border-b border-gray-300">
                    Product Manager
                </td>
            </tr> 
        </tbody>
    </table>
</body>

</html>

This example shows how to use arbitrary variants in Tailwind CSS to style specific rows in a table. The selector [:nth-child(even)]:bg-blue-100 applies a background color to every even-numbered row, showing how you can easily add custom styles directly in your HTML.

For example, if you want to underline the first item in a list only on large screens and only when hovering over it, and change the background color of the second item on hover, you can use the following.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="bg-gray-100 p-6">
    <div class="max-w-2xl mx-auto">
        <ul role="list" class="space-y-4">
            <!--Applying underline on hover on large screens -->
            <li class="lg:[&:nth-child(1)]:hover:underline p-4
                       border border-gray-300 rounded-lg bg-white shadow-md">
                <span class="font-medium">
                    Finalize project proposal
                </span>
                <p class="text-sm text-gray-500">
                    Hover on large screens to see underline effect.
                </p>
            </li>

            <!--Applying background color on hover on small screens -->
            <li class="[&:nth-child(2)]:hover:bg-teal-100 p-4 
                       border border-gray-300 rounded-lg bg-white shadow-md">
                <span class="font-medium">
                    Review design mockups
                </span>
                <p class="text-sm text-gray-500">
                    Hover on small screens to see background color change.
                </p>
            </li>
        </ul>
    </div>
</body>

</html>

You can even manage spaces and style nested elements with Tailwind CSS by using an underscore (_) in your class names. This technique allows you to apply styles to elements based on their position within a container, even if they are deeply nested.

Let's say you want to add a top margin to all <p> elements inside a particular container, including those nested inside other elements. You can achieve this with the following code.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-6 bg-gray-100">
    <div class="[&_p]:mt-4 bg-indigo-50 p-4 
                border border-indigo-300 rounded-lg shadow-md">
        <p>
            This paragraph will have a top margin.
        </p>
        <div>
            <p>
                This nested paragraph will also have a top margin.
            </p>
        </div>
    </div>
</body>

</html>

You can also use arbitrary variants with CSS at-rules like @media or @supports to add more flexibility to your styling. This allows you to apply styles based on browser features or viewport sizes directly in your HTML.

Here's how you can use these features with Tailwind CSS.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="bg-gray-100 p-6">
    <div class="p-4 bg-white shadow-lg">
        <p class="[@media(min-width:600px)]:text-lg 
                  [@supports(color:var(--fake-color))]:text-red-500 ">
            This text will be larger on screens wider than 600px.
        </p>
    </div>
</body>

</html>

In the example above, we use Tailwind CSS's arbitrary variants to add responsive and feature-based styles directly in our HTML. The @media(min-width:600px) part of the class makes the text larger on screens wider than 600px.

When using at-rules like @media or @supports in Tailwind CSS, you don't need to use the & placeholder for nested selectors, just like in CSS preprocessor.

You can combine at-rules with Tailwind classes. For example, to change a button's opacity on hover only if the browser supports it, use:

<button type="button" class="[@media(any-hover:hover){&:hover}]:opacity-100">
    <!-- Button content -->
</button>

In this case, the button will only change to full opacity on hover if the browser supports hover effects.

Creating a plugin

In Tailwind CSS, you can use plugins to add custom styling options and variants. The addVariant function allows you to create new styles, such as third: for styling the third item in a list.

Let's create a Tailwind CSS plugin to add a custom third: variant. This variant will style the third child of an element. Here's how you can set it up in your Tailwind configuration file:

First, define a custom plugin using the addVariant function. In your Tailwind CSS configuration file (tailwind.config.js), add the following code.

Example

// tailwind.config.js
const plugin = require('tailwindcss/plugin');

module.exports = {
  // ... other configurations
  plugins: [
    plugin(function({ addVariant }) {
      addVariant('third', '&:nth-child(3)');
    }),
  ],
};

Now you can use the third: variant in your CSS classes. Here's an example of how to apply it to a list item.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>   
 
<body class="bg-gray-100 p-4">
    
  <ul class="list-disc pl-4">
    <li class="p-2">Design</li>
    <li class="p-2">Development</li>
    <li class="p-2 third:bg-yellow-200">Testing</li>
    <li class="p-2">Deployment</li>
  </ul> 
</body>

</html>

In this example, the third:bg-yellow-200 class applies a yellow background color to the third list item.

Advanced topics

Advanced topics in Tailwind CSS cover more complex features of the framework, helping you understand its core concepts better. We'll break these ideas down into simple, easy-to-follow explanations below.

Using with your own classes

In Tailwind CSS, you can apply all available modifiers to your own custom classes, provided those classes are defined in Tailwind's layers or added through a plugin. This means you can apply Tailwind's styling features to your custom styles easily.

Let's create a custom class that adjusts its shadow and background color based on different states and screen sizes.

Add your custom styles using Tailwind's @layer utilities directive in your CSS file.

/* main.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .box-shadow-custom {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  }
}

Now use your custom class and Tailwind modifiers in your HTML to change its appearance based on different conditions.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>   
 
<body class="bg-gray-100 p-4">
 
  <div class="p-6 bg-white rounded-lg box-shadow-custom 
              hover:bg-blue-100 md:box-shadow-2xl transition-all 
              duration-300">
        <h1 class="text-xl font-bold">Interactive Box Shadow</h1>
        <p>This container features a custom box shadow. 
            It changes background color on hover and expands 
            the shadow on medium-sized screens and larger.
        </p>
  </div>
</body>

</html>

This example shows a container with a custom shadow, background color change on hover, and larger shadow on bigger screens, with smooth transitions.

Ordering stacked modifiers

In Tailwind CSS, you can combine multiple utility modifiers to create complex styles. Stacked modifiers apply different styles based on various states or conditions, and their order can affect the final appearance.

Modifiers are applied from the inside out, similar to nested function calls, meaning the sequence you use them in affects how they style the elements. For example, combining hover: with focus: or dark: with group-hover: can create styles that respond to different interactions or themes.

Let's see how to style a button using different orders of modifiers.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>   
 
<body class="bg-gray-100 p-4">  
    <div class="space-y-4">
        <!-- Button with dark mode styles and hover effect -->
        <button class="bg-gray-200 dark:bg-gray-800 text-black p-3 
                      rounded-md dark:text-white hover:bg-gray-600 
                      dark:hover:bg-gray-700">
                Dark Mode and Hover
        </button>
        
        <!-- Button with hover styles and dark mode effect -->
        <button class="bg-gray-200 text-black p-3 rounded-md
                      hover:bg-gray-600 dark:bg-gray-800 dark:text-white 
                      dark:hover:bg-gray-700">
              Hover and Dark Mode
        </button>
      </div> 
</body>

</html>

This example shows how the order of Tailwind CSS modifiers changes button styling. The first button applies dark mode styles before hover effects, while the second button applies hover effects before dark mode styles.

Modifier Ordering in Action

For most cases, the order of modifiers doesn't make a big difference, but there are situations where it does.

Example (dark:group-hover:opacity-10)

/* dark:group-hover:opacity-100 */
.dark .group:hover .dark\:group-hover\:opacity-100 {
  opacity: 1;
}

In this example, the .dark class must be a parent of .group. This arrangement means that the dark mode styles are applied to the parent container, while the group-hover styles are triggered when hovering over that container.

Example (group-hover:dark:opacity-100)

/* group-hover:dark:opacity-100 */
.group:hover .dark .group-hover\:dark\:opacity-100 {
  opacity: 1;
}

Here, the .dark class should be inside .group. This setup ensures that the hover effect is applied to elements within the .group, with the dark mode styles dependent on the hover state.

Example (prose-headings:hover:underline)

/* prose-headings:hover:underline */
.prose-headings\:hover\:underline:hover :is(:where(h1, h2, h3, h4, th)) {
  text-decoration: underline;
}

This example underlines all headings when you hover over the article container. The hover effect is applied to the container, affecting all headings inside it.

Example (hover:prose-headings:underline)

/* hover:prose-headings:underline */
.hover\:prose-headings\:underline :is(:where(h1, h2, h3, h4, th)):hover {
  text-decoration: underline;
}

In this case, the underline is applied only when hovering directly over the headings themselves. The hover effect targets the headings individually, not the container.

Quick reference:Tailwind Modifiers

This table provides a quick and easy reference for all the built-in modifiers available in Tailwind CSS. It's your go-to resource for identifying the right modifier quickly.

Modifier CSS
hover &:hover
focus &:focus
focus-within &:focus-within
focus-visible &:focus-visible
active &:active
visited &:visited
target &:target
* & > *
has &:has
first &:first-child
last &:last-child
only &:only-child
odd &:nth-child(odd)
even &:nth-child(even)
first-of-type &:first-of-type
last-of-type &:last-of-type
only-of-type &:only-of-type
empty &:empty
disabled &:hover
enabled &:enabled
checked &:checked
indeterminate &:indeterminate
default &:default
required &:required
valid &:valid
invalid &:invalid
in-range &:in-range
out-of-range &:out-of-range
placeholder-shown &:placeholder-shown
autofill &:autofill
read-only &:read-only
before &::before
after &::after
first-letter &::first-letter
first-line &::first-line
marker &::marker
selection &::selection
file &::file-selector-button
backdrop &::backdrop
placeholder &::placeholder
sm @media (min-width: 640px)
md @media (min-width: 768px)
lg @media (min-width: 1024px)
xl @media (min-width: 1280px)
2xl @media (min-width: 1536px)
min-[] @media (min-width: )
max-sm @media not all and (min-width: 640px)
max-md @media not all and (min-width: 768px)
max-lg @media not all and (min-width: 1024px)
max-xl @media not all and (min-width: 1280px)
max-2xl @media not all and (min-width: 1536px)
max-[] @media (max-width: )
dark @media (prefers-color-scheme: dark)
portrait @media (orientation: portrait)
landscape @media (orientation: landscape)
motion-safe @media (prefers-reduced-motion: no-preference)
motion-reduce @media (prefers-reduced-motion: reduce)
contrast-more @media (prefers-contrast: more)
contrast-less @media (prefers-contrast: less)
print @media print
supports-[] @supports ()
aria-checked &[aria-checked=true]
aria-disabled &[aria-disabled=true]
aria-expanded &[aria-expanded=true]
aria-hidden &[aria-hidden=true]
aria-pressed &[aria-pressed=true]
aria-readonly &[aria-readonly=true]
aria-required &[aria-required=true]
aria-selected &[aria-selected=true]
aria-[] &[aria-]
data-[] &[data-]
rtl [dir=rtl] &
ltr [dir=ltr] &
open &[open]

Tailwind CSS Pseudo-Classes Reference

Tailwind CSS includes a variety of pseudo-classes that help you apply styles based on how users interact with them. These pseudo-classes make your designs more interactive and responsive. Below is a brief guide to some frequently used pseudo-classes and how you can use them to improve your designs.

Hover (:hover)

The hover pseudo-class changes the style of an element when the user hovers over it with their mouse.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <button class="bg-teal-700 text-white py-2 
                   px-4 rounded hover:bg-teal-300">
        Hover Over Me
    </button>
</body>

</html>

In this example, the button changes its background color from dark teal to a lighter teal when hovered over.

Focus (:focus)

The focus pseudo-class styles an element when it receives focus, such as when a user clicks on a form field

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <input class="border-gray-300 p-2 rounded focus:border-green-600 
                focus:ring-2 focus:ring-green-400" placeholder="Focus on me"> 
</body>

</html>

In this example, the border and ring color of the input field turn green when it is focused.

Focus Within (:focus-within)

The focus-within pseudo-class applies styles to a parent element when it or any of its children have focus.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="p-4 border border-gray-300 rounded 
                focus-within:border-blue-500">
      <input type="text" class="p-2 border border-gray-300 rounded" 
             placeholder="Click inside me">
    </div>
</body>

</html>

In this example, the border of the <div> changes to blue when the input field inside it gains focus.

Focus Visible (:focus-visible)

The focus-visible pseudo-class styles an element when it is focused using keyboard navigation or other non-mouse inputs.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <button class="focus:outline-none focus-visible:ring 
                   focus-visible:ring-blue-800 py-2 px-4 rounded border 
                   bg-blue-400 text-white focus:ring focus:ring-blue-800">
            Keyboard Focus
      </button>
</body>

</html> 

In this example, a ring appears around the button when it is focused using keyboard navigation.

Active (:active)

The active pseudo-class applies styles to an element when it is being pressed or clicked on.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="p-4">
  <button class="bg-teal-500 text-white py-2 px-4 
                 rounded active:bg-teal-700">
          Press Me
  </button>
</body>

</html>

In this example, the button's background color changes to a darker blue when it is pressed.

Visited(:visited)

The :visited pseudo-class in Tailwind CSS styles links that users have visited. You can change their appearance, like colors, to help users recognize previously clicked links.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <a href="https://tutorialspoint.com" class="text-blue-600 
             visited:text-purple-600">
          Visit Website
    </a>
</body>

</html>

In this example, the link text color changes from blue to purple once the link has been visited.

Target (:target)

The target pseudo-class styles an element if its ID matches the part of the URL after the # symbol.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
  <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <a href="#section1" class="text-blue-600">
        Go to Section 1
    </a><hr>
    <a href="#section2" class="text-blue-600">
        Go to Section 2
    </a>
    <div id="section1" class="mt-4 p-4 border border-gray-300 
                              target:bg-yellow-100">
        <h2>Section 1</h2>
        <p>This is the first section.</p>
    </div>
    <div id="section2" class="mt-6 p-4 border border-gray-300 
                              target:bg-yellow-100">
        <h2>Section 2</h2>
        <p>This is the second section.</p>
    </div>
</body>

</html>

In this example, the background color of the section changes to yellow when the URL fragment matches the ID of the section.

First (:first-child)

The :first-child pseudo-class in Tailwind CSS targets the first child of a parent element for custom styling.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
 
  <ul class="list-disc pl-5">
      <li class="py-2 first:font-bold first:text-teal-500">
          Machine Learning
      </li>
      <li class="py-2">Web Development</li>
      <li class="py-2">Artificial Intelligence</li>
  </ul> 
</body>

</html>

In the above example, the first list item is styled with bold text and teal text color.

Last (:last-child)

The last-child pseudo-class applies styles to the last child element of its parent.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
  <ul class="list-disc pl-5">
      <li class="py-2">Machine Learning</li>
      <li class="py-2">Web Development</li>
      <li class="py-2 last:bg-gray-200 last:text-indigo-600">
          Artificial intelligence
      </li>
  </ul> 
</body>

</html> 

In this example, the last list item has a different background color and text color compared to the others.

Only (:only-child)

The only-child pseudo-class applies style to elements if it is the only child within its parent.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-50">
    <ul class="list-disc p-4 bg-cyan-100">
        <li class="py-4 only:py-0">
            Only item in the list
        </li>
        <!-- Add more <li> elements here to see the effect-->
    </ul> 
</body>

</html>

In this example, the only <li> in the list gets special padding if it is the only child.

Odd (:nth-child(odd))

The odd pseudo-class applies styles to elements that are in odd-numbered positions among their siblings.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <table class="w-full border-collapse">
        <thead>
            <tr>
                <th class="border px-2 py-2 text-sm">
                    Name
                </th>
                <th class="border px-2 py-2 text-sm">
                    Email
                </th>
                <th class="border px-2 py-2 text-sm">
                    Role
                </th>
            </tr>
        </thead>
        <tbody>
            <tr class="bg-white odd:bg-indigo-100">
                <td class="border px-2 py-2 text-sm">
                    Alice Johnson
                </td>
                <td class="border px-2 py-2 text-sm">
                    alice@example.com
                </td>
                <td class="border px-2 py-2 text-sm">
                    Developer
                </td>
              </tr>
              <tr class="bg-white odd:bg-indigo-100">
                <td class="border px-2 py-2 text-sm">
                    Bob Smith
                </td>
                <td class="border px-2 py-2 text-sm">
                    bob@example.com
                </td>
                <td class="border px-2 py-2 text-sm">
                    Designer
                </td>
              </tr>
              <tr class="bg-white odd:bg-indigo-100">
                <td class="border px-2 py-2 text-sm">
                    Charlie Davis
                </td>
                <td class="border px-2 py-2 text-sm">
                    charlie@example.com
                </td>
                <td class="border px-2 py-2 text-sm">
                    Product Manager
                </td>
            </tr>
        </tbody>
    </table>  
</body>

</html>  

In this example, every odd-numbered row in the table gets a light indigo background.

Even (:nth-child(even))

The even pseudo-class applies styles to elements that are in even-numbered positions among their siblings.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <table class="w-full border-collapse">
        <thead>
            <tr>
                <th class="border px-2 py-2 text-sm">
                    Task
                </th>
                <th class="border px-2 py-2 text-sm">
                    Assigned To
                </th>
                <th class="border px-2 py-2 text-sm">
                    Due Date
                </th>
            </tr>
        </thead>
        <tbody>
            <tr class="bg-white even:bg-teal-100">
                <td class="border px-2 py-2 text-sm">
                    Update website
                </td>
                <td class="border px-2 py-2 text-sm">
                    John Doe
                </td>
                <td class="border px-2 py-2 text-sm">
                    2024-09-15
                </td>
              </tr>
              <tr class="bg-white even:bg-teal-100">
                <td class="border px-2 py-2 text-sm">
                    Design new logo
                </td>
                <td class="border px-2 py-2 text-sm">
                    Jane Smith
                </td>
                <td class="border px-2 py-2 text-sm">
                    2024-09-20
                </td>
              </tr>
              <tr class="bg-white even:bg-teal-100">
                <td class="border px-2 py-2 text-sm">
                    Prepare presentation
                </td>
                <td class="border px-2 py-2 text-sm">
                    Alice Johnson
                </td>
                <td class="border px-2 py-2 text-sm">
                    2024-09-25
                </td>
            </tr>
        </tbody>
    </table>
</body>

</html>

In this example, we have styled the even-numbered row with a light teal background.

First-Of-Type (:first-of-type)

The first-of-type pseudo-class applies styles to the first element of its type within its parent.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <form class="max-w-lg mx-auto p-6 bg-white shadow-md rounded">
      <label for="name" class="block text-gray-700">
          Name
      </label>
      <input type="text" id="name" class="block w-full p-2 border 
              border-gray-300 rounded mb-4 first-of-type:border-blue-500" 
                  placeholder="Enter your name">

      <label for="email" class="block text-gray-700">
          Email
      </label>
      <input type="email" id="email" class="block w-full p-2 border 
              border-gray-300 rounded mb-4" placeholder="Enter your email">

      <label for="message" class="block text-gray-700">
          Message
      </label>
      <textarea id="message" class="block w-full p-2 border 
          border-gray-300 rounded" 
          placeholder="Enter your message"></textarea>

      <button type="submit" class="bg-blue-500 text-white p-2 rounded mt-4">
          Submit
      </button>
  </form>
 </body>

</html>

In this example, we applied the :first-of-type pseudo-class to the first input element, making it different from other fields in the form.

Last-Of-Type (:last-of-type)

The last-of-type pseudo-class applies styles to the last element of its type within its parent.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="max-w-lg mx-auto bg-white shadow-md rounded">
        <h2 class="text-xl font-bold mb-4">Comments</h2>
        <div class="border-t border-gray-300 pt-4">
            <div class="py-2 border-b border-gray-200">
                Comment by Jane: Great post!
            </div>
            <div class="py-2 border-b border-gray-200">
                Comment by John: Very informative.
            </div>
            <div class="py-2 border-b border-gray-200 
                        last-of-type:bg-blue-50">
                Comment by Alex: Thanks for the tips!
            </div>
        </div>
    </div>
</body>

</html>

In this example, we have applied :last-of-type in the list to get a different background color to highlight it.

Only-Of-Type (:only-of-type)

The only-of-type pseudo-class applies styles to an element if it is the only element of its type within its parent

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-200">
    <form class="max-w-lg p-4 mx-auto bg-white shadow-md rounded">
        <label for="contact-info" class="block text-gray-700">
            Contact Info
        </label>
        <input type="text" id="contact-info" 
            class="block w-full p-2 border border-gray-300 rounded 
                    mb-4 only-of-type:bg-yellow-50" 
                placeholder="Enter your contact information">

        <button type="submit" 
                class="bg-blue-500 text-white p-2 rounded mt-4">
            Submit
        </button>
    </form> 
</body>

</html> 

In this example, if there's only one <input> field in the form, it gets a yellow background to make it stand out.

Empty (:empty)

The empty pseudo-class applies styles to an element if it has no child elements or text.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4 bg-gray-200">
    <ul class="list-disc pl-5">
        <li class="empty:hidden">No Items Here</li>
        <li class="empty:hidden">Another Empty Item</li>
        <li class="empty:hidden">Another Item</li>
    </ul> 
</body>

</html>

In this example, if the list item is empty, it will be hidden.

Disabled (:disabled)

The :disabled pseudo-class styles elements that are disabled, affecting their appearance to indicate they cannot be interacted with.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <div class="p-4">
        <input type="text" class="disabled:opacity-100 
            p-2 border border-gray-300 rounded" 
            placeholder="Disabled input" disabled>
    </div>
</body>

</html>

In this example, the input field appears faded due to the disabled:opacity-50 class when it is disabled.

Enabled (:enabled)

The :enabled pseudo-class targets elements that are enabled, allowing for styling changes when they are active and interactive.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <div class="p-4">
        <input type="text" class="enabled:border-blue-700 p-2 
                                  border rounded" placeholder="Type here">
    </div> 
</body>

</html> 

In this example, the input field's border turns blue when it is enabled.

Checked (:checked)

The :checked pseudo-class applies styles to checkboxes or radio buttons that are selected or checked.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="p-4">
        <label>
            <input type="checkbox" class="appearance-none 
                  checked:bg-blue-500 h-5 w-5 border border-gray-400 rounded">
            <span class="ml-2">Checked box</span>
        </label>
    </div> 
</body>

</html>

In this example, the checkbox background changes color when checked.

Indeterminate (:indeterminate)

The :indeterminate pseudo-class styles a checkbox or radio button when it is in an indeterminate state, usually when it is neither checked nor unchecked.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="p-4">
        <label class="inline-flex items-center">
            <input type="checkbox" class="appearance-none 
                  indeterminate:bg-gray-300 h-5 w-5 border 
                  border-gray-300 rounded">
            <span class="ml-2">Indeterminate box</span>
        </label>
    </div>
</body>

</html>

In this example, the checkbox has a gray background in the indeterminate state.

Default (:default)

The :default pseudo-class targets elements that have a default value when the page initially loads, useful for preselected options.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <div class="p-4">
        <label class="inline-flex items-center">
            <input type="checkbox" class="default:ring-2 h-5 w-5 border 
                                          border-gray-300 rounded" checked>
            <span class="ml-2">Default box</span>
        </label>
    </div>
</body>

</html>

In this example, the checkbox has a ring if it was the default value.

Required (:required)

The :required pseudo-class applies styles to form inputs that are marked as required, indicating that they must be filled out.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="p-4">
        <input type="text" required class="required:border-red-500 p-2
            border border-gray-300 rounded" placeholder="Required field">
    </div> 
</body>

</html>

In this example, the input field's border turns red if it is required.

Valid (:valid)

The :valid pseudo-class styles an input element when its value meets the specified validity criteria.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="bg-gray-200 p-4">
    <div class="w-full max-w-md p-6 bg-white rounded-lg shadow-md">
        <h2 class="text-xl font-semibold mb-4">
            Phone Number Validation
        </h2>
        <form>
            <label for="phone" class="block text-gray-700 text-sm font-bold mb-2">
                Phone Number:
            </label>
            <input
              type="tel"
              id="phone"
              class="block w-full p-3 border border-gray-300 rounded-md 
                  focus:outline-none focus:border-blue-500 invalid:border-red-500 
                  valid:border-green-500"
              placeholder="123-456-7890"
              pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
              required
            />
                Please enter a phone number in the format: 123-456-7890.
        </form>
    </div> 
</body>

</html>

In this example, we use the valid:border-green-500, invalid:border-red-500, and focus:border-blue-500 classes to style the input field with different border colors based on its validity and focus state.

Invalid (:invalid)

The :invalid pseudo-class applies styles to an input element when its value does not meet the specified validity criteria.

Example

<!DOCTYPE html>
<html lang="en">
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="bg-gray-200 p-4">
    <div class="w-full max-w-md p-6 bg-white rounded-lg shadow-md">
        <h2 class="text-xl font-semibold mb-4">
            Invalid (:invalid) Styling
        </h2>
        <form>
            <label for="email" class="block text-gray-700 text-sm font-bold mb-2">
                Email:
            </label>
              <input
                  type="email"
                  id="email"
                  class="block w-full p-3 border border-gray-300 rounded-md 
                  focus:outline-none focus:border-blue-500 invalid:border-red-500"
                  placeholder="you@example.com" required
              />
            <p class="text-red-500 text-sm mt-2 hidden invalid:block">
              Please enter a valid email address.
            </p>
        </form>
    </div> 
</body>

</html>

In this example, we use the invalid:border-red-500 class to style the input field with a red border when the email address is invalid.

In-Range (:in-range)

The :in-range pseudo-class styles an input element when its value is within a specified range.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div>
        <input type="number" min="1" max="10" 
            class="in-range:border-green-500 p-2 border 
                border-gray-300 rounded" placeholder="1-10">
    </div> 
</body>

</html>

In this example, we use the in-range class to show the input border turns green if the value is within the range of 1 to 10.

Out-Of-Range (:out-of-range)

The :out-of-range pseudo-class styles an input element when its value is outside the specified range.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4">
    <div class="p-4">
        <input type="number" min="1" max="10" 
            class="out-of-range:ring-8 out-of-range:ring-red-500 p-2 border
                border-gray-300 rounded" placeholder="1-10">
    </div> 
</body>

</html>

In this example, we use :out-of-range to style an input field so that it displays a red ring when a number outside the range of 1 to 10 is entered.

Placeholder-shown (:placeholder-shown)

The :placeholder-shown pseudo-class applies styles to an input element when the placeholder text is visible.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <div class="p-4">
        <input type="text" class="placeholder-shown:border-gray-500 
                                  placeholder-shown:bg-cyan-50 p-2 border rounded" 
                                  placeholder="Enter text here">
    </div> 
</body>

</html>

In this example, we use :placeholder-shown to style a text input field so that it has a gray border and a cyan background when the placeholder text is visible.

Autofill (:autofill)

The :autofillpseudo-class styles an input element when the browser automatically fills in its value.

Example

<!DOCTYPE html>
<html lang="en">  
<head> 
    <script src="https://cdn.tailwindcss.com"></script>
</head> 

<body class="bg-gray-100 p-4">   
    <div class="w-full max-w-md p-6 bg-white rounded-lg shadow-md">
        <h2 class="text-xl font-semibold mb-4">Autofill Styling</h2>
        <form>
            <label for="email" class="block text-gray-700 text-sm font-bold mb-2">
                Email:
            </label>
            <input
                type="email"
                id="email"
                class="autofill:bg-yellow-200 block w-full p-3 border 
                    border-gray-300 rounded-md focus:outline-none 
                    focus:border-blue-500 placeholder-gray-400 "
                    placeholder="you@example.com"
                  required
            />
        </form>
    </div>
</body>

</html>

In this example, we use the autofill:bg-yellow-200 class to style the input field with a yellow background when the browser autofill the email address.

Read-Only (:read-only)

The :read-only pseudo-class applies styles to an input element that is set to read-only, meaning it cannot be modified by the user.

Example

<!DOCTYPE html>
<html lang="en">  
<head>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="p-4"> 
    <div class="p-4">
        <input type="text" class="read-only:bg-gray-100 p-2 border 
                                  border-gray-300 rounded" 
               value="Read-only text" readonly>
    </div> 
</body>

</html>

In this example, we use the read-only:bg-gray-100 class to style the input field with a gray background when it is read-only.