159

我想在我的 CSS 中使用条件。

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

我想要它,以便根据这个变量改变样式表!

看起来像:

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

这可以做到吗?你怎么做到这一点?

4

17 回答 17

166

不是传统意义上的,但如果您可以访问 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的方法。


然后是像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;
  }
}

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


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;
}

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

于 2009-07-15T06:28:15.200 回答
25

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

一些伪类:

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

例子:

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

于 2019-10-20T19:34:53.743 回答
20

您可以calc()结合使用var()to 模仿条件:

: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;
}

概念

于 2017-12-20T16:08:45.420 回答
15

更新:

我写了一篇关于CSS-Tricks中以下独特方法的文章,其中更详细地介绍了


我使用混合技巧设计了下面的演示,它允许模拟 某些属性的if/else场景。本质上是数字的任何属性都是此方法的简单目标,但具有文本值的属性是。

此代码有 3 个if/else场景, for opacitybackground 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)
: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>

另一种简单的使用方法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>

迄今为止最好的:

我想出了一个完全独特的方法,甚至更简单!

这个方法很酷,因为它很容易实现也很容易理解。它基于animation step()功能。

因为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>


我发现了一个我报告的Chrome 错误,在某些需要特定类型的计算的情况下,它可能会影响此方法,但有一种解决方法。

于 2020-10-12T17:25:48.347 回答
14

以下是我的旧答案,它仍然有效,但我今天有一个更有主见的方法:

CSS 如此糟糕的原因之一就是它没有条件语法。CSS 本身在现代 Web 堆栈中完全不可用。使用 SASS 一会儿,你就会知道我为什么这么说。SASS 有条件语法……和原始 CSS 相比还有很多其他优点。


旧答案(仍然有效):

它通常不能在 CSS 中完成!

您有浏览器条件,例如:

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

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

我有时将 css 类作为字符串发送到视图并将它们回显到这样的代码中(php):

<div id="myid" class="<?php echo $this->cssClass; ?>">content</div>
于 2009-07-15T06:26:59.697 回答
7

您可以创建两个单独的样式表并根据比较结果包含其中一个

在其中一个你可以放

background-position : 150px 8px;

在另一个

background-position : 4px 8px;

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

条件 CSS

于 2009-07-15T06:33:23.520 回答
6

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>

于 2017-10-02T04:05:48.760 回答
5

你可以使用 not 代替 if like

.Container *:not(a)
{
    color: #fff;
}
于 2014-06-24T23:37:04.357 回答
4

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

当然,这假设您使用的是 PHP ...

于 2009-07-15T06:26:39.523 回答
3

这是上面 Boldewyn 答案的一些额外信息。

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

if($x==1){
  print "<p class=\"normal\">Text</p>\n";
} else {
  print "<p class=\"active\">Text</p>\n";
}
于 2009-07-15T06:56:28.777 回答
2

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

于 2009-07-15T06:24:14.677 回答
2

另一种选择(基于您是否希望动态评估该 if 语句)是使用 C 预处理器,如此所述。

于 2009-07-15T08:33:03.747 回答
2

您可以为所有条件范围添加容器 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;
}
于 2015-03-03T14:49:40.450 回答
2

为此,您可以使用 javascript,这样:

  1. 首先,您为“普通”类和“活动”类设置 CSS
  2. 然后你给你的元素id '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>

于 2016-09-19T07:51:58.967 回答
2

CSS 有一个特性:条件规则。CSS 的这一特性是根据特定条件应用的。条件规则是:

  • @支持
  • @媒体
  • @文档

句法:

@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> 

于 2020-10-13T12:21:31.817 回答
1

(是的,旧线程。但它出现在谷歌搜索之上,因此其他人可能也会感兴趣)

我猜 if/else-logic 可以用 javascript 来完成,而 javascript 又可以动态加载/卸载样式表。我没有在浏览器等上测试过这个,但它应该可以工作。这将使您开始:

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

于 2010-02-25T09:02:25.610 回答
0

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

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

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

于 2016-05-12T17:23:05.727 回答