CSS 模块、反应和覆盖 CSS 类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35209924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 11:44:14  来源:igfitidea点击:

CSS Modules, React and Overriding CSS Classes

csscss-modules

提问by Joe Bruno

I am using a React component library (React Toolbox), which is outputting this class in their Tab component using CSS Modules and Webpack: label___1nGy active___1Jur tab___Le7NThe tabis a className prop I am passing down. The labeland activeclasses are coming from the library. I want to apply a different set of styles on active, something like .tab.activewhere tabis referring to the styles I have created and activematches the generated selector the library has created but cannot figure out how to do this with css-modules. I need to override this dynamically selector: .label___1nGy.active___1Jur.

我正在使用一个 React 组件库(React Toolbox),它使用 CSS 模块和 Webpack 在他们的 Tab 组件中输出这个类:label___1nGy active___1Jur tab___Le7Ntab是我传递的一个 className属性。在labelactive类是从图书馆来了。我想在 上应用一组不同的样式active,例如.tab.activewheretab指的是我创建的样式并active匹配库创建的生成的选择器,但无法弄清楚如何使用 css-modules 执行此操作。我需要重写这个动态的选择:.label___1nGy.active___1Jur

Browser

浏览器

[CSS]]2[React]3

[ CSS]] 2[ 反应] 3

采纳答案by alechill

Old post but still relevant, so adding an answer to help those with similar issue

旧帖子但仍然相关,所以添加一个答案来帮助那些有类似问题的人

While not inherently possible in CSS modules alone, the author of the react-toolbox library has actually solved this particular problem very nicely

虽然在 CSS 模块中本身不可能,但 react-toolbox 库的作者实际上很好地解决了这个特殊问题

Read their github docs which are more in depth on the subject at https://github.com/react-toolbox/react-toolbox#customizing-components

https://github.com/react-toolbox/react-toolbox#customizing-components上阅读他们的 github 文档,这些文档更深入地讨论了该主题

A list of the themeable classes for a particular component is given on the component demo page on their site too

在其站点的组件演示页面上也提供了特定组件的可主题化类列表

In your case as well as passing a className for tab, you would also create a theme with classes that overrides that desired parts of the default theme and pass that as the themeprop. For example something alog the lines of...

在您的情况下,除了为选项卡传递 className 之外,您还可以创建一个带有类的主题,这些类覆盖默认主题的所需部分并将其作为theme道具传递。例如一些类似的东西......

MyComponentWithTabs.css

MyComponentWithTabs.css

.tab {
  color: white;
}

MyTabTheme.css

MyTabTheme.css

.active {
  color: hotpink;
}

MyComponentWithTabs.js

MyComponentWithTabs.js

import styles from './MyComponentWithTabs.css'
import tabTheme from './MyTabTheme.css'

// blah blah...

return <Tab key={index} className={styles.tab} theme={tabTheme} />

Under the surface this uses a decorator they have abstracted into separate library react-css-themr, I recommend giving that a read too as it explains how the defaults are composed with your overrides in much greater depth, including the different merging strategies they use

在表面之下,这使用了一个装饰器,他们已将其抽象为单独的库react-css-themr,我建议您也阅读一下,因为它解释了如何更深入地解释默认值与您的覆盖组合,包括他们使用的不同合并策略

回答by riscarrott

CSS modules won't allow you to safely override the active className (largely by design). Really it should be exposed via an API, e.g. 'activeClassName'.

CSS 模块不允许您安全地覆盖活动的 className(主要是设计使然)。实际上,它应该通过 API 公开,例如“activeClassName”。

If the maintainers disagree or you need this quick then you can quite easily add your own active className because your implementing component is managing the index state:

如果维护者不同意或者你需要快速,那么你可以很容易地添加你自己的活动 className,因为你的实现组件正在管理索引状态:

import {Tab, Tabs} from 'react-toolbox';
import styles from './MyTabs.css';


class MyTabs extends React.Component {
  state = {
    index: 1
  };

  handleTabChange(index) {
    this.setState({ index });
  }

  render() {
    const { index } = this.state;
    return (
      <Tabs index={index} onChange={this.handleTabChange}>
        <Tab label="Tab0" className={index === 0 ? styles.active : null}>
            Tab 0 content
        </Tab>
        <Tab label="Tab1" className={index === 1 ? styles.active : null}>
            Tab 1 content
        </Tab>
      </Tabs>
    );
  }
}

Disclaimer: Code is untested.

免责声明:代码未经测试。

回答by Patrick

I had a similar case, and I solved it like so:

我有一个类似的案例,我是这样解决的:

import classNames from 'classnames';

...

const activeClassName = {};
activeClassName[`${styles.active}`] = this.props.isActive;
const elementClassNames = classNames(styles.element, activeClassName);

return <div className={elementClassNames} />

I'm using the classnamespackage to dynamically add the active class based off of the isActiveprop. Instead of an isActiveprop you can provide any boolean value.

我正在使用该classnames包根据isActive道具动态添加活动类。isActive您可以提供任何布尔值而不是道具。

A more terse way of doing this may be:

一种更简洁的方法可能是:

const elementClassNames = classNames(styles.element, {[styles.active]: this.props.isActive});

回答by David Minaya

You can override the style of the element using composes. In the bellow example, I make a ButtonComponentthat is used in a FormComponent. In the FormComponent I override the default style of the ButtonComponent.

您可以使用 覆盖元素的样式composes。在下面的示例中,我创建了一个ButtonComponentFormComponent. 在 FormComponent 中,我覆盖了 ButtonComponent 的默认样式。

ButtonComponent.css

按钮组件.css

.defaultButton {
  width: 100px;
  height: 40px;
  color: red;
  background-color: black;
}

ButtonComponent.jsx

按钮组件.jsx

import React from 'react';
import style from './buttonComponent.css';

export function ButtonComponent({ text, className = style.defaultButton }) {
  return (
    <button 
      className={className}>
      {text}
    </button>
  );
}

I set the property classNamewith the default style of the button to use it if the user don't set this property.

className如果用户未设置此属性,我将使用按钮的默认样式设置该属性以使用它。

FormComponent.css

表单组件.css

.overrideButton {
  composes: defaultButton from './ButtonComponent.css'; // This is the important
  color: green;
  background-color: blue;
}

FormComponent.jsx

表单组件.jsx

import React from 'react';
import style from './FormComponent.css';
import { ButtonComponent } from './ButtonComponent';

export function FormComponent() {
  return (
    <form>
      <ButtonComponent text='Default style'/>
      <ButtonComponent text='Override style' className={style.overrideButton}/>
    </form>
  );
}