Published on

Styling Nested Elements Based on Parent Class in Tailwind CSS

Authors
  • Name
    Ripal & Zalak
    Twitter

Styling Nested Elements Based on Parent Class in Tailwind CSS

When building web applications, you may encounter scenarios where you need to style nested elements differently based on their parent class. Tailwind CSS, being a utility-first framework, provides an efficient way to achieve this without writing custom CSS. Let’s explore how.

The Problem

In traditional CSS, you might write something like this:

.card--primary {
  background-color: white;

  a {
    color: black;
  }
}

.card--danger {
  background-color: orange;

  a {
    color: white;
  }
}

In Tailwind CSS, we aim to achieve this functionality using utility classes without writing custom styles.

Solution

Tailwind CSS version 3.1 introduced arbitrary variants, allowing you to target nested elements efficiently.

Here’s how you can style links inside different parent cards using Tailwind:

<div className="card--primary bg-white [&>a]:text-black">
  <a href="#">Primary Link</a>
  <a href="#">Another Link</a>
</div>

<div className="card--danger bg-orange-500 [&>a]:text-white">
  <a href="#">Danger Link</a>
  <a href="#">Another Link</a>
</div>

Explanation

  1. Direct Child Selector ([&>a]):

    • &>a targets only the direct child <a> elements of the parent.
    • Example: className="[&>a]:text-black" applies the text-black utility to direct child <a> tags.
  2. Arbitrary Variants for Descendants ([&_a]):

    • If you need to style all <a> elements nested within the parent, use [_a].
    • Example:
    <div className="card--primary [&_a]:text-black">
      <a href="#">Black Text</a>
      <div>
        <a href="#">Still Black Text</a>
      </div>
    </div>
    

Advanced Example: Group Selectors

For scenarios where nested styles depend on dynamic states or parent class changes, you can use group-based selectors:

<div className="card card--danger group bg-orange-500">
  <a href="#" className="text-black group-[.card--danger]:text-white">
    Styled Link
  </a>
</div>

Here:

  • .group enables grouping.
  • group-[.card--danger]:text-white applies text-white when the parent has the card--danger class.

FAQs

1. What if I need to style deeply nested elements?

Use [_tag] instead of [&>tag] to target all matching elements, regardless of depth.

<div className="card--primary [&_a]:text-black">
  <a href="#">Black Text</a>
  <div>
    <a href="#">Still Black Text</a>
  </div>
</div>

2. Can this be used with hover or focus states?

Yes! Combine arbitrary variants with pseudo-classes like this:

<div className="card--danger [&>a:hover]:text-yellow-300">
  <a href="#">Hover me!</a>
</div>

3. How does this compare to traditional CSS?

This approach reduces the need for writing custom CSS, streamlining the process with Tailwind’s utility classes.