Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

javascript - 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?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...