具有 CSS 自定义属性的条件样式

问题描述 投票:0回答:6

我喜欢使用 CSS 自定义属性,但我经常发现我希望能做到这一点。

我希望能够根据 CSS 自定义属性的值有条件地应用某些样式。这是一些伪代码:

.something {
  border: var(--is-dark-theme) ? 1px solid : none;
}

我知道自定义属性不是这样工作的。但可能还有一些我不知道的其他方法可以帮助我实现类似的结果?

或者也许有一些规范提案可以在未来实现这一点?

css specifications theming css-variables
6个回答
12
投票

这是另一个类似于 Ori Drori 的答案 的想法,我依靠在边框内使用无效值来删除边框。如果您想使用

false
/
true
/
yes
/
no

等关键字,这可能很有用

.something {
  border: var(--is-dark-theme,2px) solid black;
}
<div class="something">Dark theme</div>

<div class="something" style="--is-dark-theme: false">Light theme</div>


7
投票

有时您可以使用

calc()
来获得大致相似的结果。在这种情况下,如果
--is-dark-theme
为 0 或 1,您可以将其乘以边框的
width
,以显示或隐藏它:

.something {
  border: calc(var(--is-dark-theme) * 1px) solid black;
}
<div class="something" style="--is-dark-theme: 1">Dark theme</div>

<div class="something" style="--is-dark-theme: 0">Light theme</div>


5
投票

仅供参考:以下内容今天(2023-02-06)不起作用,但将来的某一天可能会出现这个非常好的 CSS 功能,称为 容器样式查询

/* not working today (2023-02-06), maybe in future */

@container style(--theme: dark) {
  .box {
    border: 1px solid #aaa;
  }
}

3
投票

如果你有类似“条件 xyz 是

on
off
”的情况(比如在浅色主题与深色主题示例中),你可以使用以下 CSS 技巧(我知道如果你看到这个技巧,这看起来很奇怪第一次,但与其他答案中提出的技巧相比,这个技巧适用于所有 CSS 属性):

对于每个开/关条件定义两个自定义属性,一个用于“开”情况,一个用于“关”情况。使用值

on
代替
initial
,使用值
off
(空格字符)代替
 

.light-theme {
  --is-light-theme: initial; 
  --is-dark-theme: ;
}

.dark-theme {
  --is-light-theme: ;
  --is-dark-theme: initial;
}

div {
  font-family: Helvetica, Arial, sans-serif;
  padding: 1rem;
  
  color:
    var(--is-light-theme, black)
    var(--is-dark-theme, white);
  
  background-color:
    var(--is-light-theme, #f4f4f4)
    var(--is-dark-theme, black);

  border:
    var(--is-light-theme, none)
    var(--is-dark-theme, 5px solid #aaa);
}
<div class="light-theme">
  light theme
</div>
<div class="dark-theme">
  dark theme
</div>


3
投票

此代码使您能够应用基于父级 CSS 属性的类。 因此,通过将不同的 CSS 应用于父元素,您可以更改应用于子元素的类:

.outer:hover {
  container-name: dark;
  container-type: inline-size;
}

.inner{background-color:silver;color:black;}

@container dark (min-width: 0px)  {
  .inner{background-color:#333;color:white}
}
<div class="outer">
  <div class="inner">inner</div>
</div>

这里我们有类名为

.inner
的元素,默认情况下它具有银色背景和白色文本颜色。

在它上面我们有一个类名为

.outer
的父元素。
.outer
类默认没有样式,但是在悬停时我们将
container-name
设置为
dark

.inner
元素位于具有
container-name:dark
的元素内部时,我们可以将其作为目标,并使用始终为 true 的谓词
(min-width: 0px)


3
投票

这是我上面的演示的替代版本,使用 Thorgeir 的天才答案(我添加了那些额外的

.container
div 以使解决方案更好理解):

.light-theme {
  --theme: light;
}

.dark-theme {
  --theme: dark;
}

.container {
  container: var(--theme) / inline-size;  
}

.text-box {
  font-family: Helvetica, Arial, sans-serif;
  padding: 1rem;
  color: black;
  background-color: #f4f4f4;
  border: none;
}

@container dark (min-width: 0) {
  .text-box {
    color: white;
    background-color: black;
    border: 5px solid #aaa;
  }
}
  <div class="light-theme">
    <div class="container">
      <div class="text-box">light theme</div>
    </div>
  </div>
  <div class="dark-theme">
    <div class="container">
      <div class="text-box">dark theme</div>
    </div>
  </div>
  

© www.soinside.com 2019 - 2024. All rights reserved.