【问题标题】:Can you use if/else conditions in CSS?你可以在 CSS 中使用 if/else 条件吗?
【发布时间】:2010-11-10 21:51:13
【问题描述】:

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

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

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

看起来像:

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

这可以吗?你是怎么做到的?

【问题讨论】:

    标签: css stylesheet conditional-statements


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 您可以将“PHP”替换为“您选择的编程或模板语言”
      • 问题是,如果你的 CSS 是 50kb,而你只是改变了几个值,那么静态和缓存不是更好吗?
      • 是的,但是您可以提取需要动态的部分并通过 @import url('dynamic.css.php') 重新包含它们。
      • 这取决于条件是什么。如果它们在每个用户的基础上是稳定的,您可以输出通常的缓存控制标头。
      【解决方案3】:

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

      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>
      

      【讨论】:

      • 很惊讶没有人指出 CSS 中不存在条件语法。条件 cmets 仅存在于 HTML 中。
      【解决方案4】:

      不是传统意义上的,但如果您可以访问 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 预处理器。你可以在那里使用conditionals,看起来像这样:

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

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


      CSS 本身的一个新特性是custom properties(又名 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;
      }
      

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

      【讨论】:

      • 好的答案,我只想补充一点关于缓存:由于浏览器缓存样式表并且通常不会为每个页面重新下载它们,因此很难依赖 PHP/[编程语言的选择]。这不是它应该工作的方式。如果您需要更改 CSS,当然可以将其嵌入到页面中,但这开始不利于内容/表示分离。
      • 关于 deceze 所说的,这并不意味着您不能拥有一个动态变化的网站。样式表可以保持静态,您可以使用带有或不带有 jquery 或 PHP 的 javascript 更改元素类,这样元素样式可以更改。
      • 还有,如果你想对滚动条进行风格化呢? (在 html 中找不到 ::-webkit-scrollbar-button)
      • 嗯,是吗?怎么样? Sass、CSS 变量和服务器端处理不依赖于 HTML。还是我在这里遗漏了什么?
      【解决方案5】:

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

      你可以放其中一个

      background-position : 150px 8px;
      

      在另一个

      background-position : 4px 8px;
      

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

      Conditional-CSS

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

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

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

            【讨论】:

              【解决方案9】:

              你可以用not代替if like

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

              【讨论】:

                【解决方案10】:

                您可以为所有条件范围添加容器 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;
                }
                

                【讨论】:

                  【解决方案11】:

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

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

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

                  【讨论】:

                    【解决方案12】:

                    您可以通过这种方式使用 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>

                    【讨论】:

                      【解决方案13】:

                      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>

                      【讨论】:

                      • 这太棒了!
                      【解决方案14】:

                      您可以将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;
                      }
                      

                      concept

                      【讨论】:

                      • 这是手动而不是自动if/else。应该假设变量可能随时更改并相应地执行if/else
                      【解决方案15】:

                      我很惊讶没有人提到 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>

                      【讨论】:

                      • 很棒的列表,但不包括自定义状态...因为我在根 html 元素上设置了一些自定义属性,所以我添加了 html[style*="--playerState:PAUSED"] 来补充一些自定义状态,可能也只是使用了数据集但是哦,好吧。
                      • @Endless: --playerState:PAUSED 不是有效的样式代码。您可以将其用作类值,或者使用data-playerState="Paused" 更好。
                      • 我知道,数据- === 数据集。但他们不会无缘无故地称其为自定义属性。如果我喜欢的话,至少我可以从 CSS 媒体查询中滥用它,如果我愿意,我可以覆盖 CSS 中的内容
                      • 你说得对,我还没有玩够自定义属性。听起来是个有趣的方法!
                      【解决方案16】:

                      更新:

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


                      我使用多种技巧设计了以下演示,它允许一些属性模拟if/else场景。任何本质上是数字的属性都可以轻松使用此方法,但具有文本值的属性是。

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

                      这两个布尔值是此方法的关键,并且要从非布尔动态值中获得布尔值,需要一些数学运算,幸运的是 CSS 允许使用 minmax 函数.

                      显然,这些函数(最小值/最大值)在最近的浏览器版本中受到支持,这些版本也支持 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);
                      }
                      &lt;div&gt;&lt;/div&gt;

                      另一种使用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)) ;
                      }
                      &lt;div&gt;&lt;/div&gt;

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

                      【讨论】:

                      • 为什么这不是这个页面上最受好评的帖子.....
                      • 这个,结合一些 SASS 使其更具可读性,是一个很好的解决方案
                      【解决方案17】:

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

                      • @supports
                      • @媒体
                      • @document

                      语法:

                      @supports ("condition") {
                      
                         /* your css style */
                      
                      }
                      

                      示例代码 sn-p:

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

                      【讨论】:

                        猜你喜欢
                        • 2022-08-18
                        • 2019-07-01
                        • 2019-04-25
                        • 2016-11-30
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-08-20
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多