在Semantic UI React中覆盖样式

16

我使用 Semantic UI React 并尝试找出最佳方法来覆盖默认样式,以便更改卡片的外观和整体主题。

选项1似乎是定义我的CSS并在每个规则后面加上!important,但这不是很好。

选项2是主题支持,听起来像我想要的,但我无法确定如何开始。我的应用程序正在使用CRA,我在文档中有点迷失于更改我的webpack配置文件(我没有一个)之间,2017年过时的博客建议我安装一堆目的不明确的模块,以及主题网站本身建议我定义灵活的变量文件(我喜欢这种方法)。

然而,我无法确定为什么我的主题文件没有被捕捉到,并且需要一些构建修复,这并未在主题指南中提到。

在使用CRA构建过程时,怎样才能使主题工作得最好呢?(./node_modules/.bin/react-scripts build

3个回答

21

专一性至上。只有当内联样式存在且库没有暴露出以某种方式关闭该属性的方法时(糟糕的架构选择),才需要使用!important

以下选择器类型按特异性递增:

类型选择器(例如,h1)和伪元素(例如,::before)。

类选择器(例如,.example)、属性选择器(例如, [type="radio"])和伪类(例如,:hover)。

ID选择器(例如,#example)。

https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

看一下Semantic UI中的第一个UI按钮这里, 由以下HTML组成:

<button class="ui button">Click Here</button>

CSS是通过semantic.min.css进行附加的:

.ui.button {
    cursor: pointer;
    display: inline-block;
    min-height: 1em;
    outline: 0;
    border: none;
    vertical-align: baseline;
    background: #e0e1e2 none;
    color: rgba(0,0,0,.6);
    font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
    margin: 0 .25em 0 0;
    padding: .78571429em 1.5em .78571429em;
    text-transform: none;
    text-shadow: none;
    font-weight: 700;
    line-height: 1em;
    font-style: normal;
    text-align: center;
    text-decoration: none;
    border-radius: .28571429rem;
    -webkit-box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
    box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    will-change: '';
    -webkit-tap-highlight-color: transparent;
}

要覆盖字体颜色,我们只需编写一个比此选择器更具体的选择器。我们可以通过将两个类选择器(同样具体)与类型选择器(额外的具体性)相结合来实现这一点。
这将如下所示:
button.ui.button {
  color: red;
}

现在,因为button.ui.button更具体地描述了页面(DOM)中元素的位置,比如只有.ui.button,这向浏览器发出信号,表明这种样式应该覆盖先前的声明。这是自定义主题的常见方式。
很棒的文档在这里: https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS

.ui.button {
    cursor: pointer;
    display: inline-block;
    min-height: 1em;
    outline: 0;
    border: none;
    vertical-align: baseline;
    background: #e0e1e2 none;
    color: rgba(0,0,0,.6);
    font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
    margin: 0 .25em 0 0;
    padding: .78571429em 1.5em .78571429em;
    text-transform: none;
    text-shadow: none;
    font-weight: 700;
    line-height: 1em;
    font-style: normal;
    text-align: center;
    text-decoration: none;
    border-radius: .28571429rem;
    -webkit-box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
    box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;
    transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
    will-change: '';
    -webkit-tap-highlight-color: transparent;
}

button.ui.button {
  color: red;
}
<button class="ui button">Click Here</button>


2
除了这个问题,因为Semantic在每个地方都使用!important,所以实际上并不起作用。https://github.com/Semantic-Org/Semantic-UI/blob/master/src/definitions/elements/button.less - mmla
1
@mmla 同样的规则适用,这个按预期工作。请参阅 CSS 文档 https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity,特别是关于如何覆盖 !Important 的部分。 - Joshua Robinson
@JoshuaRobinson所以在这种情况下,我们需要在末尾使用!important吗?或者有一种方法可以在不声明另一个!important规则的情况下覆盖!important吗? - Johhan Santana
它运行得很优雅。只需选择适当的选择器应用所述更改即可。 - pankaj

11

实际上,除非你确实需要使用 !important,否则你永远不应该使用它。除了让你的样式看起来非常丑陋外,让所有样式都成为 !important 是一种非常不好的做法。

既然你提到了 CRA,它支持 SCSS 模块,我可以告诉你还有第三种选项,我认为它更好一些。

下面是三个简单步骤:

1. 在层次结构中的某个高级元素上设置一个 id。我在 public/index.html 的 body 标签上这样做:

// public/index.html

...
  <body id='app'>
...

2. 创建一个 SCSS 模块文件,并在其中用 :global(#app) 包装所有类。

// src/page.module.scss

:global(#app) {
  .container {
    padding: 2rem;
  }
  .button {
    font-size: 3em;
  }

}

3. 导入样式并将其传递给语义化组件

// src/page.jsx

import React from 'react';
import { Button, Container } from 'semantic-ui-react';
import styles from './page.module.scss'

const Page = () => (
  <Container className={styles.container}>
    <Button className={styles.button} />
  </Container>
)

这个方法之所以可行,是因为 page.module.scss SCSS 模块的输出将被编译为以下内容:

#app .page_container_2oYQ {
  padding: 2rem;
}

#app .page_button_2oYQ {
  font-size: 3em;
}

如您所见,它将在模块化类名之前添加#app id选择器,这将增加选择器的特异性,进而覆盖semantic-ui中的选择器。


2
运行得很完美,我最终使用了#root,因为这是React附加的内容。 - Markov

2
当你拥有来自semantic ui、bootstrap、angular material ui等CSS文件时,如果想要覆盖任何元素的CSS,你在HTML中呈现或放置CSS文件的顺序决定了优先级。
为了让你的CSS文件覆盖其他CSS文件,请将你的CSS文件列在底部。当然,确保你的CSS选择器针对你想要覆盖的元素。
一张图片胜过千言万语。
假设你想要覆盖semantic ui中的以下内容:
<!-- from semantic-ui.min.css file or cdn -->
@media only screen and (min-width: 1200px) {
  .ui.container {
    max-width: 768px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

<!--override in my-custom-ui.css file --->

@media only screen and (min-width: 1200px) {
  .ui.container {
    max-width: 360px !important;
    margin-left: 10px !important;
    margin-right: 10px !important;
  }
}

<!--this is where precedence is set, the last css file has the highest precedence-->
<!DOCTYPE html>
<html lang="en">
<head>
 <title>my title</title>
 <meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui/dist/semantic.min.css"
    />

<!-- place your css file containing css overridden for semantic ui elements or other css at the bottom -->
<link rel="stylesheet" href="my-custom-ui.css" />
</head>
<body>
<header>
 My header
</header>
<content>
 My content
</content>
<footer>
 My footer
</footer>
</body
<script/>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接