你能在 CSS 中使用 if/else 条件吗?

我想在 CSS 中使用条件。

我的想法是,我有一个变量,我替换时,网站运行,以生成正确的样式表。

我希望它能够根据这个变量改变样式表!

看起来像是:

[if {var} eq 2 ]
background-position : 150px 8px;
[else]
background-position : 4px 8px;

这能做到吗? 你是怎么做到的?

815396 次浏览

据我所知,在 css 中没有 if/then/else。或者,您可以使用 javascript 函数来更改元素的背景位置属性。

将服务器设置为将 css 文件解析为 PHP,然后用一个简单的 PHP 语句定义变量变量。

当然,这是假设您正在使用 PHP..。

以下是我过去的回答,现在仍然有效,但我今天有一个更加固执己见的方法:

CSS 如此糟糕的原因之一就是它没有条件语法。CSS 本身在现代网络堆栈中是完全不可用的。用一会儿 SASS,你就会知道我为什么这么说了。SASS 有条件语法... ... 和许多其他的优势比原始的 CSS 太。


旧答案(仍然有效) :

它不能在 CSS 中完成一般!

你的浏览器条件是这样的:

/*[if IE]*/
body {height:100%;}
/*[endif]*/

但是没有人阻止您使用 Javascript 来改变 DOM 或动态分配类,甚至在各自的编程语言中连接样式。

我有时将 css 类作为字符串发送到视图,并将它们回显到代码中,如下所示(php) :

<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>

不是传统意义上的,但是如果您能够访问 HTML,那么您可以为此使用类。想想这个:

<p class="normal">Text</p>


<p class="active">Text</p>

并在您的 CSS 文件:

p.normal {
background-position : 150px 8px;
}
p.active {
background-position : 4px 8px;
}

这就是 CSS的做法。


还有像 无礼这样的 CSS 预处理器,你可以在那里使用 条件句,它看起来是这样的:

$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}

缺点是,您必须预处理样式表,并且条件是在编译时而不是运行时计算的。


CSS 的一个新特性是 自定义属性(又名 CSS 变量)。它们在运行时(在支持它们的浏览器中)进行计算。

有了他们,你可以做一些类似的事情:

:root {
--main-bg-color: brown;
}


.one {
background-color: var(--main-bg-color);
}


.two {
background-color: black;
}

最后,您可以使用喜欢的服务器端语言对样式表进行预处理。如果您正在使用 PHP,那么提供一个 style.css.php文件,它看起来像这样:

p {
background-position: <?php echo (@$_GET['foo'] == 'bar')? "150" : "4"; ?>px 8px;
}

但是,在这种情况下,您将会对性能产生影响,因为缓存这样的样式表将很困难。

您可以创建两个独立的样式表,并基于比较结果包含其中一个

你可以把

background-position : 150px 8px;

在另一个里面

background-position : 4px 8px;

我认为唯一可以在 CSS 中执行的检查是浏览器识别:

条件-CSS

这是一个小额外的信息,以上博尔德温答案。

添加一些 php 代码来执行 if/else

if($x==1){
print "<p class=\"normal\">Text</p>\n";
} else {
print "<p class=\"active\">Text</p>\n";
}

另一种选择(基于您是否希望对 if 语句进行动态计算)是使用 C 预处理器,如 给你所述。

(是的,老线索。但它出现在谷歌搜索的顶部,所以其他人可能也感兴趣)

我想 if/else-Logic 可以用 javascript 完成,而 javascript 又可以动态加载/卸载样式表。我还没有在浏览器上测试过,但是应该可以。这会让你开始:

Http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml

你可以用 not 代替 if like

.Container *:not(a)
{
color: #fff;
}

您可以为所有条件范围添加容器 div。

将条件值作为类添加到容器 div。(您可以通过服务器端编程设置它-php/asp...)

<!--container div-->
<div class="true-value">
<!-- your content -->
<p>my content</p>
<p>my content</p>
<p>my content</p>
</div>

现在,您可以使用嵌套选择器将容器类用作 div 中所有元素的全局变量,而无需将类添加到每个元素中。

.true-value p{
background-color:green;
}
.false-value p{
background-color:red;
}

如果您愿意使用 jquery,那么您可以在 html 中使用 javascript 设置条件语句:

$('.class').css("color",((Variable > 0) ? "#009933":"#000"));

如果变量的值大于 0,则 .class的文本颜色将更改为绿色。

你可以这样使用 javascript:

  1. 首先,为“普通”类和“活动”类设置 CSS
  2. 然后给你的元素 身份证‘ MyElement’
  3. 现在您可以使用 JavaScript 创建条件,类似下面的例子... (您可以运行它,将 myVar 的值更改为5,您将看到它是如何工作的)

var myVar = 4;


if(myVar == 5){
document.getElementById("MyElement").className = "active";
}
else{
document.getElementById("MyElement").className = "normal";
}
.active{
background-position : 150px 8px;
background-color: black;
}
.normal{
background-position : 4px 8px;
background-color: green;
}
div{
width: 100px;
height: 100px;
}
<div id="MyElement">
  

</div>

CSS 是一个设计得很好的范例,它的许多特性都没有得到很好的应用。

如果你所说的条件和变量是指一种机制,它将一些值的变化分布到整个文档中,或者在某个元素的作用域内,那么下面是如何做到这一点的:

var myVar = 4;
document.body.className = (myVar == 5 ? "active" : "normal");
body.active .menuItem {
background-position : 150px 8px;
background-color: black;
}
body.normal .menuItem {
background-position : 4px 8px;
background-color: green;
}
<body>
<div class="menuItem"></div>
</body>

通过这种方式,您可以将变量的影响分布到 CSS 样式中。 这类似于@amichai 和@SeReGa 的提议,但是更加通用。

另一个这样的技巧是在整个文档中分布一些活动项的 ID,例如,当突出显示一个菜单时: (使用 Freemarker 语法)

var chosenCategory = 15;
document.body.className = "category" + chosenCategory;
<#list categories as cat >
body.category${cat.id} .menuItem { font-weight: bold; }
</#list>
<body>
<div class="menuItem"></div>
</body>

当然,这只适用于有限的项目集,如类别或状态,而不适用于电子商店商品等无限的项目集,否则生成的 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;
}
<ul class="myList count${items.size()}">
<!-- Iterate list's items here -->
<li>Something...</div>
</ul>

你可以结合使用 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;
}

概念

我很惊讶没有人提到 CSS 伪类,它们在 CSS 中也是一种条件。您可以使用它做一些相当高级的事情,而不需要使用一行 JavaScript。

一些伪类:

  • : active-是否单击元素?
  • : check- 是否选中单选/复选框/选项? (这允许通过使用复选框进行条件样式设置!)
  • : void-元素是空的吗?
  • : 全屏-文档是否处于全屏模式?
  • : focus-元素是否具有键盘焦点?
  • : focus-inside-元素或其子元素是否具有键盘焦点?
  • : has ([ selector ])-元素是否包含与[ selector ]匹配的子元素? (遗憾的是,任何主流浏览器都不支持)
  • : hover-鼠标是否悬停在这个元素上?
  • : in-range/: out-of-range-输入值是否在最小值和最大值之间?
  • : 无效/: 有效-表单元素是否包含无效/有效的内容?
  • : 链接-这是一个未访问的链接吗?
  • : not ()-反转选择器。
  • : target-这个元素是 URL 片段的目标吗?
  • : 访问-用户以前访问过这个链接吗?

例如:

div { color: white; background: red }
input:checked + div { background: green }
<input type=checkbox>Click me!
<div>Red or green?</div>

更新:

我已经写了一篇关于下面的独特的方法在 CSS-技巧的进一步细节


我已经设计了下面的演示使用一个混合的技巧,允许 模拟 if/else场景的 有些人属性。任何本质上是数值的属性都是这种方法容易实现的目标,但是具有文本值的属性是。

此代码有3个 if/else场景,分别用于 opacitybackground colorwidth。所有3个都由两个布尔变量 bool和它的相反 notBool控制。

这两个布尔值是这个方法的 钥匙,要从非布尔动态值中获得布尔值,需要一些数学运算,幸运的是 CSS 允许使用 minmax函数。

显然,最近的浏览器版本支持这些函数(min/max) ,它们也支持 CSS 自定义属性(变量)。

var elm = document.querySelector('div')


setInterval(()=>{
elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
: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);
}
<div></div>

Another simple way using 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;
}
<label>
<input type='checkbox' hidden>
<div>Click to toggle width</div>
</label>

目前为止最好的:

我想出了一个 完全独一无二方法,它甚至更简单!

这个方法很酷,因为它很容易实现,也很容易理解。它是基于 animationstep()函数。

由于 bool可以很容易地计算为 01,这个值可以在 step中使用!如果只定义了一个步骤,那么就解决了 if/else问题。

使用关键字 forwards保持更改。

var elm = document.querySelector('div')


setInterval(()=>{
elm.style.setProperty('--width', Math.round(Math.random()*80 + 20))
}, 1000)
: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)) ;
}
<div></div>


I've found a Chrome bug which I have reported that can affect this method in some situations where specific type of calculations is necessary, but there's a way around it.

CSS 有一个特性: 条件规则。这个特性是基于一个特定的条件来应用的。 条件规则是:

  • @ 支持
  • @ media
  • @ document

句法:

@supports ("condition") {


/* your css style */


}

示例代码片段:

<!DOCTYPE html>
<html>
<head>
<title>Supports Rule</title>
<style>
@supports (display: block) {
section h1 {
background-color: pink;
color: white;
}
section h2 {
background-color: pink;
color: black;
}
}
</style>
</head>
<body>
<section>
<h1>Stackoverflow</h1>
<h2>Stackoverflow</h2>
</section>
</body>
</html> 

除了上面的答案之外,很快另一种直接使用类似于 if/else的条件,甚至与其他脚本语言更紧密结合的方法将是通过 @when/@else 条件句。实现这些条件是为了执行易于识别的逻辑链,例如:

@when supports(display: flex) {
.container {
display: flex
}
} @else media and (min-width: 768px) {
.container {
min-width: 768px
}
} @else {
.container {
width: 100%
}
}

截至2022年2月有 不支持浏览器。请参阅 这个 W3C 模块了解更多信息。