7

I have two .jsx files that represent their respective components.

The first one is, Blog.jsx

import React from "react";
import '../assets/css/blog.css';

export const Blog = () => (
    <div>
        <h1>Hello Blog</h1>
    </div>
)

With its respective CSS file, blog.css

div { background: #ff481f; }

and the second one is, Landing.jsx

import React from "react";
import '../assets/css/landing.css'

export const Landing = () => (
    <div>
        <h1>Hello Landing</h1>
    </div>
)

With its respective CSS file, landing.css

div { background: #86ff2b; }

I have added routing and called instances of those two components on the App.js file which is the default file of a React application. After running the application, when navigated to components, I faced a problem that the background color is the same for both of the components (It loads landing.css only and never changes).

How can I fix that problem that each component only uses its respective .css file and loads it?

3
  • 1
    React is not MVC based so you have to assign different classes other wise the most recent styles will override the previous styles Commented Jan 20, 2020 at 6:10
  • @BILAL Did you mean using class components instead of functional components? Commented Jan 20, 2020 at 6:14
  • 1
    No it doesn't matter which type of component you use, the styling wont be independent for each component. Just use id's if you need to make a unique style for a component Commented Jan 20, 2020 at 6:17

4 Answers 4

5

By default webpack and other build tools will compile all CSS files into one, even if css was imported in separate JSX files. So you can't use different CSS files and expect you don't affect on another part of page.

You have some options:

  1. Use BEM for naming class names.
  2. Use cssModules. In this case elements will have their own css class name and styles will not affect any other elements except if you use :global selector.

Sign up to request clarification or add additional context in comments.

5 Comments

React does not compile anything, react it's concept of transforming state into view, css files are webpack or other build tools worries. Sass have nothing to do with BEM, you can use BEM without SCSS. When you say: all pages will have their own CSS styles you are wrong, css modules solve another problem. In any way your answer is not answer for OP question.
as I said. webpack compiles all CSS altogether. not react.
and cssModule solve the problem because as I said, again, all pages will have their own CSS styles. if you write some CSS based on cssModule you will see styles will not affect any other pages. because of thanks to babel which generate random names for elements & use them for styling.
after your edits the answer got a little bit better :) but css modules know about pages nothing and css modules solve problems about styles encapsulation not in pages, css modules works with css selectors, so you should know basics
I edit the answer again. I think we talk about one thing in common. with cssModule we can prevent css affect another elements & pages (thanks to random css selectors which generated with babel & cssModule)
3

Using html tags as css selectors is a bad practice (because there is the behaviour you describe).

You should use only css classes or inline styles (using id's is another bad practise, id's have high priority).

div {
  width: 20px;
  height: 20px;
}

#id {
  background: red;
}

.class {
  background: green;
}
<div id="id" class="class"></div>

In case using css classes there is the same problem (when you have two similar classes). And this case is decided using css modules (set of rules of building) or you can use css-in-js (external library) which has its pros and cons. Also you can use BEM (methodology) and if your application is not big you can avoid this trouble.

css modules will add to your classes random hash and instead .my-awesome-class-name you will get .my-awesome-class-name-dew3sadf32s.

So, if you have two classes .class in the first file and .class in the second file in the end you will get two classes .class-dew23s2 and .class-dg22sf and you styles will resolve as expected.

css-in-js is a similar way except you should write your styles using javascript with some profits like including only those styles that are needed at the moment (what you are looking for right now) and several others.

You can code using pure css / scss / postcss / etc but many companies already choose between css modules and css-in-js.

BEM is just naming conventions for your class names.

And lastly - if you use inline-styles using react you should remember:

{} is constructor of object and {} returns new object on every call, it's mean if you write something like:

class MyAwesomeComponent extends Component {
  render() {
    return <div style={{color: "red"}}></div>;
  }
}

or

class MyAwesomeComponent extends Component {
  render() {
    const divStyles = {color: "red"};

    return <div style={divStyles}></div>;
  }
}

div will re-render every time your render will call because div takes new prop.

Instead, you should define your styles (for example) in outside of your class:

const divStyles = {color: "red"};

class MyAwesomeComponent extends Component {
  render() {
    return <div style={divStyles}></div>;
  }
}

2 Comments

inline styling is not necessarily bad, but not a good approach. because a new object will be created and the browser need to recalculate styles on every re-renders. link
@sepehr i don't say that inline-styles is bad. I try to warn about using of inline-styles :)
1

Don't define your css using HTML tags because it will affect your entire application.

use className,id or inline styling.

like- App.css

  .myApp{ color: red;}
  #myApp2{ color: blue;}

App.js

import './App.css'

<div className="myApp">color changed by className</div>
<div id="myApp2">color changed by id</div>
<div style={{color:'red'}}>color changed by inline object styling</div> // inline styling

6 Comments

please, don't use id's as css selectors
please, don't use also inline styles like style={{color:'red'}}
@SaveliTomac can you describe for both?
First: ID's have high priority (it's main reason) dev.to/clairecodes/reasons-not-to-use-ids-in-css-4ni4 Second: When you write style={{color:'red'}} you create new object every time your render was called, it's mean you element takes new prop and will rerender even your styles don't change
@SaveliTomac did i explain about Specificity in my solution?... whatever you are saying i know very well. that's syntax defined by reactjs to use.
|
0

This is not the best solution if you are looking forward to improve yours css imports/loads.

However could be the best solution if you dont want to go in deep in css, resolve the problem fast and keep working with HTML tag.

You can add a div for each component, define an Id for the div and wrap the component. Afterwards in the component's css fies you are going to define all the styles starting with the #id so all the css classe or HTML tag will affect just the corresponding component.

//App render in root
ReactDOM.render(
  <App />,
  document.getElementById('root')
);

//App
function App(props){
  return [
    <Blog />, <OtherComponent />
    ]
}
//Blog component
function Blog(props){
  return <div id="blog">
    <h1>I am Blog</h1>
    </div>
}

//Other component
function OtherComponent(props){
  return <div id="otherComponent">
    <h1>Im am other component</h1>
    </div>
}
/* blog.css*/
#blog h1{
color:yellow;
}

/* otherComponent.css*/
#otherComponent h1{
color:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="root"></div>

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.