How to scope Tailwind Css - tailwind-css

I cannot find a good way to scope tailwind CSS when including it in a system where I don't want it to apply globally that works with custom build options.
Essentially I want to do this:
.tailwind{
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
}
But PostCSS importer doesn't like this due to the fact it imports before the tailwind placeholders are replaced. So the only way to make it work is to break the build into 2 stages then import the compiled css like:
.tailwind{
#import "tailwindcss.css";
}
It works but it breaks some of the css rules which show up in dev tools.
Is there a better way to scope tailwind to stop it interfering with other systems?

I've found that you can use postcss-nested for this. Install the plugin, add it as the first plugin to your PostCSS config file and this should work:
.tailwind {
#tailwind base;
#tailwind components;
#tailwind utilities;
#tailwind screens;
}

From the docs...
The prefix option allows you to add a custom prefix to all of Tailwind's generated utility classes. This can be really useful when layering Tailwind on top of existing CSS where there might be naming conflicts.
For example, you could add a tw- prefix by setting the prefix option like so:
// tailwind.config.js
module.exports = {
prefix: 'tw-',
}

You will achieve this by setting important in the tailwind config to your parent class or id. See docs.
// tailwind.config.js
module.exports = {
important: '.tailwind',
}
Unfortunately, this seems to only be affecting the components and utilities styles... the base styles will remain unaffected.

As requested leaving my answer here:
I used the prefix as suggested by Lanny
// tailwind.config.js
module.exports = {
prefix: 'tw-',
}
And then made my tailwind css file like this:
#import "tailwindcss/components";
#import "tailwindcss/utilities";
Then I just manually copied any base styles that I wanted manually into my main css file and manually changed anything that conflicted.

I think the tricky part here is actually about the preflight/reset.css. You want to fend off external styling from coming to your scope but also don't want to pollute the external system with your tailwind style.
My current set up include following steps:
In tailwind.config.js we disable the prefight, defining a prefix tw-, and adding an extra selector #app via option important. The last change will add an extra css selector to output, e.g. #app .tw-mb-4.
module.exports = {
important: '#app',
prefix: "tw-",
corePlugins: {
preflight: false,
},
Find and copy the content of base.css from node_modules folder before pasting it into a scss file with a parent selector #app. You can compile this using any online SCSS compiler. This will help you only reset styling within your scope.
#app {
/*content from base.css*/
}
Copy compiled the styling from #2 and paste to the beginning of your tailwind css file.
Structure the html so you contents are wrapped within a div with the id of #app.
Tailwind's important option doesn't seem to add selector to #layer component so you will have to include that in your component styling.
#layer components {
#app .page-h1 {
#apply tw-mt-0 tw-mb-2 tw-text-center tw-leading-8 tw-text-4xl md:tw-text-5xl;
}
}

According to the docs:
If you’d like to completely disable Preflight — perhaps because you’re integrating Tailwind into an existing project or because you’d like to provide your own base styles — all you need to do is set preflight to false in the corePlugins section of your tailwind.config.js file.
This seems to work with Wordpress in the admin but it does remove the normalization, like cursor: pointer on button hover, for example.

What I have done is this
module.exports = {
prefix: 'tw-',
content: [
"./src/**/*.{html,ts}",
],
theme: {
extend: {},
},
purge: {
enabled: true,
content: ['./src/**/*.{html,ts}']
},
plugins: [],
corePlugins: {
preflight: false,
}
}
It will reduce build size as ,I have purged CSS, disable global CSS,as I have used preflight, and now If u want to apply tailwind class use as
<div class="tw-m-4"></div>
As we have used tw in prefix

Related

Tailwind CSS breaking existing styles

When I added Tailwind to my React project, it breaks existing styles.
I was hoping to just use Tailwind classes (like mb-3) for shortcuts.
I didn't expect it to overwrite existing styles, like changing button background to transparent.
Am I doing it wrong? Or does Tailwind overwrite styles on purpose?
EDIT:
This is what I'm talking about: (which comes from node_modules\tailwindcss\src\css\preflight.css)
The issue goes away when I exclude base, i.e:
//#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
EDIT 2:
Found the solution!
module.exports = {
corePlugins: {
preflight: false,
}
}
When you use both bootstrap and tailwind-css at the same time, you will face naming conflicts which will lead to undefined behavior ,
To avoid this, use the prefix option in your tailwind.config.js file
// tailwind.config.js
module.exports = {
prefix: 'tw-',
}
So now you can use the prefix tw- before the class name of tailwind-css which wont break any of your existing styles.
Note if you want tailwind classes to get more precedence than any other css styles , you can set the important option to true on tailwind.config.js
module.exports = {
important: true,
}
To understand the css precedence follow this What is the order of precedence for CSS?
Extended answer:
Thanks to Aximili ,
Tailwind-Css implements Preflight by default in their projects which is an opinionated set of base styles.
And this is build on top of modern-normalize
And Tailwind automatically injects these styles in #tailwind base.
So to overcome this .Remove #tailwind base from the css file or Add preflight: false,
module.exports = {
corePlugins: {
preflight: false,
}
}
Hope it helps!
Add the following line to your tailwind.config.js
module.exports = {
prefix: 'tw-',
}
An now you can use both bootstrap and tailwind but you will have to use tw- before tailwind classes such as tw-mb-2, tw-text-right etc.
while you still can use bootstrap normally. The classes won't conflict anymore.
I will not recommend using important in tailwind.config.css because you still might want to use the bootstrap at some location so the prefix is the best bet here.

Controlling the specificity of CSS Modules in a Next.js App

I'm trying to figure out a good workflow of how to use Tailwind together with CSS Modules in Next.js, but I'm running into some tricky problems regarding specificity and the order in which styles are inserted by Webpack.
Consider the following use case: I want to create a reusable Button component whose styles can be overridden with utility classes. Option 1 is to extract the component, as mentioned in the Tailwind Docs:
/* button.jsx */
export const Button = props => <button {...props} className={`btn {props.className}`} />
and in my tailwind.css file I'd add the classname in the #layer directive:
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer components {
.btn { #apply ... }
}
This is nice because I can override any of the buttons styles with utility classes, since they have higher specificity. However, I see a few minor problems here:
the class is now global, so it's included in every page even if I don't use the component
the style and component are no longer colocated - this might get messy if I create many such classes
Option 2 would be to use a CSS Module and apply the classes like this:
/* button.module.css */
.btn { #apply ...}
/* button.jsx */
import styles from "./button.module.css";
export const Button = props => <button {...props} className={`${styles.btn} {props.className}`} />
This way the CSS only gets loaded when the component is used, and the styles are colocated. Problem here is that in Next.js CSS Modules are inserted after global CSS, so they have higher specificity. Which totally makes sense, usually I'd want my CSS Modules to be able to override global styles. However, in this case I'd like them to be inserted before my global styles so that I can override them with utility classes.
I assume this should be possible by adjusting the Webpack config? Does anyone proficient with Webpack know how to achieve this?
I actually found a nice solution in tailwind v3.0, which is using the new important option. In your tailwind.config.js you can now add this line:
module.exports = {
// ...
important: '#__next'
}
This way, all your utilities are getting prefixed with #__next (the root element in Next.js), which increases their specificity above that of CSS Modules.
Go for the second option and simply add ! to the property to make that important.
/* button.module.css */
.btn { #apply !mb-0 }

Tailwind CSS custom font not appearing in compiled CSS

I'm following the Tailwind CSS documentation, but after I rebuild the CSS file, the font class does not appear in the generated file for some reason. So, I went to Google Fonts and copied the import and pasted it into a CSS file I want to compile, and it looks like this:
styles.css
#tailwind base;
#tailwind components;
#import url('https://fonts.googleapis.com/css2?family=DotGothic16&family=Lato:wght#300;400;700;900&family=Roboto:wght#400;500;700&family=Rubik:wght#400;500;700&display=swap');
#tailwind utilities;
Then I went to the Tailwind config file and added fontFamily.
tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
},
fontFamily: {
'body': ['Lato'],
}
},
variants: {
extend: {},
},
plugins: [],
}
At last, I used this command to recompile
npx tailwindcss build styles.css -o output.css
If I try to apply the class "font-body," it doesn't work, and that makes sense since the class is not in output.css
Few mistakes that I see in your code are:
The import statement should always be on the top of the file
Your configuration should be like this
fontFamily:{
'Lato':{'Lato', 'sans-serif'}
}
You should use the css rules to specify as mentioned in google fonts.
Your import statement has 3 fonts. If you are only using Lato, remove the others and configure them properly for your own better understanding.
We should generally rebuild our css file, if you have done major changes. Rebuilding is not necessary in v.2. Using :
npm build YOUR_FILE.css
and restarting dev server should work. No need of creating another output file.

How to solve "ant design base css" and "tailwindcss base css" alignments problem? How to avoid antd modifying global styles?

I prefer create project style and components style with tailwind css framework. I want to use a few ant design component. Tailwindcss and ant.design have problems together. Ant design alignment loses when we import #import 'tailwindcss/base' to the project and when we delete it ant design alignment will work fine. ant design modify global styles and according of document I try to prevent this but not work this method for me!
My babel.config.js:
['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
I add this plugin to my webpack config:
new webpack.NormalModuleReplacementPlugin(
/node_modules\/antd\/lib\/style\/index\.less/,
path.resolve(__dirname, './src/antd.less'),
),
and antd.less file:
#antd {
#import '~antd/es/style/core/index.less';
#import '~antd/es/style/themes/default.less';
}
I would recommend overriding some of Tailwind's base styles that are causing problems with Ant Design. For me, Ant Design icons did not have the correct vertical alignment when including Tailwind, so I replaced their default svg style in my global css file.
#tailwind base;
/* Override base SVG style to work with Ant Design */
svg {
vertical-align: initial;
}
TailwindCSS applies certain base styles to smoothen the cross-browser experience.
Since you are also using Ant Design, which applies some base styles of its own, setting preflight to false in your tailwind config should work:
module.exports = {
corePlugins: {
preflight: false,
}
}

Can't access global SASS variables from my component

In my Nuxt app I load all my SASS thus:
css: [
'~assets/scss/main.scss'
],
It works perfectly, except when I'm trying to use some SASS variable from within a component.
<style lang="scss">
.container {
background-color: $white;
}
</style>
In this case I get this error message:
SassError: Undefinied variable: $white
Yet, all of the SCSS contained in the SASS file where the variable is defined works throughout the app.
It is as if the app as a whole knew these files, but each individual component doesn't.
What's going on?
Most of the other answers don't take into account that Nuxt.js hides all the Webpack setup and forces you to do everything through nuxt.config.js.
My guess is that Webpack isn't compiling all the SCSS declarations together and therefore can't find the variable.
It's been a few months since I had this issue so things may have changed but here goes...
Make sure you have the correct Node packages installed (Nuxt DID NOT do this by default for me) npm i -D node-sass sass-loader
Add your CSS & SCSS files to the css: [] section of nuxt.config.js Order matters here so make sure things like variables are added before things that use them if you have separate files.
If you're using layouts (I think that's the default Nuxt setup) make sure that layouts/default.vue has a <style lang="sass"></style> block in it. If I remember correctly this can be empty but had to exist. I only have one layout but it may need to exist in all of them.
If all that seems like too much of a pain, there's a Nuxt Plugin that takes most of the work/management out of that process. Nuxt Style Resources Module
The confusing part is that:
styles from scss files CAN be loaded like this
//nuxt.config.js
css: [
'~assets/scss/main.scss'
],
//global scss file
$varcolor: black
h1{background: $varcolor}
BUT
the variables inside CAN NOT be used inside a component
//inside component
.component {background: $varcolor} // DOES NOT WORK
I also suggest the use of the nuxt style resource module:
https://github.com/nuxt-community/style-resources-module
new founded solution, checked and it's work. Founded here
add #nuxtjs/style-resources
export default {
css: [
'vendor.min.css'
],
modules: [
'#nuxtjs/style-resources'
],
//You will have to add this new object if it doesn't exist already
styleResources: {
scss: ['./assets/scss/main.scss'] // here I use only main scss with globally styles (variables, base etc)
},
}
it's strange, but if u change tilda (~) to dot(.), it's help for someone
from css: [ '~assets/scss/main.scss' ] to css: [ './assets/scss/main.scss' ]
this solution finded here
Us should either load the scss in your component
<style lang="sass">
#import 'path/to/your/_variable.scss'; // Using this should get you the variables
.my-color {
color: $primary-color;
}
Or adding the following to you to your vue.config.js
module.exports = {
css: {
loaderOptions: {
sass: {
data: `#import "#/pathto/variables.scss";`
}
}
}
};
Ref:
SassError: Undefinied variable: $white
Each <style lang="scss"> is compiled individually. You need to #import the file which defines $white into your component before the parser knows what $white means.
This is why most frameworks keep their variables in a _variables.scss file which is imported in all the other SCSS files/contexts.
The _variables.scss is not even loaded in the page, because in most cases it doesn't actually contain any rules. It only contains variable definitions which are imported into other .scss files, which output .css.
Ref:
Yet, all of the SCSS contained in the SASS file where the variable is defined works throughout the app.
If you import an SCSS file in your vue.config.js the output will be an ordinary <style> tag. Its contents will be generated at compile/build time and will result into some CSS (which apply to the entire document).
Unless specifically imported into the component SCSS, (using an #import command), the compiler will not know what $white means.
There is an important distinction to make between compilation context and browser context. Compilation happens at compile time (most likely in node-sass). Browser context is the actual browser, which only understands the CSS resulted from compilation.
How does Vue only apply style rules to the parent and not to the children with the same class? That's achieved by scoping.
It means applying a custom data-v-{key} attribute to all selectors in the generated <style> tag and to all elements the style should apply to.
See this example and inspect it using your web console: https://codesandbox.io/s/vue-template-ge2hb
It produces this markup:
As you can see, the scoped CSS has an extra [data-v-763db97b] added to the selector, which means it only applies to elements having that data attribute.

Resources