如何用: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
相关产品推荐
相关产品推荐

