How to style nested elements based on parent class using Tailwind CSS?
Asked Answered
B

6

26

Let's say I want all the links inside white card to be black, and all the links inside orange cards to be white. I can easily do in pure CSS:

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

  a {
    color: black
  }
}

.card--danger {
  background-color: orange;
  
  a {
    color: white;
  }
}

But how can I achieve similar behaviour using Tailwind (or other CSS utility frameworks)?

Bethezel answered 1/7, 2022 at 8:40 Comment(0)
S
35

This is possible in tailwind 3.1 with the addition of the arbitrary variants feature. The way you would do this is by using a selector on the parent div:

<div className="card--primary bg-white [&>a]:text-black" >
  <a/>
  <a/>
<div/>

<div className="card--danger bg-orange [&>a]:text-white" >
  <a/>
  <a/>
<div/>
Scopas answered 1/7, 2022 at 9:21 Comment(3)
can you share the reference link hereUnderbred
@VMM there you go: tailwindcss.com/docs/…Scopas
useful example: className=" [&>span>svg_path]:hover:fill-[#F80000] "Suasion
D
24

In case of Tailwind CSS

Read the descriptive and a very brief documentation entry here: Using arbitrary variants.

As I can see you need to change the color of all the <a> links no matter how deeply they reside in the <cards>. Use an underscore between & and a selectors - [&_a]:text-black. This translates to:

.card--primary {
      
  /* arbitrarily nested <a> links */
  a {
    color: black
  }
}

On the other hand the Tailwind directive with > between & and a => [&>a]:text-black would result in this css (only the direct child <a> nodes would be styled):

.card--primary {
      
  /* direct-child <a> links */
  > a {
    color: black
  }
}

Recap: the resulting Tailwind HTML for your case:

<div className="card--primary [&_a]:text-black" >
  <a></a> !-- will be black
  <div>
    <a></a> !-- will be black
  </div>
<div/>

<div className="card--danger [&_a]:text-white" >
  <a></a> !-- will be white
  <div>
    <a></a> !-- will be white
  </div>
<div/>

That's it. I hope it is helpful.

Diann answered 12/10, 2022 at 12:34 Comment(0)
C
9

In tailwind v3 you can have arbitrary group selectors. This allows you to specify a how a certain element behaves when nested beneath a parent class.

This is useful when you have a templated element needs to appear different under certain scenarios, but doesn't know anything about its parent context.

It requires the addition of the .group class, but then you can do something like this:

<div class="card">
  <a href="#" class="text-black group-[.card--danger]:text-white">
    Normal Card
  </a>
</div>
<div class="card group card--danger bg-orange-600">
  <a href="#" class="text-black group-[.card--danger]:text-white">Danger Card</a>
</div>

Here's an example on Tailwind's playground: https://play.tailwindcss.com/IQ4W4BVdjw

Croissant answered 17/2, 2023 at 15:46 Comment(1)
This is clean. Thank you!Heraclid
S
2

Nowadays Tailwind has arbitrary variants:

<div className="[&_a]:text-blue-500">
  <a href="#">Foo</a>
</div>

Related: starting from v3.4, * can be used to style child elements:

<div className="*:text-red-500">
  <a href="#">Foo</a>
  <a href="#">Bar</a>
  <a href="#">Baz</a>
</div>
Sightless answered 8/1 at 15:50 Comment(0)
H
0

YOu can do this way

<script src="https://cdn.tailwindcss.com"></script>
<div class="relative bg-slate-100 flex min-h-screen flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12 space-y-9">
<div class="relative bg-white px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
    <div class="mx-auto max-w-md">
      
      <div class="divide-y divide-gray-300/50">
        <div class="space-y-6 py-8 text-base">
          <p>White Card with all black links:</p>
          <ul class="space-y-4">
            <li class="flex items-center">
              
              <a href="https://tailwindcss.com"> First Link</a>
            </li>
            <li class="flex items-center">
              
               <a href="https://tailwindcss.com"> Second Link</a>
            </li>
            <li class="flex items-center">
              
               <a href="https://tailwindcss.com"> Third Link</a>
            </li>
          </ul>
          </div>
       
      </div>
    </div>
  </div>


  <div class="relative bg-orange-700 px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
    <div class="mx-auto max-w-md">
      
      <div class="divide-y divide-gray-300/50">
        <div class="space-y-6 py-8 text-base text-white">
          <p>Orange Card with all white links:</p>
          <ul class="space-y-4">
            <li class="flex items-center">
              
              <a href="https://tailwindcss.com"> First Link</a>
            </li>
            <li class="flex items-center">
              
               <a href="https://tailwindcss.com"> Second Link</a>
            </li>
            <li class="flex items-center">
              
               <a href="https://tailwindcss.com"> Third Link</a>
            </li>
          </ul>
          </div>
       
      </div>
    </div>
  </div>
</div>
Hooke answered 1/7, 2022 at 12:47 Comment(0)
P
0

I see where each of you are coming from, but if you are asking how to do it strictly in Tailwind:

<div class="bg-white text-black">
  <a></a>
  <a></a>
</div>
<div class="bg-black text-white">
  <a></a>
  <a></a>
</div>

Everyone else's answer seemed a little bloated.

Penthea answered 4/11, 2022 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.