Hi guys ! 🤗
Next article about React JS! Last week we talked about How to build a complete Modal Component with React Hooks.
This week, let's discover a little trick that will allow you to scope your css/scss/sass in your React JS application.
In order to solve the problem of css encapsulation, there are two main approaches, css-modules and CSS-in-JS.
However, both of them have a very very big problem. The developer experience is not good, by which I mean you often have to write more code than you expect to achieve a simple style.
With react-scoped-css
created by @gaoxiaoliangz, you can just write the normal css you know, while having the advantage of css encapsulation!
React Scoped CSS
How does it work ?
Usually, you import your global style file in your React application, or you use a css file by component if like me you like to be rigorous. But the problem with this second approach is that your style is not scoped.
The scoped CSS allows you to targets a specific element and its children without any impact on other component.
Installation:
With create-react-app
Since create-react-app doesn't allow you to change webpack and babel config. So in this scenario, you have to use craco to override webpack config. Luckily you don't have to do it manually, just use a simple craco plugin.
Setup craco following this guide
# npm i craco-plugin-scoped-css --dev
Then, create a craco.config.js
in your project root and add this code:
module.exports = {
plugins: [
{
plugin: require('craco-plugin-scoped-css')
}
]
}
Without create-react-app
You have to add one babel plugin and one webpack loader.
# npm i babel-plugin-react-scoped-css --dev
And in your babel config:
plugins: ["babel-plugin-react-scoped-css"]
Usage:
Just create your component and import your stylesheet. The css filename must be like [name].scoped.css
(or .scss/.sass). But you can define your own matching rule (.scoped.css
, .local.scss
, ...) in the plugin configuration.
Your css (or scss/sass):
Result
As you can see in the html above, component with scoped css file imported has a unique data-v-<hash>
attribute.
The css selector also has a corresponding hash like selector[data-v-<hash>]
. So all the styles in home.scoped.css
are scoped to Home.jsx
.
Architecture
One common way to structure projects is to locate CSS, JS, and tests together inside folders grouped by feature or route. So here, let's group our JS and scoped css in a folder for one component!
Voilaaa
You can find the Github Repo here: https://github.com/gaoxiaoliangz/react-scoped-css
Today, I use it on most of my projects and I encourage you to try it!
Cheers 🍻 🍻 🍻
Top comments (9)
This is very useful thanks for sharing, you have no idea how I struggled just to find something that works in the same way that you have explained it.
Still, i don`t understand why it's not so simple to scope styles in react.
I guess this is no longer needed with the use of
module.css
. No extra modules / packages are needed, and can simply name your css with the name of component, i.edevTo.module.css and import it, and its already scoped.
Hi, I am new to learning react. I read about CSS modules, but they seem to work only with classes. In every example I saw we create classes in the
someCss.module.css
file, then import it and use the classes through theclassName
attribute in the component's JSX. What if I want to write a css rule with anelement selector
but want that css rule to be applied only to the component in which the stylesheet is imported. With the package shown in the above article this seems easy. But can we achieve the same with css modules?If I'm importing style sheets from something like React bootstrap
"
import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css';
import 'bootstrap/dist/css/bootstrap.min.css';
"
How would I scope those?
Am wondering if i can nest scss, which is sthg like below:
.abc {
.efg {
background-color: white;
}
}
Not possible with CSS, but works with SCSS
Please, Where can I find the data-v- same as in your images?
He probably read the final html and css served to the browser. (e.g. the Elements and Styles tabs in chrome Dev Tools)
Still, I have one problem there are 3 elements in the CSS (body, h2, h4) but it doesn't scope to the specific component, I wonder why?!