Reputation: 3525
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>
}
}
Upvotes: 19
Views: 18780
Reputation: 351
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;
Upvotes: 1
Reputation: 158
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>
Upvotes: 0
Reputation: 1306
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] {}
Upvotes: 17
Reputation: 5844
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>
Upvotes: 9
Reputation: 518
There's nothing like that in React. 3 common ways to style:
className
like normal HTML => nothing have to learn, just add an import
and you ready to go.styled-component
- it's awesome.Upvotes: 1
Reputation: 12018
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.
Upvotes: 0