Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the CSS for a React component has effect on all other pages

I have a React component with the following files:

  • src/components/HomePage/index.js
  • src/components/HomePage/style.scss

The component is very simple:

import React from 'react';
import './style.scss';

const HomePage = () => {
    return (
        <div className="homepage">
            <h1>Landing page</h1>
        </div>
    );
};

export default HomePage;

Within style.scss I am applying a style to all <h1> tags:

h1 {
    color: #f3f3f3;
    font-family: "Cambria";
    font-weight: normal;
    font-size: 2rem;
}

And it works as expected. However, I now see that the h1 style within styles.scss is being applied to every h1 on my site, even on pages that do not use this component.

I am using Gatsby, but it's a React app at heart. My understanding is that React's code-splitting feature would take care of this, that the code from style.scss would only be included in bundles for any page that uses my component.

It's the why that I am asking about. I have two easy fixes:

  • Wrap everything in style.scss in a .homepage wrapper
  • Use CSS modules and rename the file to style.module.scss. When I see people do that they always do `import style from './style.module.scss' - is there a way to have CSS modules without assigning it to an object like that?

Update: Coming back to this question after spending a lot of time with React and I think there's a gap in the market for React styling. CSS modules is syntactically poor in my opinion and having to manually wrap everything in a .home tag to localise it is manual work I don't want to do. Someone should really create a React plugin that automatically does this so that whenever I have a file called Home.js and I import Home.css that all the CSS is automatically restricted to Home.js without me having to do anything special.

like image 550
MSOACC Avatar asked Jul 25 '20 20:07

MSOACC


People also ask

Should each React component have its own CSS file?

Separate CSS files One last thing, create a separate CSS file for each React component. Keeping separate CSS will make it much easier to find the CSS you're looking for.

Can you change CSS With React?

To change the style of an element on click in React:Set the onClick prop on the element. When the element is clicked, set the active state. Use a ternary operator to conditionally set the new styles based on the state variable.

How to use CSS in react JS?

There are multiple ways to use the css in the react js we will discuss two majorly used ways one is using as the constant on the same component and another is using on separate file which can be used by many other components. Let us discuss both the ways and benefits of them.

Can I include a JavaScript object in React components?

You can include a JavaScript object for CSS in React components, although there are a few restrictions such as camel casing any property names which contain a hyphen. You can style React components in two ways using JavaScript objects as shown in the example. Regular CSS is a common approach, arguably one step better than inline CSS.

What are the best practices for styling React components?

Best Practices for Styling React Components 1 Introduction. In any React app, components are the basic building blocks of that application. ... 2 Inline CSS. We can add inline CSS, which are specified as attributes and are passed to the elements. ... 3 CSS in JS. ... 4 CSS Modules. ... 5 Conclusion. ...

How to scope CSS class names locally in react?

CSS Modules can be very useful to scope of CSS class names locally. Below is an example of how the same. We'll define two files: MyBtnComponent.css - This is our CSS module where we'll just define our normal CSS code. MyBtnComponent.js - This is our React Component which would render the button that'll use our CSS class defined above.


2 Answers

If you want to localize CSS rules, then you would have to switch to modular stylesheets (works the same for sass stylesheets).

In your current structure, the component imports non-modular stylesheet and doesn't localize the changes with a unique identifier. Therfore added rules live in a global scope without a unique identifier that would localize them so that only selected components could understand them. That means that they are capable of easily overwriting the same-named rules which were previously established (import order matters here, because it would dictate how the bundler appends the output stylesheet).

So instead of holding component-related rules within ./style.scss file, rename it to ./index.module.scss and then you would utilize it within the component like so:

import React from 'react';
import styles from './index.module.scss';

const HomePage = () => {
    return (
        <div className={style.homepage}>
            <h1 className={style.heading}>Landing page</h1>
        </div>
    );
};

export default HomePage;

and your stylesheet would look like:

.heading {
    color: #f3f3f3;
    font-family: "Cambria";
    font-weight: normal;
    font-size: 2rem;
}

disclaimer:

I've changed the styling convention from selecting elements by their tag, to selecting them by class, because targetting elements by tag is widely considered a bad practice [ref] , but if you want to maintain it, then you would have to provide a parent scope for such a rule (it already exists since the parent <div/> element has an assigned class. In this case the implementation would look like:

import React from 'react';
import styles from './index.module.scss';

const HomePage = () => {
    return (
        <div className={style.homepage}>
            <h1>Landing page</h1>
        </div>
    );
};

export default HomePage;

and styles:

.homepage {
    h1 {
        color: #f3f3f3;
        font-family: "Cambria";
        font-weight: normal;
        font-size: 2rem;
    }
}
like image 86
Wiktor Bednarz Avatar answered Sep 22 '22 14:09

Wiktor Bednarz


You can either go with the easiest way that is mentioned below.

import React from 'react';
import './style.scss';

const HomePage = () => {
    return (
    <div className = "home">
            <div className="homepage">
                <h1>Landing page</h1>
            </div>
    </div>
    );
};

export default HomePage;

You can wrap whole html inside one div of particular component name

CSS:

.home h1 {
    color: #f3f3f3;
    font-family: "Cambria";
    font-weight: normal;
    font-size: 2rem;
}

This is the easiest way. However this is my personal solution because I also face the same issues when I was beginner at react.

like image 44
Krenil Avatar answered Sep 22 '22 14:09

Krenil