You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否以HTML元素类为条件在SCSS中实现变量递增?

问题:能否用HTML元素的类作为SCSS/CSS逻辑判断条件?

我有一个动态下拉菜单,部分选项会添加.hidden类隐藏。每个选项包含按钮和hover时显示的.list元素,希望将所有非.hidden选项的.list元素对齐到底部,需为其设置基于父元素高度百分比的bottom样式,且仅对无.hidden类的元素递增计算变量值。

HTML结构如下:

<ul class="dropdown-menu components" role="dropdown">
    <li class="dropdown-item hidden"> <!-- 不递增$c -->
        <button class="btn icon"></button>
        <div class="list"></div>
    </li>
    <li class="dropdown-item">  <!-- $c = 4 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-400% - 2rem) -->
    </li>
    <li class="dropdown-item hidden"> <!-- 不递增$c -->
        <button class="btn icon"></button>
        <div class="list"></div>
    </li>
    <li class="dropdown-item">  <!-- $c = 3 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-300% - 2rem) -->
    </li>
    <li class="dropdown-item">  <!-- $c = 2 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-200% - 2rem) -->
    </li>
    <li class="dropdown-item hidden"> <!-- 不递增$c -->
        <button class="btn icon"></button>
        <div class="list"></div> 
    </li>
    <li class="dropdown-item"> <!-- $c = 1 -->
        <button class="btn icon"></button>
        <div class="list"></div>  <!-- bottom: calc(-100% - 2rem) -->
    </li>
</ul>

尝试了以下SCSS代码,但@for循环会忽略:not(.hidden)条件,每次迭代都递增$c:

$elements: 10;
$c:0;
@for $i from 0 to $elements {
    &:not(.hidden){
        $c: $c + 1;
        &:nth-last-child(#{$c}){
            .list{
                bottom: calc(calc(-100% * #{$c}) - 2rem);
            }
        }
    }
}

我知道可以用JavaScript实现,但希望仅通过SCSS/SASS实现纯CSS方案,请问是否可行?


解决方案

纯SCSS可以实现,但需要利用CSS的:has()伪类(注意浏览器兼容性),因为预编译的SCSS无法直接感知DOM中的类存在,必须通过CSS选择器筛选符合条件的元素。

实现代码

$max-items: 10; // 设置最大可能的非.hidden元素数量

@for $c from 1 through $max-items {
  $selector: '&:not(.hidden)';
  
  // 匹配从下往上第1个非.hidden元素(无后续非.hidden元素)
  @if $c == 1 {
    $selector: $selector + ':not(:has(~ &:not(.hidden)))';
  } 
  // 匹配从下往上第c个非.hidden元素(后续有c-1个非.hidden元素,且无第c个)
  @else {
    // 构建"后续有c-1个非.hidden元素"的条件
    $selector: $selector + ':has(';
    @for $i from 1 through $c - 1 {
      $selector: $selector + '~ &:not(.hidden)';
      @if $i < $c - 1 {
        $selector: $selector + ':has(';
      }
    }
    // 闭合所有:has(括号
    @for $i from 1 through $c - 1 {
      $selector: $selector + ')';
    }
    // 排除后续有第c个非.hidden元素的情况
    $selector: $selector + ':not(:has(';
    @for $i from 1 through $c {
      $selector: $selector + '~ &:not(.hidden)';
      @if $i < $c {
        $selector: $selector + ':has(';
      }
    }
    @for $i from 1 through $c {
      $selector: $selector + ')';
    }
  }

  #{$selector} {
    .list {
      bottom: calc(-#{$c} * 100% - 2rem);
    }
  }
}

代码说明

  1. 循环生成计数选择器:从c=1到设定的最大数量,为每个计数生成对应的CSS选择器
  2. 筛选非.hidden元素:通过:not(.hidden)排除隐藏项
  3. 精准计数:利用:has()伪类检测当前元素后续的非.hidden元素数量,确保只对从下往上的第c个非.hidden元素应用样式
  4. 动态适配:如果.hidden类是动态添加/移除的,CSS会自动重新匹配选择器,无需重新编译SCSS

兼容性说明

  • :has()伪类目前支持Chrome、Edge、Safari 15.4+;Firefox需要手动开启layout.css.has-selector.enabled配置
  • 如果需要兼容旧浏览器,纯CSS/SCSS方案无法实现,建议使用JavaScript辅助

内容的提问来源于stack exchange,提问作者Mironek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:24:23