Using NextJS, how can you import in CSS using tailwind css? - tailwind-css

Just started using tailwindcss in a Next.js project.
I set it up through my CSS file, and was trying to setup some basics for headers h1, h2, ... but I like separating the logic a bit so it doesn't get too messy, so I tried to `#import './typography.css' which includes some tailwind, but it doesn't work.
Here is my base CSS file:
#tailwind base;
#tailwind components;
#tailwind utilities;
#tailwind variants;
#import './typography.css';
My typography:
h1 {
#apply text-6xl font-normal leading-normal mt-0 mb-2;
}
...
Any ideas on how I can get this to work?
Update
I've tried:
Added #layer base in my typography.css file, but receive an error: Syntax error: /typography.css "#layer base" is used but no matching #tailwind base
Also tried do it at the import layer, eg #layer base { #import("typography.css") }, that doesn't create an error but the styles aren't applied.

You need set the target layer for this to work.
Since you want to change the base html elements in your typography.css file do:
#layer base {
h1 {
#apply text-6xl font-normal leading-normal mt-0 mb-2;
}
}
More details in the documentation here: https://tailwindcss.com/docs/adding-base-styles

Based on the docs from tailwind, here is a TLDR;
Install
npm install -D postcss-import
Update your postcss.config.js
// /postcss.config.js
module.exports = {
plugins: {
"postcss-import": {}, // <= Add this
tailwindcss: {},
autoprefixer: {}
}
}
Then in your main css file where you have the imports, you need to:
rename the tailwindcss imports to from #import base; to #import "tailwindcss/base"; (same for the components and utilities
Then you need to import in the proper order. If the file is a base put it after the base import, it's a components, put it after the components
#import "tailwindcss/base"; // <= used to be `#tailwind base;`
#import "./custom-base-styles.css";
#import "tailwindcss/components"; // <= used to be `#tailwind components;`
#import "./custom-components.css";
#import "tailwindcss/utilities"; // <= used to be `#tailwind utilities;`
#import "./custom-utilities.css";
Then in your custom-base-styles.css you can:
#layer base {
h1 {
#apply text-3xl text-slate-800;
}
}

According to the docs the issue is a matter of the order of the statements. They recommend to put the #tailwind base; statement in a seperate file and import it like this:
#import "./tailwind-base-statement.css";
#import "./typography.css";

You must use postcss-import
https://tailwindcss.com/docs/adding-custom-styles#using-multiple-css-files
https://tailwindcss.com/docs/using-with-preprocessors#build-time-imports
if you use Laravel webpack mix, add it in .postCss(....)
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'), // <------------ add postcss-import here
require('tailwindcss'),
])

used poscss and postcss-import-plugin import plugin
npm install -D postcss-import
update postcss.config.js file
module.exports = {
plugins: {
'postcss-import': {},
tailwindcss: {},
}
}
add #tailwind base; inside top of your typography.css
for more deatils you can check this link:
https://tailwindcss.com/docs/using-with-preprocessors#build-time-imports

I found something that seems to work for me.
Basically postcss-import has its own layer system that we can use instead of tailwinds layer system.
#import 'tailwindcss/base' layer(Base);
#import './base/typography.css' layer(Base);
#import 'tailwindcss/components' layer(Components);
#import 'tailwindcss/utilities' layer(Utilities);
#layer Base {
#root {
#apply some-styles;
}
}
In postcss-import#usage it describes using layer() with #import
...
#import 'baz.css' layer(baz-layer);
...
I used uppercase layer names to avoid conflicting with tailwinds layers.
Install postcss-import as described in tailwinds article.
using-with-preprocessors#build-time-imports
Then add layer() to your imports like #import 'tailwindcss/base' layer(Base).
Also rename your #layers calls to something different than tailwinds layers.
For examples you can look any of the test fixtures with layer in the filename.
postcss-import/test/fixtures
UPDATE
The root cause of this for me was using Create React App.
Because it doesn't allow you to configure postcss.config.js.
So another solution would be to migrate to something else instead.
darekkay/create-react-app-to-vite#migration
tailwindcss.com/issues/1472
tailwindcss/guides/create-react-app
we highly recommend using Vite, Next.js, Remix, or Parcel instead of Create React App

Related

Laravel Vite #apply tailwind custom styles are not compiled

I'm using Laravel Vite and have this in my app.css
#tailwind base;
#tailwind components;
#tailwind utilities;
#import 'animate/base.css';
#import 'animate/animations.css';
#layer components {
.ql-container {
#apply border-2 border-slate-300;
}
}
And postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},
}
The ql-container custom Tailwind styles are not getting compiled and I'm not sure why. This is how it's defined in the Tailwind docs.
If the class ql-container is added inside an #layer directive and its use is not detected by Tailwind in any of your templates, then it will not be included in the css output.
If it is not wrapped in a directive then it will always be added to the css output, so just don't wrap the style with #layer components { ... }.

tailwind: how to use #apply for custom class in nuxt2?

I am trying to use #apply on my custom class in Nuxt.js 2
nuxt.config.js
export default {
buildModules: [
'#nuxtjs/tailwindcss',
],
tailwindcss: {
cssPath: '~/assets/app.css',
exposeConfig: true
}
}
assets/app.css
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer utilities {
.btn {
#apply border-2 p-2 font-bold;
}
}
in any vue-single-file or any other scss file
<style lang="scss">
.btn-lg {
#apply btn;
}
</style>
The btn class does not exist. If you're sure that btn exists, make sure that any #import statements are being properly processed before Tailwind CSS sees your CSS, as #apply can only be used for classes in the same CSS tree
So, how to make my custom styles be seen by the Tailwind CSS before processing to make my custom classes work in #apply?
I've tried the solutions in the following questions and document
adding-custom-utilities
not able to use custom classes in #apply in scss file tailwind nextjs project?
But none of them work
I am using:
Tailwindcss 2.2.19 via #nuxtjs/tailwindcss
Nuxt.js 2.15.8
Thanks a lot for any replies!
As I mentioned in the comments, add a mode: "jit" can solve this problem.
tailwind.config.js
module.exports = {
mode: 'jit'
}
It's a good vanilla solution.
However, if you are programming the project in a virtual machine(Homestead) just like me, this could cause a error that the node can't recoginze the changings of your css/scss/sass files.
so there's another two solutions:
use pure tailwindcss instead of #nuxtjs/tailwindcss
just follow the document: Install Tailwind CSS with Nuxt.js
use plugin() in your tailwind.config.css
const plugin = require('tailwindcss/plugin')
const fs = require('fs')
module.exports = {
// ... purge, theme, variants, ...
plugins: [
plugin(function({ addUtilities, postcss }) {
const css = fs.readFileSync('./your-custom-style-file-path', 'utf-8')
addUtilities(postcss.parse(css).nodes)
}),
],
}
from github
But what's more, this solution can't recoginze the changings too. So add your css/scss/sass files in nuxt.config.js (I'm using nuxt-vite)
vite: {
plugins: [
{
name: 'watch-external', // https://stackoverflow.com/questions/63373804/rollup-watch-include-directory/63548394#63548394
async buildStart(){
const files = await fg(['assets/**/*']);
for(let file of files){
this.addWatchFile(file);
}
}
}
]
}

Use Sass in Saber

Goal
I'd rather enjoy using Sass in the Saber framework, which it supports. Here are the docs for it if you wish. Simple, right?
Problem
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser
My code is extremely vanilla at this stage.
Context
I did this:
yarn add sass-loader sass --dev
And initially did that:
// saber-config.js
module.exports = {
build: {
loaderOptions: {
sass: {
data: `#import "#/scss/main.scss";`
}
}
}
}
...which resulted in no styles. M'kay. So I removed that part and imported the styles directly into the layout component, like so—
<!-- layouts/page.vue -->
<style lang="scss">
#import url('../scss/main.scss');
</style>
That's the point at which the aforementioned error occurs. What's also interesting is that if I move the Sass code from main.scss to the page.vue <style> tags, it works.
Turns out is was a Sass version issue. I resolved it by bumping down a version.
"devDependencies": {
"saber": "^0.11.7",
"saber-plugin-feed": "^0.4.3",
"saber-plugin-query-posts": "^0.4.6",
"sass": "^1.22.12",
"sass-loader": "^8.0.0"
}

Best way to have global css in Vuejs

What is the best way to have a global css file in Vuejs for all components? (Default css like bg color, button styling, etc)
import a css file in the index.html
do #import in main component
put all the css in the main component (but that would be a huge file)
Import css in your index.html, but if you're using webpack you can just import your stylesheets in your main js config and all your components will get the css.
As comments below suggested if using webpack adding this to main.js works:
import './assets/css/main.css';
I found the best way is to create a new file in the assets folder, I created as global.css but you can name anything of your choice. Then, import this file global.css file in the main.js.
Note: Using this approach you can also create multiple files if you think the global.css is getting really large then simply import all those files in the main.js.
#\assets\global.css
/* move the buttons to the right */
.buttons-align-right {
justify-content: flex-end;
}
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './routes'
Vue.config.productionTip = false
// Importing the global css file
import "#/assets/global.css"
new Vue({
router,
render: h => h(App)
}).$mount('#app')
In App.vue you can add a style property to declare you CSS file:
<style>
#import './assets/css/global.css';
</style>
You can also do something like this: https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/
My folders are mostly structured like this:
- src
- assets
- _global.scss
- _colors.scss
- _fonts.scss
- _paragraphs
- index.scss // <-- import all other scss files.
This also works with normal css.
create a new css file in your assets folder for example : global.css
import "global.css" to main.js
import '#/assets/main.css';
There are to two ways, as I know, to achieve this.
Approach 1
Utilize vue.config.js configuration, less config can also be replaced with sass:
module.exports = {
css: {
loaderOptions: {
less: {
additionalData: `#import '#/style/common.less';`
}
}
}
}
Approach 2
In your .vue file, make your style looks like this:
<style lang="less">
#import (reference) "../../style/variables.less";
#app {
background: #bgColor;
}
</style>
Note: the (reference) flag is used to make variables defined in variables.less take effect. If you don't have variables, #import "../../style/variables.less"; is sufficient to do the trick.
For your reference, you can also take a look at this link:
https://github.com/tjcchen/vue-practice/tree/master/multipage-app
Sass announced their new module system. Why don't you use #use and #forward?
My approach is the best way to use scss with vite.
Use defineConfig to setup global scss (colors, mixin) and reuse in all component without import
css: {
preprocessorOptions: {
scss: {
additionalData: `#use "~/styles/main.scss" as *;`,
},
},
},
Here: code sandbox
create a vue.config.js file in your root directory
Create a styles folder inside your src folder and you can create your global style file here for example base.scss
to use scss install two dependencies
npm install node-loader sass-loader
Inside your vue.config.js paste code from below
module.exports = {
css: {
loaderOptions: {
sass: {
additionalData: `#import "#/styles/base.scss";`
}
}
}
};

How are `postcss-import` configured plugins applied

I've just started using PostCSS exclusively with Webpack. When using postcss-import to inline external stylesheets, I see it's options allow us to configure plugins and transformers to be applied on imported sources, but I'm a bit confused on how this fits in together with other options configured for the main PostCSS runner.
For instance, if I want to inline URLs, should I be adding the postcss-url plugin to postcss-import, the PostCSS runner or both (if my main stylesheet also has URL references)?
It's recommended to make postcss-import the first plugin in your list when you're defining the plugins for postcss in webpack. Since postcss-import just inlines the #import to the start of the file, any postcss plugin defined afterwards will be applied to it.
Example:
(For the example i'm gonna assume you use a postcss.config.js file, the same logic applies if you use an array for the plugins in the webpack 1 format)
// Header.css
#import 'button.css';
.foo {
font-size: 3rem;
transform:translateY(-10px);
}
// Button.css
.bar {
transform:translateX(20px);
}
If the import plugin is behind autoprefixer, it will first apply the autoprefixer plugin on the file and then afterwards import the #import file. So by the time the file is imported the prefixing will have already happened, the output will be:
// postcss.config.js
module.exports = {
plugins: {
'autoprefixer': {},
'postcss-import': {}
},
};
// output.css
.bar {
transform: translateX(20px); // Prefixing hasn't happened on the imported file
}
.foo {
font-size: 3rem;
transform:translateY(-10px);
-webkit-transform:translateY(-10px); // original file has been prefixed though
}
If you put the import first though, it will inline the imported file and then do the autoprefixing, this means both the imported and the original file will be autoprefixed:
// postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
'autoprefixer': {}
},
};
// output.css
.bar {
transform: translateX(20px);
-webkit-transform:translateX(20px); // Also prefixed now
}
.foo {
font-size: 3rem;
transform:translateY(-10px);
-webkit-transform:translateY(-10px);
}
So this means you don't actually have to add plugins again in the option of the postcss-import plugin.

Resources