This plugin adds slash-modifier tagging support to Tailwind’s built-in child (*:
) and descendant (**:
) variants. Keep using them as usual, and optionally filter which children/descendants match using a plain selector via /selector
— no arbitrary variants needed.
Examples: */option
, **/.active
, */button[aria-label]
.
<div class="*:border-2 *:border-blue-500 */ol:bg-red-100 */ul:bg-green-100 odd:**/li:font-bold">
<ul class="">
<li>CSS</li>
<li>Good</li>
</ul>
<ol>
<li>Tailwind</li>
<li>Better</li>
</ol>
</div>
<div class="*/button[aria-label]:italic">
<button type="button" aria-label>test</button>
</div>
<div class="**/span.active:text-violet-500">
<span class="active">test</span>
</div>
Open this example in Tailwind Play: https://play.tailwindcss.com/0AXQLqxOqW
First, install the package:
npm install @toolwind/tagged-combinators
Then add it to your Tailwind config:
Tailwind v4 ( |
Tailwind v3 ( |
You can do this with Tailwind’s arbitrary variants, but the syntax is noisier:
<!-- Arbitrary variants -->
<div class="[&>*]:text-sm [&>option]:font-bold [&_span.active]:text-violet-500"></div>
<!-- Tagged combinators (this plugin) -->
<div class="*:text-sm */option:font-bold **/span.active:text-violet-500"></div>
<!-- Direct children (all) -->
<div class="*:text-sm">…</div> <!-- & > * -->
<!-- Direct children (filtered) -->
<div class="*/button:text-sm">…</div> <!-- & > button -->
<div class="*/.primary:text-sm">…</div> <!-- & > .primary -->
<!-- Any descendants -->
<section class="**:mt-2">…</section> <!-- & * -->
<section class="**/input:mt-2">…</section> <!-- & input -->
<section class="**/.active:underline">…</section> <!-- & .active -->
You can tag most selectors (no bracket syntax required): tags, classes, attributes, etc.
<div class="*/button:hover:text-red-600"></div>
<div class="**/a.active:underline"></div>
One exception is pseudo classes, as the :
conflicts with Tailwind's own variant syntax.
- Without a tag,
*:
compiles to& > *
and**:
compiles to& *
. This syntax is built into Tailwind natively and this plugin preserves it without any conflicts. - Tag using the slash modifier — no brackets needed:
*/button
,**/.active
,*/button:hover
.
I hope you find @toolwind/tagged-combinators
a valuable addition to your projects. If you have any issues or suggestions, don't hesitate to open an issue or pull request.
If you liked this, you might also like my other Tailwind CSS plugins:
- @toolwind/signals: Apply styles based on parent or ancestor state, a state-driven alterative to groups
- @toolwind/multi: Group utilities together by variant
- @toolwind/mixins: Construct reusable & aliased sets of utilities inline
- @toolwind/selector-patterns: Dynamic CSS selector patterns
- @toolwind/js: Effortless build-time JS script injection
- @toolwind/directional-shadows: Supercharge your shadow utilities with added directional support (includes directional
shadow-border
utilities too ✨) - @toolwind/default-shades: Default shades for simpler color utility classes
- @toolwind/lerp-colors: Expand your color horizons and take the fuss out of generating new—or expanding existing—color palettes