Sass选择器间传递变量遇作用域限制,如何实现父变量给子选择器使用?
问题原因
你的写法不生效的核心原因是:Sass 变量是编译时变量,遵循块级作用域规则,在 #foo、#bar 块内定义的变量出了当前选择器块就会销毁,外部的 .prism 选择器在编译阶段根本读取不到这几个变量。且Sass编译完成后就不存在变量概念,无法实现运行时的上下文变量传递。
推荐解决方案
方案1:使用 Mixin 封装公共逻辑(兼容性最好)
把公共的 prism 样式逻辑封装成可接收参数的 mixin,在对应的 id 选择器内调用并传入专属参数,编译后会自动生成对应上下文的样式。
// 定义公共mixin,接收参数 @mixin prism-style($x1, $x2, $y1, $y2) { .prism .pane.x { width: calc(#{$x2} - #{$x1}); } .prism .pane.y { width: calc(#{$y2} - #{$y1}); } } // 对应id块内调用mixin,传入专属值 #foo { @include prism-style(25, 75, 95, 120); } #bar { @include prism-style(40, 63, 21, 103); }
方案2:使用CSS自定义属性(运行时继承,写法最简洁)
现代浏览器都支持原生CSS自定义属性(CSS变量),它是运行时继承的,完全符合你的预期写法,不需要依赖Sass的变量作用域:
#foo { --x1: 25; --x2: 75; --y1: 95; --y2: 120; } #bar { --x1: 40; --x2: 63; --y1: 21; --y2: 103; } .prism .pane.x { width: calc(var(--x2) - var(--x1)); } .prism .pane.y { width: calc(var(--y2) - var(--y1)); }
该方案仅不兼容IE11及更老版本浏览器,现代业务场景下优先推荐。
方案3:配置表循环生成(适合多实例场景)
如果后续还有更多同结构的容器,把所有配置存成Sass Map统一维护,循环生成样式更高效:
// 统一维护所有容器的参数 $prism-configs: ( foo: (25, 75, 95, 120), bar: (40, 63, 21, 103) ); // 循环生成所有样式 @each $id, $params in $prism-configs { ##{$id} { $x1: nth($params, 1); $x2: nth($params, 2); $y1: nth($params, 3); $y2: nth($params, 4); .prism .pane.x { width: calc(#{$x2} - #{$x1}); } .prism .pane.y { width: calc(#{$y2} - #{$y1}); } } }
内容的提问来源于stack exchange,提问作者user2009300
相关产品推荐
相关产品推荐

