我喜欢使用 CSS 自定义属性,但我经常发现我希望能做到这一点。
我希望能够根据 CSS 自定义属性的值有条件地应用某些样式。这是一些伪代码:
.something {
border: var(--is-dark-theme) ? 1px solid : none;
}
我知道自定义属性不是这样工作的。但可能还有一些我不知道的其他方法可以帮助我实现类似的结果?
或者也许有一些规范提案可以在未来实现这一点?
这是另一个类似于 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>
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>
仅供参考:以下内容今天(2023-02-06)不起作用,但将来的某一天可能会出现这个非常好的 CSS 功能,称为 容器样式查询:
/* not working today (2023-02-06), maybe in future */
@container style(--theme: dark) {
.box {
border: 1px solid #aaa;
}
}
如果你有类似“条件 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>
此代码使您能够应用基于父级 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)
这是我上面的演示的替代版本,使用 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>