Using CSS with @apply for plugin styles (instead of low-level CSS-in-JS) #3004
DaniGuardiola
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm using the excellent typography plugin and I've been trying to use tailwind's
@apply
itself to make my life much easier when extending the default plugin styles.This has led me to experiment with possible implementations.
Hacky way
I've achieved this in a hacky but effective way.
The script
What this is script does is basically read a source CSS file, process it with PostCSS using the tailwind and autoprefixer plugins, and turned into CSS-in-JS format by
postcss-js
. Then it writes the output to a JSON file that is later read from the tailwind configuration to extend the plugin styles. Note that the config used by tailwind is the 'base' one (more on that below).Tailwind config
In order to avoid recursivity when calling tailwind (as a postcss plugin), I've divided the tailwind config into two files: a base one (used from the script), and the final one which extends from the base and adds the compiled styles for the typography plugin:
package.json scripts
To run this method I've modified my
package.json
scripts so that they look like this:This has the disadvantage that the changes are not refreshed on file save when in development mode. A workaround is to run the script again, as Next.js will pick up the changes. A file watcher could be set-up for this task.
The input CSS
This is how the input CSS looks. To generate the appropriate structure, I'm using "fake selectors" that eventually get transformed into the object props that the plugin expects.
Compiled output
The output of running
tailwind-hack.js
script is written to this file:Ideas
I don't know much about PostCSS or Tailwind internals. However, with this experiment, I've learned a little bit. One idea that comes to mind is to allow asynchronous plugin functions so that you can have something like
async theme => <plugin config>
. This would allow for this hack to become less hacky.This approach could be accompanied by a bunch of secondary tools exported from the tailwind package (or maybe as
theme.<tool>
, or(theme, tool1, tool2) => <>
or(theme, { tool1, tool2 })
), for example:apply("<tailwind classes>")
function that returns CSS-in-JS structuresOf course, the config recursivity issue is still there, so maybe tailwind could detect the current "plugin scope" and use a config without the problematic prop (which is the one being generated, hence the recursivity).
There'd be some limitations too with media-queries and pseudo-states, but maybe those could also be abstracted in a similar way with some kind of standard plugin CSS-in-JS spec? IDK, just brainstorming.
Another approach that could work would be to add an option to tailwind as a postcss plugin to work synchronously. That would leave the config loader unchanged but I'm guessing there'd be tradeoffs.
Conclusion
This hack works for me, as I don't change these styles very often, but it'd be cool if there was a more practical solution to this. Just wanted to give my two cents in case it helps push this forward.
I was actually inspired to play with this by this quote from the typography plugin README:
Have a great day, whoever's reading this :)
Beta Was this translation helpful? Give feedback.
All reactions