Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use nth-child(odd) css selector with Tailwind on the parent element

I'm trying to achieve the following:

<table>
  <tr class="odd:bg-white even:bg-slate-100">
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr class="odd:bg-white even:bg-slate-100">
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr class="odd:bg-white even:bg-slate-100">
    <td>name</td>
    <td>title1</td>
  </tr>
</table>

But without entering the css on each tr child tag, but once on the table tag.

Something like this: (which I couldn't make it work, btw)

<table class="--odd:bg-white even:bg-slate-100 [&:nth-child(odd)]:bg-gray-400">
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
</table>

Right now I'm doing something like this to achieve it, but I'd like to do it all with tailwind classes, if possible

<style lang="postcss">
    div.plan-details :nth-child(odd) {
        @apply text-zinc-500;
    }
    div.plan-details :nth-child(even) {
        @apply text-zinc-900;
    }
</style>

Also tried with this but it didn't work.

I have this tailwind play example with both examples

like image 610
opensas Avatar asked Sep 10 '25 19:09

opensas


2 Answers

You need to use Arbitrary variants. To put it simply:

& is self-referential which means children:pl-4 will result in .children\:pl-4 > * { .. }

To apply this logic to odd and even children, we'll use the :nth-child(odd) and :nth-child(even) selectors giving them different background colors:

[&>*:nth-child(odd)]:bg-blue-500
[&>*:nth-child(even)]:bg-red-500

In practice:

<div class=" [&>*:nth-child(odd)]:bg-red-500 [&>*:nth-child(even)]:bg-blue-500">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>

div

Tailwind-play


While this method works fine on div and li elements, it doesn't seem to work on table elements...

The user Wongjn pointed out to me that the browser injects a <tbody> element. This is why the above method is applied to all the elements when selecting odd-numbered elements. Our selector chose only one element, the <tbody> element!

Yes, the browser will often inject a <tbody> element between the <table> and elements if it does not exist, so the direct descendent selectors evaluate against the <tbody>, not the <tr> elements

tbody


To work around the <tbody> injection, we can change the selector to choose the child of the <tbody>:

[&>tbody>*:nth-child(odd)]

In practice:

<table class=" [&>tbody>*:nth-child(odd)]:bg-red-500 [&>tbody>*:nth-child(even)]:bg-blue-500">
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
  <tr>
    <td>name</td>
    <td>title1</td>
  </tr>
</table>

enter image description here

Tailwind-Play

As opensas suggested, it is possible to insert the <tbody> manually:

That's great, I guess we could also explicitly add the tbody ourselves, to avoid that browser magic, like this: Tailwind-play

<table>
  <tbody class="[&>*:nth-child(odd)]:bg-red-500 [&>*:nth-child(even)]:bg-blue-500">
    <tr>
      <td>name</td>
      <td>title1</td>
    </tr>
    <tr>
      <td>name</td>
      <td>title1</td>
    </tr>
    <tr>
      <td>name</td>
      <td>title1</td>
    </tr>
  </tbody>
</table>
like image 158
ChenBr Avatar answered Sep 13 '25 10:09

ChenBr


in tailwind there are several props explore a little one day.. you can use the Even prop of tailwind in the parent div of its children, like this:

<div className={`even:mt-8`}>
      <div>
        {/* Content*/}
      </div>
</div>
like image 32
Márcio Junior Avatar answered Sep 13 '25 10:09

Márcio Junior