Strategies for Using @apply vs. theme() #13064
-
Hey Team! I'd like to delve into the thought process behind our choice to use
I'm curious about the considerations that lead us to choose
Why was
Additionally, do Looking forward to hearing your insights on this, thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
Adam Wathan (creator of Tailwind) does seem to advocate avoiding |
Beta Was this translation helpful? Give feedback.
-
The biggest difference is that Here's an example that has shown up in our issues/discussions a number of times over the years — say you have some custom CSS using .foo {
@apply text-red-500;
} This generates the CSS you'd expect: .foo {
color: rgb(239 68 68)
} Now say somewhere on your site you have some markup like this: <div>
<h1>The <span class="text-red-500">absolute best</span> tool for tracking your spending.</h1>
</div> ...and for some reason (people do this, I still don't know why), someone writes this CSS to tweak the @media (min-width: 900px) {
h1 > .text-red-500 {
text-decoration: underline
}
} You may be surprised to discover that now your simple .foo {
color: rgb(239 68 68)
}
@media (min-width: 900px) {
h1 > .foo {
text-decoration: underline
}
} This is because that custom CSS someone wrote that targeted the This is by design, because the whole point of - <div class="text-red-500 underline bg-black flex">
+ <div class="text-red-500 some-custom-class"> So Said another way, using our previous example: <div>
<h1>The <span class="text-red-500">absolute best</span> tool for tracking your spending.</h1>
</div> @media (min-width: 900px) {
h1 > .text-red-500 {
text-decoration: underline
}
} ...if we create that same .foo {
@apply text-red-500;
} ...it's expected that the user can do this refactoring and nothing in the browser changes: <div>
- <h1>The <span class="text-red-500">absolute best</span> tool for tracking your spending.</h1>
+ <h1>The <span class="foo">absolute best</span> tool for tracking your spending.</h1>
</div> This is why all this CSS ends up being generated: .foo {
color: rgb(239 68 68)
}
@media (min-width: 900px) {
h1 > .foo {
text-decoration: underline
}
} If we didn't generate that CSS, replacing In contrast, using .foo {
color: theme(colors.red.500);
} ...always generates this, no matter what: .foo {
color: rgb(239 68 68)
} So I also just find it unfortunate that people so often do stuff like: .some-selector {
@apply flex;
} ...instead of just: .some-selector {
display: flex;
} In this case, there's really no benefit to using It's more terse for sure, especially when dealing with breakpoints, hover states, etc. but to me it's still not worth it, I'd rather just write the properties out by hand — you're already in a CSS file writing CSS anyways. Hope that helps! |
Beta Was this translation helpful? Give feedback.
-
We use @apply almost exclusively in the rare scenarios where abstracting at the CSS level makes the most sense (as opposed to JavaScript const at top of file, inside component, or inside map loop). We don't use theme() at all. The reason @apply is compelling is the conciseness, universalness, and Prettier auto-ordering that normal Tailwind utilities afford, even inside a plain CSS file. @apply also offers the ability to quickly paste to/from React code when switching abstraction levels. If you are refactoring code, copy and paste Tailwind utilities between CSS and React means you are a lot less likely to break styles versus the tedious process of writing out longhand properties. Another advantage is that bad properties like Obviously, use extreme caution when dealing with things like |
Beta Was this translation helpful? Give feedback.
The biggest difference is that
@apply
is an enormously complicated beast that does a lot more than you think, whiletheme()
is a very simple function that just grabs a value from your theme and dumps it in the spot where you called the function.Here's an example that has shown up in our issues/discussions a number of times over the years — say you have some custom CSS using
@apply
in a pretty innocent way like this:This generates the CSS you'd expect:
Now say somewhere on your site you have some markup like this:
..…