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

如何用:has/:is/:where简化嵌套CSS,仅声明一次::before并按类设content?

使用:is/:where简化图例CSS代码

原代码

CSS

.legend__list {
  display: flex;
  border: 2px solid rgb(241, 230, 230);
  align-content: center;

  .legend {
    font-size: large;
    color: greenyellow;

    &.clan {
      &::before {
        content: "\1F9EC";
      }
    }

    &.deity {
      &::before {
        content: "\1FA94";
      }
    }

    &.cast {
      &::before {
        content: "\4DE4";
      }
    }
  }
}

dl {
  display: flex;
  margin: auto;
}

HTML

<div class="legend__list">
  <dl>
    <dt class="legend clan"></dt>
    <dd>Clan</dd>
  </dl>
  <dl>
    <dt class="legend deity"></dt>
    <dd>Deity</dd>
  </dl>
  <dl>
    <dt class="legend cast"></dt>
    <dd>Cast</dd>
  </dl>
</div>

需求说明

上述代码可正常运行,希望通过:has、:is或:where选择器优化CSS写法,让代码更简洁。你尝试了如下模拟写法,询问是否可行:

.legend {
  font-size: large;
  color: greenyellow;

  &::before {
    content: "";

    :has(.deity) {
      content: "\1F9EC";
    }

    :where(.clan) {
      content: "\1FA94";
    }

    :is(.cast) {
      content: "\4DE4";
    }
  }
}

问题分析与正确写法

你写的这段模拟代码没法正常工作,因为伪元素::before内部不能通过:has/:is/:where反向选择父元素的类。正确的做法是用:is或:where直接选中带不同后缀类的.legend元素,再给它们的伪元素设置对应内容:

方案1:用:is简化选择器

:is的权重和它包含的最高权重选择器一致,和原代码权重相同,不会影响样式优先级:

.legend__list {
  display: flex;
  border: 2px solid rgb(241, 230, 230);
  align-content: center;

  .legend {
    font-size: large;
    color: greenyellow;

    &:is(.clan)::before {
      content: "\1F9EC";
    }
    &:is(.deity)::before {
      content: "\1FA94";
    }
    &:is(.cast)::before {
      content: "\4DE4";
    }
  }
}

dl {
  display: flex;
  margin: auto;
}

方案2:更紧凑的写法(用:where)

如果不需要考虑权重,可以用:where替代:is,它的权重为0,写法逻辑和:is一致:

.legend__list {
  display: flex;
  border: 2px solid rgb(241, 230, 230);
  align-content: center;

  .legend {
    font-size: large;
    color: greenyellow;

    &::before {
      content: "";
    }

    &:where(.clan)::before {
      content: "\1F9EC";
    }
    &:where(.deity)::before {
      content: "\1FA94";
    }
    &:where(.cast)::before {
      content: "\4DE4";
    }
  }
}

dl {
  display: flex;
  margin: auto;
}

为啥不用:has?

:has是用来选择包含特定子元素的父元素,而这里我们要直接选中带特定类的.legend元素,用:has反而会增加代码复杂度,完全没必要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:34:52