Nextjs does not load tailwind css classes without re-building everytime - css

I am using tailwind css in my nextjs project, and have achieved quite so far, though i am facing an issue which is that when i change the tailwind inbuilt className from "bg-fuchsia-600" to "bg-fuchsia-100", the css class doesnt gets applied, but when i run the script
"build-css": "tailwindcss build src/styles/global.css -o public/styles.css"
then the css gets applied, so everytime i change the tailwind inbuilt css class , i have to run this script which shouldnt be the case.
Below is the setup for this
global.css
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
button.css - My custom css file
.button{
color: orange
}
the script extracts file in public folder by the name styles.css
and there i created the main.css file with the following content
#import './styles.css';
#import '../src/styles/button.css';
and then i am using it in the main _app.tsx file
import '../public/main.css'
Now when i render my component
const Login: React.FC<IProps> = (props) => {
const formik: FormikProps<FormValues> = useFormik<FormValues>({
initialValues: {
email: "",
password: "",
},
validationSchema: null,
onSubmit: (values) => {
console.log(values);
},
});
return (
<>
<p className="bg-fuchsia-100 button">hello</p>
<Navbar />
</>
);
};
export default Login;
for the P tag, the className "button" which is my custom css, the change is reflected in the browser ,but for the tailwind inbuilt classname bg-fuchsia-100 i had to run the script again to make it working if i change it to bh-fuchsia-500 or anything
tailwind.config.js
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
colors: {
primary: "#fff",
},
},
},
plugins: [],
};

Related

Purge-css seems to remove every bootstrap css in production mode

I am using Purgecss to remove unused Css on my next application. Other third party libraries am using are Bootstrap, react-bootstrap and bootstrap-icons. I followed the instructions from
https://purgecss.com/guides/next.html but it does not work in production mode.
Below are links to screenshots for both dev mode and production mode.
dev mode
and
production mode
postcss.config.js
module.exports = {
"plugins": [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
"autoprefixer": {
"flexbox": "no-2009"
},
"stage": 3,
"features": {
"custom-properties": false
}
}
],
[
'#fullhuman/postcss-purgecss',
{
content: [
'./pages/**/*.{js,jsx,ts,tsx}',
'./components/**/*.{js,jsx,ts,tsx}',
'./node_modules/bootstrap/dist/**/*.css"'
],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: ["html", "body"]
}
],
]
}
next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig
_app.js
import 'bootstrap/dist/css/bootstrap.css'
import "bootstrap-icons/font/bootstrap-icons.css";
import '../styles/globals.css'
import Head from "next/head";
function MyApp({Component, pageProps}) {
return (
<>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</Head>
<Component {...pageProps} />
</>
);
}
export default MyApp;
why is it behaving that way?
Modify your next.config.js by following
purgeCssPaths: [
'node_modules/react-bootstrap/**/*.js'
],
// also you can try to make white lists
purgeCss: {
whitelist: () => [
'modal',
'modal-dialog',
'modal-xl',
...
],
whitelistPatterns: () => [/modal*/, /accordion*/, /card*/],
whitelistPatternsChildren: () => [/modal*/, /accordion*/, /card*/]
}
If some classes are removed anyway, try following:
This is not entirely correct, but you can make a separate fake component with all the necessary classes that the PurgeCSS removes (modal window, carousel, and so on). You can see the missing classes in the Bootstrap documentation
You can tell PurgeCss to look at Bootstrap js files for needed classes
As an example, my vite.config.js looks like this:
purgecss({
content: ['resources/**/*.php',
'resources/**/*.js',
'resources/**/*.vue',
'node_modules/bootstrap/js/**/*.js']
}),
As you can see I added all Bootstrap js source files to look for needed classes.

SvelteKit Unused CSS selector warning in VS Code

How can I remove VS Code Unused CSS selector warning? This warning is in all files where i use <style lang="scss">. I know that I don't use .btn class in some components, but I want this class as global css.
my svelte.config.js:
const config = {
onwarn: (warning, handler) => {
const { code, frame } = warning;
if (code === "css-unused-selector")
return;
handler(warning);
},
preprocess: [
preprocess({
defaults: {
style: 'scss'
},
postcss: true,
scss: {
prependData: `#import 'src/scss/global.scss';`
}
})
],
};
Please can someone help me?
If you use prependData that means you add the import to every component where you use styles. This is not what you want, therefore remove this setting. What you want is to import this file once so it's available globally. This can be done by just importing it inside the script tag, SvelteKit (or rather: Vite) can handle style imports.
Inside your root __layout.svelte file, add
<script>
import 'path/to/your/global.scss';
</script>

Use tailwind #apply in CSS modules in Next.js

I've setup tailwind with my Next.js site as per the official guide here: https://github.com/tailwindcss/setup-examples/tree/master/examples/nextjs
However, when I try and use the #apply method, in a CSS module on a component level, eg:
.container {
#apply rows-span-3;
}
I get the following error:
Syntax error: #apply cannot be used with .rows-span-3 because .rows-span-3 either cannot be found, or its actual definition includes a pseudo-selector like :hover, :active, etc. If you're sure that .rows-span-3 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.
This is my postcss.config.js:
const purgecss = [
'#fullhuman/postcss-purgecss',
{
content: ['./components/**/*.jsx', './pages/**/*.jsx'],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
},
]
module.exports = {
plugins: [
'postcss-flexbugs-fixes',
'postcss-import',
'postcss-mixins',
'postcss-calc',
'postcss-extend',
['postcss-color-mod-function', {
importFrom: [
'./assets/styles/vars.css',
],
}],
['postcss-preset-env', {
stage: 1,
preserve: false,
importFrom: [
'./assets/styles/vars.css',
],
}],
'tailwindcss',
'autoprefixer',
...(process.env.NODE_ENV === 'production' ? [purgecss] : []),
'postcss-nested',
],
}
I manage to make it work using this example
link to tailwind doc
From the doc:
You have this module css
/*Button.module.css*/
.error {
#apply bg-red-800 text-white;
}
Component file
//Button.js
import styles from './Button.module.css'
export function Button() {
return (
<button
type="button"
// Note how the "error" class is accessed as a property on the imported
// `styles` object.
className={styles.error}
>
Destroy
</button>
)
}
From the example, please notice the use of className={styles.error} instead of className="error"

On using customize-cra to override antd less variable creates multiple duplicate css files on build

I am using customize-cra to override antd less variable but it creates multiple duplicate CSS files on build.
As mentioned in antd docs https://ant.design/docs/react/use-with-create-react-app#Advanced-Guides
if I use default import of CSS like this
#import '~antd/dist/antd.css';
it produces only 1.5MB(Including my custom CSS) of CSS files after the build.
Then I remove #import '~antd/dist/antd.css';
And i used customize-cra , like this code.
const { override, fixBabelImports, addLessLoader } = require('customize-cra');
const overrideVariables = require('./src/styles/overrideVariables');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
}),
addLessLoader({
javascriptEnabled: true,
modifyVars: overrideVariables,
}),
);
This produces 6MB(Including my custom CSS) for CSS files after the build.
Am I am using it wrong or any other solution for this?
I'd recommend using craco. There is craco-antd plugin that works great and does exactly what you need.
craco.config.js
module.exports = {
plugins: [
{
plugin: require('craco-antd'),
options: {
lessLoaderOptions: {
noIeCompat: true
}
}
}
]
};
And then you can add your variables in antd.customize.less
#primary-color: #1da57a;
#link-color: #1da57a;

How to render activeClassName style for a react-router-dom NavLink rendered within a material-ui button in a typescript environment?

I am learning react and trying to set the style of a react-router-dom NavLink encapsulated inside a material-ui Button. I am using React with Typescript and a custom Webpack build.
The documentation states that this can be achieved by setting the activeClassName property.
In the code listing below I try setting the activeClassName on the button containing the NavLink component.
import * as navbar from './NavBar.css';
const NavBarLinks = () => (
<>
<Button
color="inherit"
component={NavLink}
activeClassName={navbar.highlighted}
to="/about"
>
About
</Button>
</>
);
The highlighted css class is as follows:
.highlighted {
border-bottom: 3px solid rgb(174, 185, 28);
}
However, no bottom border is rendered. How do I get the activeClassName style to render for a react-router-dom NavLink rendered within a material-ui Button within a Typescript environment?
My build environment is configured as follows.
I have created a type declaration file for the stylesheet
and saved this in a folder referenced in tsconfig.json.
export const active: string;
export const horizmenu: string;
export const highlighted: string;
My tsconfig.json includes the typesRoot configuration. This references the types folder where my css type declaration file is stored:
"typeRoots": ["node_modules/#types", "src/types"]
My webpack development configuration is using css-loader to bundle css files under src/app/*/
{
// link css modules
test: /\.css$/,
include: path.resolve(constants.dir.SRC, 'app'),
use: [
{ loader: require.resolve('style-loader') },
{
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: '[path][name]__[local]___[hash:base64:5]',
},
importLoaders: 1,
sourceMap: true,
},
},
],
},
...
When I perform a Webpack development build I can see that the NavBar.css contents are picked up by the css-loader and embedded as a string in the bundle file.
What you have should work, but you are passing a class name, not a style, so I think you just need to make your activeClassName prop equal to "highlighted".
<Button
color="inherit"
component={NavLink}
activeClassName="highlighted"
to="/about"
>
About
</Button>
You'll also need to add !important to you style so it overrides the CSS of the Material UI button.
Working codesandbox link

Resources