Direct Children Selector in Tailwind CSS
Have you ever looked at markup like this and thought to yourself, whoa, this is a lot of repetition? That's a valid concern and one of the trade-offs of working with Tailwind CSS. Consider the following:
export default function DirectChildren() { return ( <div className="mx-auto max-w-5xl p-4"> <h1 className="text-2xl font-medium">Direct children selector</h1> <ul className="mt-6 flex flex-wrap gap-x-4 gap-y-3 font-medium"> <li className="rounded-full bg-amber-200 px-5 py-1 text-amber-800"> you </li> <li className="rounded-full bg-amber-200 px-5 py-1 text-amber-800"> can </li> <li className="rounded-full bg-amber-200 px-5 py-1 text-amber-800"> now </li> <li className="rounded-full bg-amber-200 px-5 py-1 text-amber-800"> style </li> ... </ul> </div> );}
Here, you can see that each li
element is styled in the same manner. This repetition could make your code look cluttered and harder to maintain.
One method to tidy up this code is by taking advantage of the *:class
syntax, a direct children selector that you can use in Tailwind CSS. This little trick lets us apply styles to direct children of an element from the parent, thereby making our HTML more concise. Here's how the same code would look using the direct children selector:
export default function DirectChildren() { return ( <div className="mx-auto max-w-5xl p-4"> <h1 className="text-2xl font-medium">Direct children selector</h1> <ul className="mt-6 flex flex-wrap gap-x-4 gap-y-3 font-medium *:rounded-full *:bg-amber-200 *:px-5 *:py-1 *:text-amber-800"> <li>you</li> <li>can</li> <li>now</li> ... </ul> </div> );}
In the updated code, all the styles for the li
items are applied from the ul
element using the *:class
syntax. However, keep in mind that this approach might not be suitable for all scenarios, especially when you're responsible for the direct children of an element.
Transcript
00:00 Have you ever looked at markup like this and thought to yourself, whoa, this is a lot of repetition. That's a valid concern and one of the trade-offs of working with Tailwind CSS. Personally, I don't mind this too much because I'm really fast with multi-cursor and find and replace. I also know that in many cases, instead of all these li items,
00:19 I would have an abstracted component which is maintained in one place, or even just a loop where I repeat the same markup and style it in one place. This is going to work great like this, but perhaps there's a specific reason why you want to apply styles from the parent element, the ul here, and then have these styles apply to each li item.
00:38 Well, with the new direct children selector in Tailwind, you can do that. I will copy the string of classes from the first element, and now I will delete all of these class name attributes on all the li items. We have much more concise HTML, but obviously, we've lost the styles.
00:55 If I apply the styles on the parent here, this is definitely not going to do what we want. It's going to apply these styles to the ul element instead. Let's move these classes outside and comment them out for a bit. We're going to use the direct child modifier to apply these classes to the direct children.
01:14 This is the shortest modifier in Tailwind, star column. Then let's start by bringing this bg-ember-200 class. You can see that all the children elements, these li items, have these styles applied. If I hover, you can see it's created this direct child,
01:31 and then anything that is a direct child, and that's how it works. I'll delete this class. Let's do the same with rounded-full, star-rounded-full. It's working. I will bring the last four classes, or maybe this was three classes. I'll make sure that they are prefixed with the star selector.
01:50 We're back in business, but now all the classes for the children, the li items, have been applied from the parent. I wouldn't use this as the default approach, but there are cases where you may not be able to control the direct children of an element. In that case, it makes sense to be able to
02:07 target the styles for these direct children from the parent.
- Play Replace Remix's unstable_parseMultipartFormData with @mjackson/form-data-parser
Replace Remix's unstable_parseMultipartFormData with @mjackson/form-data-parser
- Play Epic Workshop Diff Tab Demo
Epic Workshop Diff Tab Demo
- Play Epic Workshop Test Tab Demo
Epic Workshop Test Tab Demo
- Play Get Started with the Epic Workshop App (for React)
Get Started with the Epic Workshop App (for React)
- Play Prisma Typed SQL Queries
Prisma Typed SQL Queries
- Play A Deep Dive in Tailwind Font Settings
A Deep Dive in Tailwind Font Settings