If you haven't check TailwindCSS, you might want to. I don't want to repeat the awesomeness here π€ͺ
TL;DR. Full implementation can be found on my Github muhajirdev/svelte-tailwind-template
Get Svelte default template
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
Install dependencies
npm install --save-dev tailwindcss postcss-import @fullhuman/postcss-purgecss postcss rollup-plugin-postcss autoprefixer
Setup rollup-plugin-postcss
// rollup.config.js
...
import postcss from 'rollup-plugin-postcss'
...
export default {
plugins: [
postcss({extract: true}),
svelte(...),
...
]
}
Here's the end result
//rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss'
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/bundle.js'
},
plugins: [
postcss({
extract: true
}),
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file β better for performance
css: css => {
css.write('public/bundle.css');
}
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration β
// consult the documentation for details:
// https://github.com/rollup/rollup-plugin-commonjs
resolve({ browser: true }),
commonjs(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
Create postcss.config.js
const production = !process.env.ROLLUP_WATCH;
const purgecss = require("@fullhuman/postcss-purgecss");
module.exports = {
plugins: [
require("postcss-import")(),
require("tailwindcss"),
require("autoprefixer"),
// Only purge css on production
production &&
purgecss({
content: ["./**/*.html", "./**/*.svelte"],
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
})
]
};
Create src/main.css
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
Import src/main.css
in src/main.js
// src/main.js
import App from "./App.svelte";
import "./main.css";
const app = new App({
target: document.body,
props: {
name: "world"
}
});
export default app;
Optional
Remove public/global.css
And also remove
<link rel="stylesheet" href="global.css" />
from index.html
as we already have normalize.css from tailwind
And finally, now you can just write tailwind class
Try it <div class="bg-black">test</div>
should give you a div with black background.
Any feedback would be very appreciated :)
Originally published at https://muhajir.dev/writing/using-tailwincss-with-svelte/
Top comments (19)
Hey thanks for this - super helpful! I'm running into an issue though when I use the svelte class shorthand:
Purgecss ins't detected that I'm using the class active :(
This extractor is working for me, but I've not tested it thoroughly:
Hey Tom,
I haven't tried it yet. It's probably related to the purgecss regex.
See more here: tailwindcss.com/docs/controlling-f.... When the class name is not found anywhere in the source code. It will try to remove that code. Hence the class active is removed.
You can find the regex implementation in github.com/muhajirdev/svelte-tailw... . in
defaultExtractor
part.A quick solution for this it to put class "active" into whitelist.
Here's an example I whitelist "html", and "body" in nextjs-tailwind template github.com/muhajirdev/nextjs-tailw...
Hey,
Yeah you're right it's an issue with the regex. It matches the whole string class:active. I tried to come up with a regex that could handle that but failed miserably! My current solution was to drop that svelte feature and use the classnames package to simplify optional classes.
I think whitelisting would work too, but I'm using tailwindcss so I was adding lots of classes like that. I didn't want have to keep addind lots of little utility classes to a whitelist.
Cheers!
I've noticed as soon as I import
main.css
, I lose the styles defined in my svelte components (using thestyle
tag as normal). I don't mind so much as I prefer to do all my styling with Tailwind and usingapply
, but is that to be expected? Just want to make sure I'm not doing something wrong.I've actually solved this, so the Svelte styles work as normal alongside Tailwind:
rollup.config.js
give a name to the extracted CSS so it doesn't clash with the CSS generated by Svelte, for example:public/index.html
public/tailwind.css
to.gitignore
Hi!!
Thank you for this tutorial. I have a problem.
I'm trying to create my own classes in tailwind so I can apply them. I created the file 'tailwind.config.js', and imported it into 'postcss.config.js' as follows:
thepracticaldev.s3.amazonaws.com/i...
tailwind.config.js:
thepracticaldev.s3.amazonaws.com/i...
I try to apply the added class in the tailwind.config.js file in HTML and it doesn't apply. Could you tell me how to make it work?
Thank you so much.
Thanks a bunch for writing this! It was super easy to follow :)
One note: I ran into an issue with PostCSS and autoprefixer. I had to downgrade autoprefixer from v10 to v9.8.6.
Source
found it
templates now use
public/build/bundle.js
This was really helpful, thanks so much!!
You're welcome
Is is the same setup for sapper more or less?
i haven't tried yet with sapper unfortunately :).
Probably similar, just take a look at config file , postcss and rollup
This post made it easy to update a Svelte app for experimenting withTailwind CSS, thanks ππΎ
you're welcome
sadly this does not seem to work at time of writing this comment any longer due to github.com/rollup/rollup/issues/3443 - apparent issues with rollup
thanks so much, I struggled to get this working on my own... all the info from the libraries/frameworks seems 90% complete
Glad to hear it helps you :)