Closed HellPat closed 6 years ago
If you're using Tailwind with plain old CSS (which you can totally do), then you'll need to use a PostCSS library that supports inline imports. I use postcss-import. You may also want to look at using cssnext, which I believe includes this by default.
Let me know if that doesn't solve your issues!
@reinink I'm also trying to get this to work using the postcss-import plugin and am getting the same error.
@import must precede all other statements (besides @charset)
Would you mind sharing a sample gulp config?
Here is mine.
var gulp = require('gulp');
gulp.task('css', function () {
var postcss = require("gulp-postcss");
var atimport = require('postcss-import');
var tailwindcss = require("tailwindcss");
return gulp.src('styles/style.css')
.pipe(postcss([
atimport(),
tailwindcss('./styles/config.js'),
require('autoprefixer'),
]))
.pipe(gulp.dest(''));
});
Edit: after a bit more digging, I can get this to work by creating a style.css entry point that imports my base tailwinds css and then any other files.
@reinink the trick mentioned by @SmashBrando works. I already use postcss-import, but this plugin produced this warning.
Now I import the @tailwind preflight;
from an other file.
My main.css
looks like that:
@import "_reset";
@import "_breadcrumb";
@import "_utilities";
and i moved the @tailwind …
calls to _reset
/_utilities
.
This is not optimal, maybe we can document this behaviour on https://tailwindcss.com/docs/installation in a extra using with postcss-import seciton or smth. like that?
Or maybe you a better way and want to share your config?
I'm using nuxt and have set up tailwind according to the nuxt example. I get the same error message which makes me think that the documentation is wrong for tailwind webpack.
warning in ./assets/css/tailwind.css
(Emitted value instead of an instance of Error) postcss-import: /Users/nappdev/projects/webviewer2/assets/css/tailwind.css:25:4:
@import must precede all other statements (besides @charset)
@ ./assets/css/tailwind.css 4:14-147 13:3-17:5 14:22-155
@ ./.nuxt/App.js
@ ./.nuxt/index.js
@ ./.nuxt/client.js
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
I've set up postcss.config.js
as:
module.exports = {
plugins: [
require('tailwindcss')('./tailwind.js'),
require('postcss-import'),
require('postcss-custom-properties'),
require('postcss-color-function'),
require('autoprefixer')
]
}
My tailwind.css
is:
@tailwind preflight;
@import "variables.css";
@import "icons.css";
@tailwind utilities;
@psren Your work-around is the only way I can get it to work. I tried to require
postcss-import before tailwindcss but that did nothing.
I've changed my tailwind.css
to:
@import "preflight.css";
/**
* Here you would add any of your custom component classes; stuff that you'd
* want loaded *before* the utilities so that the utilities could still
* override them.
*
* Example:
*
* .btn { ... }
* .form-input { ... }
*
* Or if using a preprocessor:
*
* @import "components/buttons";
* @import "components/forms";
*/
@import "variables.css";
@import "icons.css";
@import "utilities.css";
/**
* Here you would add any custom utilities you need that don't come out of the
* box with Tailwind.
*
* Example :
*
* .bg-pattern-graph-paper { ... }
* .skew-45 { ... }
*
* Or if using a preprocessor..
*
* @import "utilities/backgrond-patterns";
* @import "utilities/skew-transforms";
*/
preflight.css and utilities.css contains the 2 tailwind calls
@dotnetCarpenter You need to run postcss-import
before Tailwind and make sure any @tailwind
calls are moved out to their own files to satisfy that error you pasted:
@import must precede all other statements (besides @charset)
The problem is @tailwind
is coming before an @import
which is invalid according to the CSS spec, and postcss-import
is strict about that. You'd get the same error even if you had a file like this:
.foo {
color: blue;
}
@import "icons.css";
So it's not really a Tailwind issue specifically, just that when using postcss-import
you can't have any additional code before any @import
statements.
So the solution like you noticed is to make your main CSS file only import statements, so you're free to order them as you like. This means wrapping all other code (including @tailwind
statements) in separate files.
Yes you're right. Which is also what I have done. The issue is that the example does not and I bet that most nuxt users, like me, will copy the example before they google and find the work-around. I've updated the example to reflect the work-around...
Sorry posted in wrong issue.. Moved to https://github.com/nuxt/nuxt.js/issues/2094
Hmm even @reinink says it inlines imports... https://github.com/tailwindcss/tailwindcss/issues/45#issuecomment-341281707
It does inline imports, it's just strict about the fact that imports must come first in the file. You copy and pasted an error you saw yourself explaining that:
warning in ./assets/css/tailwind.css
(Emitted value instead of an instance of Error) postcss-import: /Users/nappdev/projects/webviewer2/assets/css/tailwind.css:25:4:
@import must precede all other statements (besides @charset)
@ ./assets/css/tailwind.css 4:14-147 13:3-17:5 14:22-155
@ ./.nuxt/App.js
@ ./.nuxt/index.js
@ ./.nuxt/client.js
@ multi webpack-hot-middleware/client?name=client&reload=true&timeout=30000&path=/__webpack_hmr ./.nuxt/client.js
That stack trace is postcss-import
saying "imports must come before any other code in a file".
Since @tailwind
calls are not imports, it errors. As we've talked about in this thread, the solution is to wrap all of your code in separate files. Again, it's not a Tailwind-specific issue; that's how that plugin works.
It inlines the imports perfectly as long as your imports come before other code, like the error message explains, and like you noticed after extracting the Tailwind calls to separate files.
Thanks for clarifying. I think the following is very confusing:
/* Or if using a preprocessor:
*
* @import "components/buttons";
* @import "components/forms";
*/
Since PostCSS is a transpiler, which makes it a preprocessor in my book, not writing how to use tailwind with PostCSS import transformations is very confusing. Can we agree to a different wording?
Since tailwind calls are not imports, it errors. As we've talked about in this thread, the solution is to wrap all of your code in separate files. Again, it's not a Tailwind-specific issue; that's how that plugin works.
thats all true.
Mmmh, maybe we could add some example configurations to https://tailwindcss.com/docs/installation#3-use-tailwind-in-your-css and not only the one example.
This should not be a problem in maintenance because this one file most likely won't change at all.
@psren Totally, we actually plan to add a separate page for each that documents any of the preprocessor-specific gotchas, like how you can't nest @screen
with Less, how you have to disable processCssUrls
using Sass with Laravel Mix, or how you have to wrap Tailwind features with @css {}
in Stylus.
Maybe just linking to some quick gists for each one from the docs would be a good interim solution though.
Some people reading this far might find this summary useful. I solved this by switching the following lines in my main CSS file from:
@tailwind preflight;
@tailwind components;
@tailwind utilities;
to:
@import "tailwindcss/preflight";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
and ensuring postcss-import
came before tailwind
in my postcss config:
require('postcss-import'),
require('tailwindcss')('./src/css/tailwind.js'),
Thanks to the points made by @dotnetCarpenter and @adamwathan.
Whether I missed this or not, one thing in addition to @harrygreen's suggestion is this: @apply and @import in the same root css file will break things.
My webpack.config.js loads styles.css
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const path = require('path')
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'styles.css',
},
module: {
rules: [{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader'
]
})
}]
},
plugins: [
new ExtractTextPlugin('styles.css')
]
}
This top-level styles.css
only at-imports things:
/** Tailwind */
@import "tailwindcss/preflight";
@import "tailwindcss/components";
/** My components. */
@import "./alerts.css";
/* This would fail ---
.something {
@apply .m-2
}
*/
/** Tailwind again */
@import "tailwindcss/utilities";
My alerts.css
component:
.alert {
@apply .m-2 .px-4 .py-3 .rounded
}
/* etc */
@rhyswat You're misunderstanding the problem in your example — it's not that using @apply
in the same file as @import
breaks things, it's that you cannot have any non-import statements before any import statements.
In your example the reason adding the rule with @apply
breaks things is because now you have a non-import statement preceding an import statement.
postcss-import will refuse to process this file for example:
.foo { color: blue }
@import "tailwindcss/utilities";
...because .foo { ... }
comes before @import "tailwindcss/utilities"
which is not allowed as per the spec:
The @import CSS at-rule is used to import style rules from other style sheets. These rules must precede all other types of rules, except @charset rules.
This will totally work:
/** Tailwind */
@import "tailwindcss/preflight";
@import "tailwindcss/components";
/** My components. */
@import "./alerts.css";
/** Tailwind again */
@import "tailwindcss/utilities";
.something {
@apply .m-2
}
But you might not want your CSS in that order. In that case, the correct solution is for this file to only contain import statements and any non-import rules to other files that can be imported, so that you are following the spec while still having control over your CSS order.
So again it has nothing to do with @apply
, postcss-import just doesn't allow you to have any CSS come before any import statements.
@adamwathan Can you share a sample vue-cli project where we can use the @apply directive in imported stylesheets? I wasted a day trying every suggested solution in here.
I have the same problem, I am trying this in a Laravel project but I can't do it using scss.
Some people reading this far might find this summary useful. I solved this by switching the following lines in my main CSS file from:
@tailwind preflight; @tailwind components; @tailwind utilities;
to:
@import "tailwindcss/preflight"; @import "tailwindcss/components"; @import "tailwindcss/utilities";
and ensuring
postcss-import
came beforetailwind
in my postcss config:require('postcss-import'), require('tailwindcss')('./src/css/tailwind.js'),
Thanks to the points made by @dotnetCarpenter and @adamwathan.
Some people reading this far might find this summary useful. I solved this by switching the following lines in my main CSS file from:
@tailwind preflight; @tailwind components; @tailwind utilities;
to:
@import "tailwindcss/preflight"; @import "tailwindcss/components"; @import "tailwindcss/utilities";
and ensuring
postcss-import
came beforetailwind
in my postcss config:require('postcss-import'), require('tailwindcss')('./src/css/tailwind.js'),
Thanks to the points made by @dotnetCarpenter and @adamwathan.
Thank you! thank you! you saved me many hours of work, I could not find a solution that worked for me! Now I just need to work with postcss-font-magician and it would be great!!
@adamwathan I think the docs miss this tiny piece from @harrygreen 's answer above:
...and ensuring postcss-import came before tailwind in my postcss config
I was pulling my hair out till I found this 🙂
Already mentioned in this page:
Then add it as the very first plugin in your PostCSS configuration
Already mentioned in this page:
Then add it as the very first plugin in your PostCSS configuration
True, but the examples in the installation document do not make this clear.
Keep in mind that some postcss plugins, like postcss-import
, must come before tailwind to make it work.
@burmashave that's because it only mentions how to install tailwindcss
itself on that page. It doesn't make any assumptions on what other plugins you might or might not use.
From the postcss-import
docs:
This plugin should probably be used as the first plugin of your list. This way, other plugins will work on the AST as if there were only a single file to process, and will probably work as you can expect.
Might be helpful to add a note about plugin order being important and affecting the generated CSS. Pretty sure a PR that mentions it would be welcome (without being too specific and refering to just one plugin).
@burmashave that's because it only mentions how to install
tailwindcss
itself on that page. It doesn't make any assumptions on what other plugins you might or might not use.
@hacknug The section I linked to in the installation docs is entitled "Using Tailwind with PostCSS." So it clearly makes an assumption you might want to use Tailwind with ... PostCSS. The code snippets displayed there suggest that you only need to require 'tailwindcss' and 'autoprefixer', and make no mention of their order in the postcss.config.js file, unlike the "Build-time imports" section you linked to.
I'm trying to include a component. In the comments of the "bootstrap file"
@import
is used. This is not a funcionality provided by tailwind or is it?I expect that I have to add
postcss-import
to my workflow. Am I wrong or are the docs wrong here?If i import a file like dokumented i get an error.
And here the error:
What am I doing wrong?