Reputation: 6363
I'm currently using CSS Modules with React for my styling. So each of my components is importing in it's component specific css file, like so:
import React from 'react';
import styles from './App.css';
const example = () => (
<div className={styles.content}>
Hello World!
</div>
);
export default example;
This works fine when styling individual components, but how do I apply global styling (html, body, header tags, divs, etc.) that isn't component specific?
Upvotes: 134
Views: 221355
Reputation: 59
The best practice I can say there should be a CSS folder where you can keep all the CSS you need all over the application like I need font size is 20 in my all components so need to follow these step:
name _font.scss
.name index.scss
.import _font.scss
inside index.scss
(@import './fonts';
).index.js
starting file (import "../scss/index.scss"
).In this case, you may find duplication. For example - you have container CSS globally which is created one of your files but you want to have a separate container for one of your file
This case make a separate css/scss file for this application name should be like (cssname.module.scss
) must include .module
for better handling.
With this css you can import your jsx file (import Style from './cssname.module.scss'
)
You can use like className= {Style.container}
but if you want to use some of your global and local css together
install Classnames from npm (npm install classNames
)
how to use:
import cn from 'Classnames'
className = {cn(Style.container,"fs-20 text-center")}
here fs-20 and text-center are the global CSS present in some of your files
Upvotes: 5
Reputation: 109
Another simple way if you want to use css module is:
<style jsx global>{`
.slick-prev:before,
.slick-next:before {
color: somecolor;
}
`}</style>
Upvotes: 3
Reputation: 1072
Solution 1 :
Import global styles in starting point of reactapp
.
where the whole react app has been wrapped
in a root component .
it can be index.js
or app.js
or index.html
Solution 2 :
use scss
and create main.scss
file and import all other specifically needed custom scss
files in main.scss
Upvotes: 0
Reputation: 485
I had encountered the same problem and found the following ways to address the issue, you may choose what applies to you best
A sample is given below:
// exclude all global styles for css modules
{
test: /\.(less|css)$/,
exclude: path.resolve(__dirname, './src/styles'),
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]'
}
}
},
"postcss-loader",
"less-loader"
]
},
// process global styles without css modules
{
test: /\.(less|css)$/,
include: path.resolve(__dirname, './src/styles'),
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
"css-loader",
"postcss-loader",
"less-loader"
]
}
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]',
mode: 'global',
}
}
},
If you are defining mode as global then all your included css classes will not be replaced with hashed names, instead only the ones you specify as :local will be given unique names. For example:
/* this will remain as is */
.header {
color: blue;
}
:local {
/* this will become something like item_xSH2sa */
.item {
color: yellow;
}
}
// regex to test for modules, loaderUtils is part of webpack dependencies
const cssModuleRegex = new RegExp(/\.module\.(less|css)$/);
const loaderUtils = require("loader-utils");
// inside webpack rules
{
test: /\.(less|css)$/,
use: [
{
loader: CssExtractPlugin.loader,
options: { hot: is_dev, reloadAll: is_dev }
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: '[local]___[hash:base64:5]',
getLocalIdent: getLocalIdent
}
}
},
"postcss-loader",
"less-loader"
]
}
// this is a copy of the default function, modified slightly to achieve our goal
function getLocalIdent(loaderContext, localIdentName, localName, options) {
// return local name if it's a global css file
if (!cssModuleRegex.test(loaderContext.resourcePath)) {
return localName;
}
if (!options.context) {
// eslint-disable-next-line no-param-reassign
options.context = loaderContext.rootContext;
}
const request = path
.relative(options.context, loaderContext.resourcePath)
.replace(/\\/g, '/');
// eslint-disable-next-line no-param-reassign
options.content = `${options.hashPrefix + request}+${localName}`;
// eslint-disable-next-line no-param-reassign
localIdentName = localIdentName.replace(/\[local\]/gi, localName);
const hash = loaderUtils.interpolateName(
loaderContext,
localIdentName,
options
);
return hash
.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-')
.replace(/^((-?[0-9])|--)/, '_$1');
}
Upvotes: 7
Reputation: 26350
The only way I found for importing styles globally, but only for a specific route is adding:
<style dangerouslySetInnerHTML={{__html: `
body { max-width: 100% }
`}} />
inside the return of render
method.
Otherwise, the style
tag would be added to the <head>
, and the styles would be applied for all next routes.
From https://medium.learnreact.com/the-style-tag-and-react-24d6dd3ca974
Maybe the styles could be imported as a string from a file to have the code more organized.
Upvotes: 7
Reputation: 3396
Since you're using the ES6 import syntax you may use the same syntax to import your stylesheet
import './App.css'
Also, you can wrap your class with :global
to switch to the global scope (this mean CSS Module won't modulify it, eg: adding a random id next to it)
:global(.myclass) {
background-color: red;
}
Upvotes: 222
Reputation: 6363
This can be done by simply adding:
require('./App.css');
(thanks @elmeister who correctly answered this question.)
Upvotes: 12