DEV Community

Charlie Gerard
Charlie Gerard

Posted on

7 1

Writing a TailwindCSS variant plugin

I've been using TailwindCSS for the past few months and wanted to spend some time understanding how to create custom plugins.
I noticed that the CSS pseudo-element :first-line was not available by default in Tailwind so I decided to implement it myself by creating a variant plugin.

When using TailwindCSS, you add a tailwind.config.js file to your codebase where you specify different settings, themes, etc.
It's also in this file that you can add plugins.

To get started, you need to add a function inside the plugins property of your config file.

// tailwind.config.js
plugins: [
    plugin(({ addVariant, e }) => {
    })
]
Enter fullscreen mode Exit fullscreen mode

The addVariant is a helper function to register custom variants and e is for escaping strings meant to be used in class names.

Inside this plugin function is where you need to write the logic.

In the end, I'd like to be able to write classes with the following syntax: first-line:text-red. This would set the color of the first line of an element to red, for example.

By default, text-red works but sets the color of the whole element, so how can we make the prefix first-line: work?

Here's the full code sample that I'll explain below.

addVariant("first-line", ({ modifySelectors, separator }) => {
  modifySelectors(({ className }) => {
    const newClass = e(`first-line${separator}${className}`);
    return `.${newClass}:first-line`;
  });
});
Enter fullscreen mode Exit fullscreen mode

In addVariant, I specify the name of my variant, here first-line.

Then, we need to use the modifySelectors function, and the separator option that lets you customise what character or string should be used to separate variant prefixes, in our case :.

Inside modifySelectors, we have access to the class that first-line is applied to.

As we want to be able to write first-line:text-red, when the plugin detects that first-line is used, the separator is : and the className is text-red.

Then, this function returns this entire class and appends :first-line to target the first line of the element, the same way you would write it using vanilla CSS.

This way, the className generated in the end is .first-line\:text-red:first-line. Tailwind does its magic to use the color red, and this variant makes sure it's only applied to the first line of the element it's applied to. πŸŽ‰

And that's it! πŸ™‚ If you'd like to have a look at the source code, you can find it on Github.

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay