20

Is there a React equivalent of scoped css as in Vue that's super easy to work with, without a bunch of re-writes? One which I can just import an existing css file, and hook it up to a component, and it just works?

In Vue, it's as easy as

<style scoped src="./boxes.css"></style>

And Bam! Your css is now scoped to your component.

Is there anything similar in React? Something like

// import the css file
import styles from "./boxes.css";

// hook it to a component, or using any other methods
@inject(styles)
class Boxes extends Component {
  render(){
    <div className='container'>
       /* must support multiple classes out-of-the-box, unlike CSSModule where you have to 
       re-write into a super long array like className={[styles.box, styles.green, styles.large]} */
      <div className='box green large'></div> 
      <div className='box red small'></div> 
    </div>
  }
}
3
  • you need that: styled-components.com ... it's so superior to VUE scoped css Commented May 28, 2019 at 23:06
  • example of how vue is simple and powerful out of the box. Commented Feb 20, 2020 at 22:40
  • Have you tried Svelte? ... It has it built in ... and is much more performant than React :) Commented Nov 23, 2021 at 18:46

6 Answers 6

17

Every answer here is about CSS Modules, but scoped styles in Vue works another way.

Here the library for React that works like <style scoped> in Vue: https://github.com/gaoxiaoliangz/react-scoped-css

Input:

import React from 'react'
import './Title.scoped.css'

const Title = props => {
  return (
    <h1 className="title">
      <p>{props.children}</p>
    </h1>
  )
}

export default Title

Output:

<h1 class="title" data-v-hi7yyhx>
.title[data-v-hi7yyhx] {}
Sign up to request clarification or add additional context in comments.

Comments

9

https://facebook.github.io/create-react-app/docs/adding-a-css-modules-stylesheet

Button.module.css

.error {
  background-color: red;
}

another-stylesheet.css

.error {
  color: red;
}

Button.js

import React, { Component } from 'react';
import styles from './Button.module.css'; // Import css modules stylesheet as styles
import './another-stylesheet.css'; // Import regular stylesheet

class Button extends Component {
  render() {
    // reference as a js object
    return <button className={styles.error}>Error Button</button>;
  }
}

Result: No clashes from other .error class names

<!-- This button has red background but not red text -->
<button class="Button_error_ax7yz">Error Button</button>

Comments

1

There's nothing like that in React. 3 common ways to style:

  1. Import a css file then use className like normal HTML => nothing have to learn, just add an import and you ready to go.
  2. Css-in-js libraries. I prefer styled-component - it's awesome.
  3. Inline style

3 Comments

but 1. won't be scoped, it'll affect all other components
I found your question deplicated here. More infor about scope CSS in React link
For styled-components see: styled-components
1

For anyone that stumbles upon this...

Coming from Vue, I faced this issue as well. I was able to device a flexible scoped styling structure for each component

Consider the below.

const useOwnStyles = () => ({
    hero: {
        backgroundColor: "red",
        height: "300px",
    },
    // add more classes
});

const Home = () => {
    const classes = useOwnStyles();
    return (
        <div style={classes.hero}>
           <div>My Section</div>
        </div>
    );
}
 
export default Home;

Comments

0

As far as I know, there's no way to do it exactly the way Vue does it, but there are plenty of libraries for doing this kind of thing, which gives you lots of choice for however you prefer to work. My personal recommendation is emotion.

3 Comments

Why isn't it possible in React?
It's probably possible with React, but no one's really had a real need for it. The current solutions for styling have been satisfactory for the most part
I think people will be looking for this feature if they have Vue experience. I did Vue and React. And if scoped styling feature of Vue is available in react it will remove verbose JS className code in components. From className={`text-3xl mt-4 ${styles.yo}`} to className="text-3xl mt-4 yo"
0

You can use css modules with the webpack css-loader.

It will scope your css by adding a unique hash in the name of your css classes.

For exemple if you have a ComponentA with a style definition in a file named stylesA.css and a ComponentB with a style definition in a file named stylesB.css like:

import * as React from 'react'

const stylesA = require('./stylesA.css')
const stylesB = require('./stylesB.css')

class ComponentA extends React.Component {
  render <div className={stylesA.container}>
}

class ComponentB extends React.Component {
  render <div className={stylesB.container}>
}

class Main extends React.Component {
  render <div>
    <ComponentA />
    <ComponentB />
  </div>
}

your HTML file will result as

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
  </head>
  <body>
    <div id="app">
      <div class="container-[HASH FOR A]">
      </div>
      <div class="container-[DIFFERENT HASH FOR B]">
      </div>
    </div>
    <script src="bundle.js"></script>
  </body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.