Hai*_*vgi 107 css stylesheet conditional-statements
我想在我的CSS中使用条件.
我的想法是,当运行站点以生成正确的样式表时,我有一个我替换的变量.
我想要它,以便根据这个变量样式表改变!
看起来像:
[if {var} eq 2 ]
background-position : 150px 8px;
[else]
background-position : 4px 8px;
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?你怎么做到这一点?
Bol*_*wyn 125
不是传统意义上的,但如果您可以访问HTML,则可以使用类.考虑一下:
<p class="normal">Text</p>
<p class="active">Text</p>
Run Code Online (Sandbox Code Playgroud)
并在您的CSS文件中:
p.normal {
background-position : 150px 8px;
}
p.active {
background-position : 4px 8px;
}
Run Code Online (Sandbox Code Playgroud)
这是CSS的方式.
然后是像Sass这样的CSS预处理器.你可以在那里使用条件,看起来像这样:
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
Run Code Online (Sandbox Code Playgroud)
缺点是,您必须预先处理样式表,并且在编译时评估条件,而不是运行时.
CSS本身的一个新功能是自定义属性(也就是CSS变量).它们在运行时进行评估(在支持它们的浏览器中).
有了他们,你可以做一些事情:
:root {
--main-bg-color: brown;
}
.one {
background-color: var(--main-bg-color);
}
.two {
background-color: black;
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以使用自己喜欢的服务器端语言预处理样式表.如果您使用的是PHP,请提供一个style.css.php类似于以下内容的文件:
p {
background-position: <?php echo (@$_GET['foo'] == 'bar')? "150" : "4"; ?>px 8px;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将对性能产生影响,因为缓存这样的样式表将很困难.
Pet*_*ter 18
我很惊讶没有人提到 CSS 伪类,它们也是 CSS 中的一种条件。你可以用它做一些非常高级的事情,而无需一行 JavaScript。
一些伪类:
例子:
div { color: white; background: red }
input:checked + div { background: green }Run Code Online (Sandbox Code Playgroud)
<input type=checkbox>Click me!
<div>Red or green?</div>Run Code Online (Sandbox Code Playgroud)
mar*_*kus 15
以下是我的旧答案仍然有效,但我今天有一个更加自以为是的方法:
CSS糟透了的原因之一就是它没有条件语法.CSS本身在现代Web堆栈中完全无法使用.使用SASS一会儿,你会知道我为什么这么说.SASS具有条件语法......以及与原始CSS相比还有很多其他优点.
旧答案(仍然有效):
一般来说,它无法在CSS中完成!
您有浏览器条件,例如:
/*[if IE]*/
body {height:100%;}
/*[endif]*/
Run Code Online (Sandbox Code Playgroud)
但没有人阻止您使用Javascript来动态更改DOM或动态分配类,甚至连接各自编程语言中的样式.
我有时将css类作为字符串发送到视图并将它们回显到代码中(php):
<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>
Run Code Online (Sandbox Code Playgroud)
vsy*_*ync 10
我写了一篇关于CSS-Tricks 中的以下独特方法的文章,其中详细介绍了
我设计了下面的演示,使用混合技巧,允许模拟 某些属性的if/else场景。本质上是数字的任何属性都是此方法的容易目标,但具有文本值的属性是。
这段代码有 3 个if/else场景, for opacity, background color& width。所有 3 都由两个布尔变量bool及其相反的notBool.
这两个布尔值是此方法的关键,要从非布尔动态值中实现布尔值,需要一些数学运算,幸运的是 CSS 允许使用min&max函数。
显然,最近的浏览器版本支持这些函数(最小值/最大值),这些版本也支持 CSS 自定义属性(变量)。
var elm = document.querySelector('div')
setInterval(()=>{
elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)Run Code Online (Sandbox Code Playgroud)
:root{
--color1: lightgreen;
--color2: salmon;
--width: 70; /* starting value, randomly changed by javascript every 1 second */
}
div{
--widthThreshold: 50;
--is-width-above-limit: Min(1, Max(var(--width) - var(--widthThreshold), 0));
--is-width-below-limit: calc(1 - var(--is-width-above-limit));
--opacity-wide: .4; /* if width is ABOVE 50 */
--radius-narrow: 10px; /* if width is BELOW 50 */
--radius-wide: 60px; /* if width is ABOVE 50 */
--height-narrow: 80px; /* if width is ABOVE 50 */
--height-wide: 160px; /* if width is ABOVE 50 */
--radiusToggle: Max(var(--radius-narrow), var(--radius-wide) * var(--is-width-above-limit));
--opacityToggle: calc(calc(1 + var(--opacity-wide)) - var(--is-width-above-limit));
--colorsToggle: var(--color1) calc(100% * var(--is-width-above-limit)),
var(--color2) calc(100% * var(--is-width-above-limit)),
var(--color2) calc(100% * (1 - var(--is-width-above-limit)));
--height: Max(var(--height-wide) * var(--is-width-above-limit), var(--height-narrow));
height: var(--height);
text-align: center;
line-height: var(--height);
width: calc(var(--width) * 1%);
opacity: var(--opacityToggle);
border-radius: var(--radiusToggle);
background: linear-gradient(var(--colorsToggle));
transition: .3s;
}
/* prints some variables */
div::before{
counter-reset: aa var(--width);
content: counter(aa)"%";
}
div::after{
counter-reset: bb var(--is-width-above-limit);
content: " is over 50% ? "counter(bb);
}Run Code Online (Sandbox Code Playgroud)
<div></div>Run Code Online (Sandbox Code Playgroud)
clamp:label{ --width: 150 }
input:checked + div{ --width: 400 }
div{
--isWide: Clamp(0, (var(--width) - 150) * 99999, 1);
width: calc(var(--width) * 1px);
height: 150px;
border-radius: calc(var(--isWide) * 20px); /* if wide - add radius */
background: lightgreen;
}Run Code Online (Sandbox Code Playgroud)
<label>
<input type='checkbox' hidden>
<div>Click to toggle width</div>
</label>Run Code Online (Sandbox Code Playgroud)
我想出了一个完全独特的方法,它更简单!
这个方法很酷,因为它很容易实现,也很容易理解。它基于animation step()功能。
由于bool可以很容易地计算为0或1,因此可以在step! 如果只定义了一个步骤,那么if/else问题就解决了。
使用关键字forwards持久化更改。
var elm = document.querySelector('div')
setInterval(()=>{
elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)Run Code Online (Sandbox Code Playgroud)
:root{
--color1: salmon;
--color2: lightgreen;
}
@keyframes if-over-threshold--container{
to{
--height: 160px;
--radius: 30px;
--color: var(--color2);
opacity: .4; /* consider this as additional, never-before, style */
}
}
@keyframes if-over-threshold--after{
to{
content: "true";
color: green;
}
}
div{
--width: 70; /* must be unitless */
--height: 80px;
--radius: 10px;
--color: var(--color1);
--widthThreshold: 50;
--is-width-over-threshold: Min(1, Max(var(--width) - var(--widthThreshold), 0));
text-align: center;
white-space: nowrap;
transition: .3s;
/* if element is narrower than --widthThreshold */
width: calc(var(--width) * 1%);
height: var(--height);
line-height: var(--height);
border-radius: var(--radius);
background: var(--color);
/* else */
animation: if-over-threshold--container forwards steps(var(--is-width-over-threshold));
}
/* prints some variables */
div::before{
counter-reset: aa var(--width);
content: counter(aa)"% is over 50% width ? ";
}
div::after{
content: 'false';
font-weight: bold;
color: darkred;
/* if element is wider than --widthThreshold */
animation: if-over-threshold--after forwards steps(var(--is-width-over-threshold)) ;
}Run Code Online (Sandbox Code Playgroud)
<div></div>Run Code Online (Sandbox Code Playgroud)
我发现了一个Chrome 错误,我已报告该错误会在某些需要特定类型计算的情况下影响此方法,但有一种解决方法。
您可以创建两个单独的样式表,并根据比较结果包含其中一个样式表
在其中一个你可以把
background-position : 150px 8px;
Run Code Online (Sandbox Code Playgroud)
在另一个
background-position : 4px 8px;
Run Code Online (Sandbox Code Playgroud)
我认为你可以在CSS中执行的唯一检查是浏览器识别:
将服务器设置为将css文件解析为PHP,然后使用简单的PHP语句定义变量变量.
当然这假设您正在使用PHP ...
您可以calc()结合使用与var()模拟条件句:
:root {
--var-eq-two: 0;
}
.var-eq-two {
--var-eq-two: 1;
}
.block {
background-position: calc(
150px * var(--var-eq-two) +
4px * (1 - var(--var-eq-two))
) 8px;
}
Run Code Online (Sandbox Code Playgroud)
CSS 是一个设计精美的范式,它的许多功能都没有被广泛使用。
如果条件和变量是指将某个值的更改分发到整个文档或某个元素的范围内的机制,那么这是如何做到的:
var myVar = 4;
document.body.className = (myVar == 5 ? "active" : "normal");Run Code Online (Sandbox Code Playgroud)
body.active .menuItem {
background-position : 150px 8px;
background-color: black;
}
body.normal .menuItem {
background-position : 4px 8px;
background-color: green;
}Run Code Online (Sandbox Code Playgroud)
<body>
<div class="menuItem"></div>
</body>Run Code Online (Sandbox Code Playgroud)
这样,您就可以在整个 CSS 样式中分配变量的影响。这类似于@amichai 和@SeReGa 的提议,但更通用。
另一个这样的技巧是在整个文档中分发某个活动项目的 ID,例如再次突出显示菜单时:(使用 Freemarker 语法)
var chosenCategory = 15;
document.body.className = "category" + chosenCategory;Run Code Online (Sandbox Code Playgroud)
<#list categories as cat >
body.category${cat.id} .menuItem { font-weight: bold; }
</#list>Run Code Online (Sandbox Code Playgroud)
<body>
<div class="menuItem"></div>
</body>Run Code Online (Sandbox Code Playgroud)
当然,这仅适用于有限的项目集,例如类别或状态,而不是像电子商店商品那样的无限集,否则生成的 CSS 会太大。但是在生成静态离线文档时特别方便。
将 CSS 与生成平台结合起来做“条件”的另一个技巧是:
.myList {
/* Default list formatting */
}
.myList.count0 {
/* Hide the list when there is no item. */
display: none;
}
.myList.count1 {
/* Special treatment if there is just 1 item */
color: gray;
}Run Code Online (Sandbox Code Playgroud)
<ul class="myList count${items.size()}">
<!-- Iterate list's items here -->
<li>Something...</div>
</ul>Run Code Online (Sandbox Code Playgroud)