
-
There are many opinions on how to deal with such cases. Some recommend using the @apply directive for your components’ base styles. Others argue that you should already consider all the possible variants of your component and use JavaScript logic to apply proper classes based e.g. on the component’s props.
-
SurveyJS
JavaScript Form Builder with No-Code UI & Built-In JSON Schema Editor. Keep full control over the data you collect and tailor the form builder’s entire look and feel to your users’ needs. SurveyJS works with React, Angular, Vue 3, and is compatible with any backend or auth system. Learn more.
-
twin.macro
🦹♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
One of the more promising alternatives is twin.macro - a Babel macro that processes Tailwind classes to generate JS objects understandable by various CSS-in-JS libraries. The developer experience (DX) of using it is amazing as you not only get all of Tailwind’s features without much change to your code, but you also get much more flexibility - all that on top of the traditional benefits of CSS-in-JS. Here’s an example code:
-
While not too long, css`@apply is a lot to repeat for every class you want to “compile”. That’s why using Vite and some Rollup plugins (Vite uses Rollup under the hood) I was able to shorten it into this:
-
One of the more promising alternatives is twin.macro - a Babel macro that processes Tailwind classes to generate JS objects understandable by various CSS-in-JS libraries. The developer experience (DX) of using it is amazing as you not only get all of Tailwind’s features without much change to your code, but you also get much more flexibility - all that on top of the traditional benefits of CSS-in-JS. Here’s an example code:
-
Vanilla-extract allows you to utilize TypeScript as your CSS preprocessor, just like Sass. On top of that, it comes with Sprinkles - an atomic CSS framework that allows you to reproduce Tailwind’s utility classes.
-
Now, I’d like to mention one more Tailwind alternative that might be worth your attention - especially in regards to class composition - UnoCSS.
-
While not too long, css`@apply is a lot to repeat for every class you want to “compile”. That’s why using Vite and some Rollup plugins (Vite uses Rollup under the hood) I was able to shorten it into this:
-
Stream
Stream - Scalable APIs for Chat, Feeds, Moderation, & Video. Stream helps developers build engaging apps that scale to millions with performant and flexible Chat, Feeds, Moderation, and Video APIs and SDKs powered by a global edge network and enterprise-grade infrastructure.
-
After exploring all the above alternatives (and more), I’ve decided to implement my own, custom solution. For that, I’ve turned to Linaria - a true zero-runtime CSS-in-JS library.
-
The above config is what I used to get the shorthand and Liniaria working in Vite. To give you an overview of how it works - the twis first replaced with css\@apply and then the css template literal tag is auto-imported where necessary. I’ve only used this setup with Vite and Astro (Vite-based) so I don’t know how hard it’d be to get it working in other bundlers (though pure Rollup should work as well).