如何使 React CSS 导入组件范围?

Posted

技术标签:

【中文标题】如何使 React CSS 导入组件范围?【英文标题】:How to make React CSS import component-scoped? 【发布时间】:2018-04-15 21:05:35 【问题描述】:

我有几个具有以下 CSS/组件结构的组件

About/style.css

.AboutContainer 
    # Some style


p > code 
    # Some style

我在组件中导入 CSS 如下

About/index.js

import './style.css';

export default class About extends Component 
    render() 
         # Return some component
    

但是,CSS 被导入 <header> 部分并保持全局范围。

我期待 CSS 是:

    组件范围内的样式仅应用于在此组件内呈现的内容。 如果卸载该组件,该组件的样式将会消失。

但是,当从浏览器检查时,样式在 <header> 部分指定并应用于所有组件

<header>
   // Stuff
   <style type="text/css">style for component About</style>
   <style type="text/css">style for component B</style>
   <style type="text/css">style for component C</style>
   // Stuff
</header>

如何将 CSS 导入组件范围?似乎我对 React ES6 中的 CSS 导入理解不正确。

我在关注this tutorial


编辑

布雷特的回答是正确的。但是,我的问题原来在其他地方。我使用create-react-app 创建了我的应用程序,它基本上简化了执行 React 所需的设置。它包括 WebPack、Babel 和其他上手的东西。它使用的默认 WebPack 配置没有为css-loader 设置module option,因此它默认为false,因此未启用本地范围。

只是为了获得更多信息,create-react-app 似乎没有直接的方法来自定义 WebPack 配置,但似乎在网络上有很多方法解决方法。

【问题讨论】:

看看 CSS 模块 - github.com/css-modules/css-modules *** 出现了问题,当“这个闪亮的库解决了您的问题”回答了一个精心制定的问题时,没有解决问题。该问题已更新为正确答案(感谢@Harry Cho!),但获得零赞成票。 你可以使用 css 模块和 create-react-app 而不根据这个博客弹出:robinwieruch.de/create-react-app-css-modules 将 mystyle.css 重命名为 mystyle.module.css 并将其导入以在使用 create-react-app 创建的 react 应用程序中使用 css 模块 【参考方案1】:

听起来CSS Modules 或许多其他 CSS-in-JS 包可以满足您的需求。其他包括Emotion(我目前最喜欢的)、Styled Components,或许多包here。

CSS 模块是一个 CSS 文件,默认情况下,所有类名和动画名都在本地范围内。所有 URL (url(...)) 和 @imports 都是模块请求格式(./xxx 和 ../xxx 表示相对,xxx 和 xxx/yyy 表示在模块文件夹中,即在 node_modules 中)。

这是一个简单的例子:

假设我们有一个 React 组件,例如:

import React from 'react';
import styles from './styles/button.css';

class Button extends React.Component 
  render() 
    return (
      <button className=styles.button>
        Click Me
      </button>
    );
  

export default Button;

还有./styles/button.css中的一些CSS:

.button 
  border-radius: 3px;
  background-color: green;
  color: white;

在 CSS Modules 执行之后,生成的 CSS 会是这样的:

.button_3GjDE 
  border-radius: 3px;
  background-color: green;
  color: white;

_3DjDE 是随机生成的散列 - 给 CSS 类一个唯一的名称。

另一种选择

更简单的替代方法是避免使用通用选择器(如pcode 等),并为组件和元素采用基于类的命名约定。即使像BEM 这样的约定也有助于防止您遇到的冲突。

将此应用于您的示例,您可能会选择:

.aboutContainer 
  # Some style


.aboutContainer__code 
  # Some style

基本上,您需要设置样式的所有元素都会收到一个唯一的类名。

【讨论】:

【参考方案2】:

也许react-scoped-css 会有所帮助。顺便说一句,我是这个库的作者,如果你发现有任何问题或只是想改进它,你可以随时提出问题或发送 pr。

【讨论】:

这很好,但是 sass 呢。 您实际上可以根据需要添加任何预处理器 谢谢。太棒了!【参考方案3】:

您可以使用 SASS (.scss) 来模仿作用域 CSS。

假设您只需要在一个组件中使用引导程序(以避免冲突)。将组件包装在 &lt;div className='use-bootstrap'&gt; 中,然后创建一个 .scss 文件,如下所示:

.use-bootstrap    
  // Paste bootstrap.min.css here

【讨论】:

这并不能解决整个问题 - CSS 选择器将被连接(如果使用 sass 嵌套),但是标记呢?内部选择器仍然存在不唯一的危险 这可行,但用于@font-face 的相关路径会导致控制台出错... 这对我来说效果很好。我使用 .use-bulma @import "bulma"; 包含了hole Bulma 框架。 【参考方案4】:

因为你提到你使用了create-react-app,所以这里的解决方案很容易将style.css更改为style.module.css,它看起来像这样:

import styles from "./style.css"
<button className=styles.button>blabla</button>

关于这篇文章的更多信息: https://blog.bitsrc.io/how-to-use-sass-and-css-modules-with-create-react-app-83fa8b805e5e

【讨论】:

【参考方案5】:

使用此文件命名约定[name].module.css 并查看文档:https://create-react-app.dev/docs/adding-a-sass-stylesheet

JSX 文件

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

const MyPage = () => 
    return (
        <div className=styles>
            <h1>My Page</h1>
        </div>
    );
;

export default MyPage;

样式文件

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

【讨论】:

以上是关于如何使 React CSS 导入组件范围?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vue 组件中导入 CSS 文件,范围仅限于组件?

在 React 中如何只导入需要的 Bootstrap 样式。引导 css 模块?

React-如何使导出组件对其目录私有?

如何在 React 组件中导入 CSS 文件

如何修复 React 应用程序中 Angular Web 组件的 CSS 问题?

如何忽略 Next.js 组件中导致单元测试中的解析错误的 CSS 模块导入