相关文章推荐
心软的吐司  ·  一加 Ace 2_百度百科·  11 月前    · 
lichail  ·  Nintendo Switch ...·  5 年前    · 

Every utility class in Tailwind can be applied conditionally by adding a modifier to the beginning of the class name that describes the condition you want to target.

For example, to apply the bg-sky-700 class on hover, use the hover:bg-sky-700 class:

Hover over this button to see the background color change

Save changes
<button class="bg-sky-500 hover:bg-sky-700 ...">
  Save changes
</button>
How does this compare to traditional CSS?

When writing CSS the traditional way, a single class name would do different things based on the current state.

Traditionally the same class name applies different styles on hover

.btn-primary {
  background-color: #0ea5e9;
.btn-primary:hover {
  background-color: #0369a1;
}

In Tailwind, rather than adding the styles for a hover state to an existing class, you add another class to the element that only does something on hover.

In Tailwind, separate classes are used for the default state and the hover state

.bg-sky-500 {
  background-color: #0ea5e9;
.hover\:bg-sky-700:hover {
  background-color: #0369a1;
}

Notice how hover:bg-sky-700 only defines styles for the :hover state? It does nothing by default, but as soon as you hover over an element with that class, the background color will change to sky-700 .

This is what we mean when we say a utility class can be applied conditionally — by using modifiers you can control exactly how your design behaves in different states, without ever leaving your HTML.

Tailwind includes modifiers for just about everything you’ll ever need, including:

  • Pseudo-classes , like :hover , :focus , :first-child , and :required
  • Pseudo-elements , like ::before , ::after , ::placeholder , and ::selection
  • Media and feature queries , like responsive breakpoints, dark mode, and prefers-reduced-motion
  • Attribute selectors , like [dir="rtl"] and [open]
  • These modifiers can even be stacked to target more specific situations, for example changing the background color in dark mode, at the medium breakpoint, on hover:

    <button class="dark:md:hover:bg-fuchsia-600 ...">
      Save changes
    </button>

    In this guide you’ll learn about every modifier available in the framework, how to use them with your own custom classes, and even how to create your own.

    Pseudo-classes

    Hover, focus, and active

    Style elements on hover, focus, and active using the hover , focus , and active modifiers:

    Try interacting with this button to see the hover, focus, and active states

    Save changes
    <button class="bg-violet-500 hover:bg-violet-600 active:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-300 ...">
      Save changes
    </button>

    Tailwind also includes modifiers for other interactive states like :visited , :focus-within , :focus-visible , and more.

    See the pseudo-class reference for a complete list of available pseudo-class modifiers.

    First, last, odd, and even

    Style an element when it is the first-child or last-child using the first and last modifiers:

    <ul role="list" class="p-6 divide-y divide-slate-200">
      {#each people as person}
        <!-- Remove top/bottom padding when first/last child -->
        <li class="flex py-4 first:pt-0 last:pb-0">
          <img class="h-10 w-10 rounded-full" src="{person.imageUrl}" alt="" />
          <div class="ml-3 overflow-hidden">
            <p class="text-sm font-medium text-slate-900">{person.name}</p>
            <p class="text-sm text-slate-500 truncate">{person.email}</p>
          </div>
      {/each}
    

    You can also style an element when it’s an odd or even child using the odd and even modifiers:

    <tbody> {#each people as person} <!-- Use a white background for odd rows, and slate-50 for even rows --> <tr class="odd:bg-white even:bg-slate-50"> <td>{person.name}</td> <td>{person.title}</td> <td>{person.email}</td> {/each} </ tbody> </table>

    Tailwind also includes modifiers for other structural pseudo-classes like :only-child , :first-of-type , :empty , and more.

    See the pseudo-class reference for a complete list of available pseudo-class modifiers.

    Form states

    Style form elements in different states using modifiers like required , invalid , and disabled :

    Try making the email address valid to see the styles change

    < label class = " block " > < span class = " block text-sm font-medium text-slate-700 " > Username </ span > <!-- Using form state modifiers, the classes can be identical for every input --> < input type = " text " value = " tbone " disabled class = " mt-1 block w-full px-3 py-2 bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 </ label > <!-- ... --> </ form >

    Using modifiers for this sort of thing can reduce the amount of conditional logic in your templates, letting you use the same set of classes regardless of what state an input is in and letting the browser apply the right styles for you.

    Tailwind also includes modifiers for other form states like :read-only , :indeterminate , :checked , and more.

    See the pseudo-class reference for a complete list of available pseudo-class modifiers.

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

    When you need to style an element based on the state of some parent element, mark the parent with the group class, and use group-* modifiers like group-hover to style the target element:

    Hover over the card to see both text elements change color

    Create a new project from a variety of starting templates.

    <a href="#" class="group block max-w-xs mx-auto rounded-lg p-6 bg-white ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500">
      <div class="flex items-center space-x-3">
        <svg class=
    
    
    
    
        
    "h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24"><!-- ... --></svg>
        <h3 class="text-slate-900 group-hover:text-white text-sm font-semibold">New project</h3>
      </div>
      <p class="text-slate-500 group-hover:text-white text-sm">Create a new project from a variety of starting templates.</p>
    

    This pattern works with every pseudo-class modifier, for example group-focus, group-active, or even group-odd.

    Differentiating nested groups

    When nesting groups, you can style something based on the state of a specific parent group by giving that parent a unique group name using a group/{name} class, and including that name in modifiers using classes like group-hover/{name}:

    <ul role="list">
      {#each people as person}
        <li class="group/item hover:bg-slate-100 ...">
          <img src="{person.imageUrl}" alt="" />
            <a href="{person.url}">{person.name}</a>
            <p>{person.title}</p>
          </div>
          <a class="group/edit invisible hover:bg-slate-200 group-hover/item:visible ..." href="tel:{person.phone}">
            <span class="group-hover/edit:text-gray-700 ...">Call</span>
            <svg class="group-hover/edit:translate-x-0.5 group-hover/edit:text-slate-500 ...">
              <!-- ... -->
            </svg>
      {/each}
    

    Groups can be named however you like and don’t need to be configured in any way — just name your groups directly in your markup and Tailwind will automatically generate the necessary CSS.

    Arbitrary groups

    You can create one-off group-* modifiers on the fly by providing your own selector as an arbitrary value between square brackets:

    <div class="group is-published">
      <div class="hidden group-[.is-published]:block">
        Published
      </div>
    </div>

    For more control, you can use the & character to mark where .group should end up in the final selector relative to the selector you are passing in:

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

    Styling based on sibling state (peer- {modifier} )

    When you need to style an element based on the state of a sibling element, mark the sibling with the peer class, and use peer-* modifiers like peer-invalid to style the target element:

    Try making the email address valid to see the warning disappear

    < label class = " block " > < span class = " block text-sm font-medium text-slate-700 " > Email </ span > < input type = " email " class = " peer ... " /> < p class = " mt-2 invisible peer-invalid:visible text-pink-600 text-sm " > Please provide a valid email address. </ label > </ form >

    This makes it possible to do all sorts of neat tricks, like floating labels for example without any JS.

    This pattern works with every pseudo-class modifier, for example peer-focus , peer-required , and peer-disabled .

    It’s important to note that the peer marker can only be used on previous siblings because of how the general sibling combinator works in CSS.

    Won’t work, only previous siblings can be marked as peers

    <label>
      <span class="peer-invalid:text-red-500 ...">Email</span>
      <input type="email" class="peer ..."/>
    </label>

    Differentiating peers

    When using multiple peers, you can style something on the state of a specific peer by giving that peer a unique name using a peer/{name} class, and including that name in modifiers using classes like peer-checked/{name} :

    Published status
    <fieldset>
      <legend>Published status</legend>
      <input id="draft" class="peer/draft" type="radio" name="status" checked />
      <label for="draft" class="peer-checked/draft:text-sky-500">Draft</label>
      <input id="published" class="peer/published" type="radio" name="status" />
      <label for="published" class="peer-checked/published:text-sky-500">Published</label>
      <div class="hidden peer-checked/draft:block">Drafts are only visible to administrators.</div>
      <div class="hidden peer-checked/published:block">Your post will be publicly visible on your site.</div>
    </fieldset>

    Peers can be named however you like and don’t need to be configured in any way — just name your peers directly in your markup and Tailwind will automatically generate the necessary CSS.

    Arbitrary peers

    You can create one-off peer-* modifiers on the fly by providing your own selector as an arbitrary value between square brackets:

    <form>
      <label for="email">Email:</label>
      <input id="email" name="email" type="email" class="is-dirty peer" required />
      <div class="peer-[.is-dirty]:peer-required:block hidden">This field is required.</div>
      <!-- ... -->
    </form>

    For more control, you can use the & character to mark where .peer should end up in the final selector relative to the selector you are passing in:

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

    Pseudo-elements

    Before and after

    Style the ::before and ::after pseudo-elements using the before and after modifiers:

    Email
    <label class="block">
      <span class="after:content-['*'] after:ml-0.5 after:text-red-500 block text-sm font-medium text-slate-700">
        Email
      </span>
      <input type="email" name="email" class="mt-1 px-3 py-2 bg-white border shadow-sm border-slate-300 placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-sky-500 block w-full rounded-md sm:text-sm focus:ring-1" placeholder="[email protected]" />
    </label>

    When using these modifiers, Tailwind will automatically add content: '' by default so you don’t have to specify it unless you want a different value:

    When you look annoyed all the time, people think that you're busy.
    <blockquote class="text-2xl font-semibold italic text-center text-slate-900">
      When you look
      <span class="before:block before:absolute before:-inset-1 before:-skew-y-3 before:bg-pink-500 relative inline-block">
        <span class="relative text-white">annoyed</span>
      </span>
      all the time, people think that you're busy.
    </blockquote>

    It’s worth noting that you don’t really need ::before and ::after pseudo-elements for most things in Tailwind projects — it’s usually simpler to just use a real HTML element.

    For example, here’s the same design from above but using a <span> instead of the ::before pseudo-element, which is a little easier to read and is actually less code:

    <blockquote class="text-2xl font-semibold italic text-center text-slate-900">
      When you look
      <span class="relative">
        <span class="block absolute -inset-1 -skew-y-3 bg-pink-500" aria-hidden="true"></span>
        <span class="relative text-white">annoyed</span>
      </span>
      all the time, people think that you're busy.
    </blockquote>
    

    Save before and after for situations where it’s important that the content of the pseudo-element is not actually in the DOM and can’t be selected by the user.

    Note that if you’ve disabled our preflight base styles, the content property will not be set to an empty string by default, and you will need to include content-[''] any time you use the before and after modifiers.

    If you’ve disabled preflight make sure to set the content manually

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

    Placeholder text

    Style the placeholder text of any input or textarea using the placeholder modifier:

    <label class="relative block">
      <span class="sr-only">Search</span>
    
    
    
    
        
    
      <span class="absolute inset-y-0 left-0 flex items-center pl-2">
        <svg class="h-5 w-5 fill-slate-300" viewBox="0 0 20 20"><!-- ... --></svg>
      </span>
      <input class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-2 pl-9 pr-3 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm" placeholder="Search for anything..." type="text" name="search"/>
    </label>

    File input buttons

    Style the button in file inputs using the file modifier:

    <form class="flex items-center space-x-6">
      <div class="shrink-0">
        <img class="h-16 w-16 object-cover rounded-full" src="https://images.unsplash.com/photo-1580489944761-15a19d654956?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1361&q=80" alt="Current profile photo" />
      </div>
      <label class="block">
        <span class="sr-only">Choose profile photo</span>
        <input type="file" class="block w-full text-sm text-slate-500
          file:mr-4 file:py-2 file:px-4
          file:rounded-full file:border-0
          file:text-sm file:font-semibold
          file:bg-violet-50 file:text-violet-700
          hover:file:bg-violet-100
      </label>
    </form>

    Note that Tailwind’s border reset is not applied to file input buttons. This means that to add a border to a file input button, you need to explicitly set the border-style using a class like file:border-solid alongside any border-width utility:

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

    List markers

    Style the counters or bullets in lists using the marker modifier:

    Ingredients

  • 5 cups chopped Porcini mushrooms
  • 1/2 cup of olive oil
  • 3lb of celery
  • <ul role="list" class="marker:text-sky-400 list-disc pl-5 space-y-3 text-slate-500">
      <li>5 cups chopped Porcini mushrooms</li>
      <li>1/2 cup of olive oil</li>
      <li>3lb of celery</li>
    </ul>