CSS 模块、React 和覆盖 CSS 类
Posted
技术标签:
【中文标题】CSS 模块、React 和覆盖 CSS 类【英文标题】:CSS Modules, React and Overriding CSS Classes 【发布时间】:2016-05-14 14:10:20 【问题描述】:我正在使用 React 组件库(React Toolbox),它使用 CSS 模块和 Webpack 在其 Tab 组件中输出此类:label___1nGy active___1Jur tab___Le7N
tab
是我正在传递的 className 道具。 label
和 active
类来自库。我想在active
上应用一组不同的样式,比如.tab.active
,其中tab
指的是我创建的样式,active
匹配库创建的生成选择器,但不知道该怎么做这与 css 模块。我需要重写这个动态选择器:.label___1nGy.active___1Jur
。
[]]2 []3
【问题讨论】:
你能给我们看一个你的代码的小例子吗? 我想修改 react 工具箱组件比覆盖动态生成的类名更容易......或者你可以使用 React Toolbox Webpack Loader github.com/react-toolbox/react-toolbox#customization 感谢您的回复。我已经看过加载器并且当然打算使用它,但是我看到这种情况经常发生,并且希望避免修改库。我想知道 css-modules 本身是否为这个问题提供了一些解决方案,例如:global
或 compose
关键字
通常你会从.tab
类组成.active
类。但是 react 工具箱组件没有提供必要的 api 来设置你自己的activeClassname
prop。
【参考方案1】:
旧帖子但仍然相关,因此添加答案以帮助有类似问题的人
虽然仅在 CSS 模块中不可能实现,但 react-toolbox 库的作者实际上已经很好地解决了这个特殊问题
在https://github.com/react-toolbox/react-toolbox#customizing-components阅读他们对这个主题更深入的github文档
在他们网站的组件演示页面上也给出了特定组件的主题类列表
在您的情况下,除了为选项卡传递 className 之外,您还可以创建一个主题,其中包含覆盖默认主题所需部分的类,并将其作为 theme
属性传递。例如一些类似...
MyComponentWithTabs.css
.tab
color: white;
MyTabTheme.css
.active
color: hotpink;
MyComponentWithTabs.js
import styles from './MyComponentWithTabs.css'
import tabTheme from './MyTabTheme.css'
// blah blah...
return <Tab key=index className=styles.tab theme=tabTheme />
从表面上看,它使用了一个他们已经抽象到单独的库react-css-themr 的装饰器,我建议也阅读一下,因为它解释了默认值是如何与您的覆盖更深入地组合的,包括他们使用的不同合并策略
【讨论】:
【参考方案2】:CSS 模块不允许您安全地覆盖活动的类名(主要是设计使然)。实际上,它应该通过 API 公开,例如'activeClassName'。
如果维护者不同意或者您需要快速执行此操作,那么您可以很容易地添加自己的活动 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>
);
免责声明:代码未经测试。
【讨论】:
【参考方案3】:我有一个类似的案例,我是这样解决的:
import classNames from 'classnames';
...
const activeClassName = ;
activeClassName[`$styles.active`] = this.props.isActive;
const elementClassNames = classNames(styles.element, activeClassName);
return <div className=elementClassNames />
我正在使用classnames
包根据isActive
属性动态添加活动类。您可以提供任何布尔值,而不是 isActive
属性。
更简洁的方法可能是:
const elementClassNames = classNames(styles.element, [styles.active]: this.props.isActive);
【讨论】:
【参考方案4】:组样式加载器
您可以使用group-style-lader 覆盖组件的样式。此加载器为您提供了一种简单直观的方式来覆盖组件的样式。
配置加载器
安装加载器
npm install --save-dev group-style-loader
在你的 webpack 设置中配置加载器
module.exports =
module:
rules: [
test: /\.css$/i,
use: [
'group-style-loader',
'style-loader',
loader: "css-loader",
options:
modules: true
]
]
;
您只需将它放在
style-loader
或mini-css-extract-plugin
加载程序之前。
覆盖组件的样式
下一个示例展示了如何从 App 组件中覆盖 Card 组件的样式。
您可以按照自己的习惯定义组件的样式。
card.css
.container
width: 300px;
height: 400px;
border-radius: 8px;
.title
font-weight: bold;
font-size: 24px;
.summary
margin-top: 24px;
font-size: 20px;
唯一的区别是在卡片组件中,你要使用mergeStyle
函数将自定义样式与组件的默认样式合并。
card.jsx
import React from 'react';
import mergeStyle from './card.css';
export function Card( customStyle )
const style = mergeStyle(customStyle);
return (
<div className=style.container>
<div className=style.title>Title</div>
<div className=style.summary>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor.
</div>
</div>
)
然后,在App组件中,要覆盖Card组件的样式,你需要使用分隔符@定义Card组件的自定义样式987654330@。所有使用此分隔符的类都将被分组到样式对象的 card 属性中。
app.jsx
.title
font-size: 32px;
font-weight: bold;
margin: 44px;
.list
display: flex;
.card_title
color: blue;
.card_summary
color: green;
最后,只需要通过它的customStyle
属性传递卡片组件的自定义样式即可。
app.jsx
import React from 'react';
import Card from './card';
import style from './app.css';
export function App()
return (
<div>
<h1 className=style.title>Group style</h1>
<div className=style.list>
<Card/>
<Card customStyle=style.card/>
</div>
</div>
);
在前面的示例中,您有两个卡片组件,第一个使用其默认样式,第二个使用我们定义的自定义样式。
您可以在其repository 中查看有关如何使用group-style-loader
的完整说明。
【讨论】:
【参考方案5】:fileName.css 中的技巧
在声明className后添加className-active
.className
background: white;
.className-active
background: black;
<div className='className className-active' />
<div className='className-active className' />
div 总是黑色的
【讨论】:
以上是关于CSS 模块、React 和覆盖 CSS 类的主要内容,如果未能解决你的问题,请参考以下文章