SCSS中如何基于嵌套子元素存在扩展父类样式?
问题:React组件结合SCSS实现子元素存在时为父元素添加样式
一、React组件渲染逻辑
{ isTopLevel ? ( <div className="top-level"> {hasChildren ? ( <div className="expand-icon"> <Icon /> </div> ) : null} </div> ) : null; }
二、当前SCSS代码
.top-level { margin: 0 $spacing-8 0 0; width: $spacing-16; height: $spacing-16; .expand-icon { cursor: pointer; @extend .header-column; background-color: red; } }
三、需求
- 当
.expand-icon存在时,将红色背景应用于.top-level - 了解如何从嵌套类(
.expand-icon)扩展父类(.top-level)的样式
四、解决方案
1. 子元素存在时为父元素添加样式
SCSS本身没有原生“父选择器”直接检测子元素存在,但可以用CSS的:has()伪类实现需求:
.top-level { margin: 0 $spacing-8 0 0; width: $spacing-16; height: $spacing-16; // 当.top-level包含.expand-icon时,添加红色背景 &:has(.expand-icon) { background-color: red; } .expand-icon { cursor: pointer; @extend .header-column; } }
注意::has()伪类支持绝大多数现代浏览器,若需兼容旧版浏览器,更稳妥的方式是在React组件中通过状态给父元素加额外类名:
{isTopLevel ? ( <div className={`top-level ${hasChildren ? 'has-expand-icon' : ''}`}> {hasChildren ? ( <div className="expand-icon"> <Icon /> </div> ) : null} </div> ) : null}
对应的SCSS代码:
.top-level { margin: 0 $spacing-8 0 0; width: $spacing-16; height: $spacing-16; // 通过额外类名实现样式切换 &.has-expand-icon { background-color: red; } .expand-icon { cursor: pointer; @extend .header-column; } }
2. 从嵌套类扩展父类样式
要让嵌套的.expand-icon继承父类样式,推荐把父类公共样式抽成占位符选择器(用%定义),方便复用:
// 定义父类公共样式占位符 %top-base-styles { margin: 0 $spacing-8 0 0; width: $spacing-16; height: $spacing-16; } .top-level { // 父类应用公共样式 @extend %top-base-styles; &:has(.expand-icon) { background-color: red; } .expand-icon { cursor: pointer; @extend .header-column; // 嵌套类继承父类公共样式 @extend %top-base-styles; } }
如果仅需复用部分属性值,也可以用变量存储避免重复:
// 定义可复用变量 $top-margin: 0 $spacing-8 0 0; $top-size: $spacing-16; .top-level { margin: $top-margin; width: $top-size; height: $top-size; &:has(.expand-icon) { background-color: red; } .expand-icon { cursor: pointer; @extend .header-column; // 复用变量值 margin: $top-margin; width: $top-size; height: $top-size; } }
内容的提问来源于stack exchange,提问作者tdranv
相关产品推荐
相关产品推荐

