DEV Community

Cover image for 🦄 How to scope your CSS/SCSS in React JS ⚡️
Victor de la Fouchardière
Victor de la Fouchardière

Posted on • Updated on

🦄 How to scope your CSS/SCSS in React JS ⚡️

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.

React SCSS Scoped

Created with meme-studio.io

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
Enter fullscreen mode Exit fullscreen mode

Then, create a craco.config.js in your project root and add this code:

module.exports = {
  plugins: [
    {
      plugin: require('craco-plugin-scoped-css')
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Without create-react-app

You have to add one babel plugin and one webpack loader.

# npm i babel-plugin-react-scoped-css --dev
Enter fullscreen mode Exit fullscreen mode

And in your babel config:

plugins: ["babel-plugin-react-scoped-css"]
Enter fullscreen mode Exit fullscreen mode

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.

React CSS Scoped JSX

Your css (or scss/sass):

React CSS Scoped CSS

Result

React CSS Scoped HTML

As you can see in the html above, component with scoped css file imported has a unique data-v-<hash> attribute.

React CSS Scoped CSS

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!

Alt Text

Example of one of my projects

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)

Collapse
 
ghalib profile image
Ghaleb Al-Nakhlani

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.

Collapse
 
grantdotdev profile image
Grant Riordan

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.e
devTo.module.css and import it, and its already scoped.

Collapse
 
khanurooj5299 profile image
Urooj Khan

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 the className attribute in the component's JSX. What if I want to write a css rule with an element 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?

Collapse
 
jamesbaker1 profile image
James Baker

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?

Collapse
 
jjbully profile image
Jeffrey • Edited

Am wondering if i can nest scss, which is sthg like below:


.abc {
.efg {
background-color: white;
}
}

Collapse
 
vanortton profile image
Vanortton

Not possible with CSS, but works with SCSS

Collapse
 
ghalib profile image
Ghaleb Al-Nakhlani

Please, Where can I find the data-v- same as in your images?

Collapse
 
leonardoraele profile image
Leonardo Raele

He probably read the final html and css served to the browser. (e.g. the Elements and Styles tabs in chrome Dev Tools)

Collapse
 
ghalib profile image
Ghaleb Al-Nakhlani

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?!