2

I’m working on a responsive grid layout using Tailwind CSS and want to style grid items differently based on the screen size.

Here’s a simplified example of my code:

<html lang="en">

<head>
  <script src="https://unpkg.com/@tailwindcss/browser"></script>
</head>

<body class="bg-gray-800">
  <section class="container mx-auto my-10 text-white">
    <div class="grid grid-cols-2 gap-10 text-white xl:grid-cols-4 [&>*:nth-child(2n+1)]:bg-blue-500 xl:[&>*:nth-child(4n+1)]:bg-blue-500">
      <div class="size-20 bg-gray-600">1</div>
      <div class="size-20 bg-gray-600">2</div>
      <div class="size-20 bg-gray-600">3</div>
      <div class="size-20 bg-gray-600">4</div>
      <div class="size-20 bg-gray-600">5</div>
      <div class="size-20 bg-gray-600">6</div>
      <div class="size-20 bg-gray-600">7</div>
      <div class="size-20 bg-gray-600">8</div>
      <div class="size-20 bg-gray-600">9</div>
      <div class="size-20 bg-gray-600">10</div>
    </div>
  </section>
</body>

</html>

What I’m trying to achieve:

  • Below xl screens (default): Make every odd item (1, 3, 5, 7, 9) blue.

  • At xl breakpoint: Only make every 4th starting at 1 (1, 5, 9) blue.

The issue:

When I resize to xl screens, both selectors apply at the same time.
So instead of only 1, 5, 9 being red, I get 1, 3, 5, 7, 9.

It looks like Tailwind’s xl: prefix doesn’t override the base [&>*:nth-child()] rule, and both are active.

Question:

How can I properly switch nth-child selectors at different Tailwind breakpoints so that only the desired styles are applied per breakpoint?

3
  • honestly? Don't use tailwind and just use honest to goodness plain old normal CSS in a stylesheet. Instantly solve your problem by just... writing plain CSS in a few @media rules. Commented Sep 8 at 14:17
  • @mike-pomax-kamermans Thanks for your valuable opinion, but Tailwind is awesome! The coding experience is much smoother. I’ve worked with various CSS frameworks, including vanilla CSS and Bootstrap. From my experience, Tailwind gives me the best coding experience. To explain how good it really is—it feels like coding in VS Code instead of Sublime. Interestingly, I switched to Tailwind just a few days ago. Commented Sep 8 at 14:26
  • Related: How to access all the direct children of a div in Tailwind CSS? Commented Sep 8 at 14:36

1 Answer 1

2

You can use the odd and even variants.

Use the max-breakpoint variants alongside the breakpoint variants, so you can revoke the odd-item styling above the XL breakpoint.

And then you just need to chain the variants together. From left to right, in order of importance: first, declare the breakpoint, then use * to select the nested child elements, and finally, with odd/even, target the child elements and specify the styling for odd or even.

By default, up to the XL breakpoint, the odd children of the current element should have a blue background.

max-xl:*:odd:bg-blue-500

From the XL breakpoint onward, the even children of the current element should have a blue background.

xl:*:even:bg-blue-500

Example:

<script src="https://unpkg.com/@tailwindcss/browser"></script>

<div class="grid grid-cols-2 gap-10 text-white xl:grid-cols-4 max-xl:*:odd:bg-blue-500 xl:*:even:bg-blue-500">
  <div class="size-20 bg-gray-600">1</div>
  <div class="size-20 bg-gray-600">2</div>
  <div class="size-20 bg-gray-600">3</div>
  <div class="size-20 bg-gray-600">4</div>
  <div class="size-20 bg-gray-600">5</div>
  <div class="size-20 bg-gray-600">6</div>
  <div class="size-20 bg-gray-600">7</div>
  <div class="size-20 bg-gray-600">8</div>
  <div class="size-20 bg-gray-600">9</div>
  <div class="size-20 bg-gray-600">10</div>
</div>

Now that clarified this, you can replace odd and even with special arbitrary variants using the requested child selectors:

Make every odd item (1, 3, 5, 7, 9) blue

max-xl:*:odd:bg-blue-500

Only make every 4th starting at 1 (1, 5, 9) blue

xl:*:[:nth-child(4n+1)]:bg-blue-500

Example:

<script src="https://unpkg.com/@tailwindcss/browser"></script>

<div class="grid grid-cols-2 gap-10 text-white xl:grid-cols-4 max-xl:*:odd:bg-blue-500 xl:*:[:nth-child(4n+1)]:bg-blue-500">
  <div class="size-20 bg-gray-600">1</div>
  <div class="size-20 bg-gray-600">2</div>
  <div class="size-20 bg-gray-600">3</div>
  <div class="size-20 bg-gray-600">4</div>
  <div class="size-20 bg-gray-600">5</div>
  <div class="size-20 bg-gray-600">6</div>
  <div class="size-20 bg-gray-600">7</div>
  <div class="size-20 bg-gray-600">8</div>
  <div class="size-20 bg-gray-600">9</div>
  <div class="size-20 bg-gray-600">10</div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

Actually, I want the first element of each row to be styled, no matter how many columns there are—that’s why I was using nth-child. Your solution works well with max-xl instead of xl, thanks! Also, I want to use custom classes instead of bg-blue-500. Is it possible to apply a custom class with [&>*:nth-child(...)]? I tried it, but it didn’t work. How can I make this work?
You can apply utilities. In v4, you must declare the required classes using @utility to do this. First playground - not working without @utility and Second playground - working with @utility
Or you can add inline CSS as an arbitrary value, like this: play.tailwindcss.com/s33Y8EZvUl

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.