Custom group "states" in tailwind css

owzim

There are essentially just two states for groups out-of-the-box: hover and focus

Simplified examples:

<div class="group">
  <p class="group-hover:text-gray-900">foo</p>
  <p class="group-hover:text-gray-500">bar</p>
</div>
<a class="group">
  <span class="group-focus:text-gray-900">foo</span>
  <span class="group-focus:text-gray-500">bar</span>
</a>

Ho to add custom states, so this is possible:

<a class="group">
  <span class="group-foo-state:text-gray-900">foo</span>
  <span class="group-foo-state:text-gray-500">bar</span>
</a>

and with the custom state foo-state active

<a class="group foo-state">
  <span class="group-foo-state:text-gray-900">foo</span>
  <span class="group-foo-state:text-gray-500">bar</span>
</a>

Essentially mimicking the CSS cascade.

Ihar Aliakseyenka

You can write plugin or use same arbitrary variants since Tailwind 3.1. It is not quite group properties but uses same concept - so instead of .group it may contain any class name you wish but it would be convenient to use .group

// tailwind.config.js

const plugin = require('tailwindcss/plugin')

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      // ...
    },
  },
  plugins: [
    plugin(function({ addVariant }) {
      addVariant('group-with-foo', '.group.foo &') // custom CSS
      addVariant('group-no-foo', '.group:not(.foo) &')
    })
  ],
}

addVarinat function is what creates new variant. First argument - variant name, should be unique. Second - any valid CSS as string (or function which should return string).

& sign points to an element with THIS custom variant. Your plugin SHOULD have either & or starts with @ symbol otherwise it will not be valid.

<a class="group">
  <span class="group-with-foo:bg-red-500">
    Parent has NOT `foo` class therefore I'm NOT red
  </span>
  <span class="group-no-foo:bg-red-500">
    Parent has NOT `foo` class but it doesn't matter (it has `group` though)
  </span>
</a>

<hr>

<a class="group foo">
  <span class="group-with-foo:bg-red-500">
    It is red because parent has BOTH `group` and `foo` class
  </span>
  <span class="group-no-foo:bg-red-500">
    Parent has `foo` class therefore I'm not red
  </span>
</a>

If you need to use arbitrary variants you need to pass same CSS as seconda argument, but instead of spaces you should use _. If your class has _ sign, it must be escaped as \_

<a class="group">
  <span class="[.group.foo_&]:bg-red-500">
    It is red because parent has BOTH `group` and `foo` class
  </span>
  <span class="[.group:not(.foo)_&]:bg-red-500">
    Parent has `foo` class therefore I'm not red
  </span>
</a>

DEMO

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related