stylus选择器 - selector()用法和使用场景

stylus选择器中的高阶用法用法selector() bif。常规用法,和&选择器的对比,函数用法和mixins用法。

语法

stylus内置的 selector() 函数,用于返回当前样式块的选择器字符串。所谓的当前指代的是运行时环境,方便进行动态样式生成或复用当前选择器。这为使用场景带来了很多有趣的可能性。

selector() 函数返回的是字符串,因此需要使用 {} 包裹才能作为选择器生效(Stylus 的插值语法)。

无参调用

用于获取当前样式块的选择器字符串,下面的例子中,当前样式块.foo .bar

1
2
3
4
5
.foo
.bar
{selector()} // selector() 返回 .foo .bar
color: #FFF
content: selector() // 此处选择器所在的样式块包含上面一个selector()生成的样式

编译后CSS

1
2
3
4
.foo .bar .foo .bar {
color: #fff;
content: '.foo .bar .foo .bar';
}

有参调用(一个参数)

这个 bif 还可以接受一个可选的字符串参数,在这种情况下它将返回编译后的选择器。请注意,如果当前作用域没有任何 & 符号,则不会在其前面添加选择器。

1
2
3
4
5
6
7
8
.foo
.bar
{selector('.para1')} // 等同于直接写 .para1
color: #FFF
.foo
.bar
{selector('&.para1')} // 在有&的情况下,&会被渲染成当前选择器环境 &.para1 => .foo .bar.para1
color: #FFF

编译后CSS

1
2
3
4
5
6
.foo .bar .para1 {
color: #fff;
}
.foo .bar .foo .bar.para1 {
color: #fff;
}

有参调用(多个参数)(不建议使用)

在传入多个参数时,将在当前样式块的选择器下,创建嵌套选择器结构

当前上下文选择器分别与每个参数组合后,再将所有组合结果串联(无空格拼接)

规则:(当前选择器 + 空格 + sel1) + (当前选择器 + 空格 + sel2) + ...(注意:是组合结果的直接拼接,而非后代 / 兄弟关系)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.foo
.bar
// .foo .bar .para1 + .foo .bar .para2
// => .foo .bar .para1 .para2
{selector('.para1', '.para2')}
color: #FFF
.foo
.bar
// .foo .bar.para1 + .foo .bar .para2
// .foo .bar.para1.foo .bar .para2
// 剔除错误css .foo .bar.para1<.foo .bar> .para2
// => .foo .bar.para1 .para2
{selector('&.para1', '& .para2')}
color: #FFF

.foo
.bar
// .foo .bar .para1 + .foo .bar.para2
// .foo .bar .para1.foo .bar.para2
// 剔除错误css .foo .bar .para1<.foo .bar>.para2
// => .foo .bar .para1.para2
{selector('& .para1', '&.para2')}
color: #FFF

编译后CSS

1
2
3
4
5
6
7
8
9
.foo .bar .foo .bar .para1 .para2 {
color: #fff;
}
.foo .bar .foo .bar.para1 .para2 {
color: #fff;
}
.foo .bar .foo .bar .para1.para2 {
color: #fff;
}

在stylus中,stylus会尝试修正无效语法,Stylus 不会主动 “优化” 合法选择器,只有当 selector() 多参数拼接后出现 不符合 CSS 语法规范的片段 时,才会触发自动修正。Stylus 修正的底层思路是 “尽量保留开发者想表达的样式语义,同时剔除导致语法错误的冗余片段”

selector() 多参数机制产生语法错误时,通过 “保留目标类名、剔除重复上下文” 的逻辑,尽量让样式能正常生效,避免编译失败。但这种修正并非 “设计特性”,而是对 “不推荐用法(滥用 selector() 多参数)” 的容错。

在上面的例子中,你可能发现了, selector() 在处理多个参数的过程中,出现了复杂的处理逻辑,最终编译后的css类明难以理解。

你不用去搞清楚其中的代码逻辑。

只是想说明,尽量不要使用selector() 多参数,优先用原生嵌套语法,让代码更易维护。

和&语法的对比

核心差异:& 是 “拼接符号”,selector() 是 “选择器字符串”

  • & 的本质:是一个 “选择器拼接标记”,用于将父选择器与子规则直接拼接,他只是一个静态替换。
  • selector() 的本质:是一个 “函数”,返回当前上下文的完整选择器字符串,它可以实现&的所有功能外,还可以基于上下文,动态生成“选择器字符串”,借助{}语法,生成选择器。

selector()使用场景

那,何时用 selector() 而不是 &

需要对选择器进行 “字符串级操作” 时

& 只能用于直接拼接选择器(如 &:hover 变成 .parent:hover),但无法对选择器进行拆分、拼接变量或复杂逻辑处理。而 selector() 返回字符串,支持所有字符串操作。

基于当前类.component生成一个新类名.theme-component

1
2
3
4
5
prefix = ".theme-"

.component
{prefix + replace("\.", "", selector())}
color: red

编译后CSS

1
2
3
.component .theme-component {
color: #f00;
}

需要在函数中 “动态生成选择器” 时

定义函数,在函数中根据调用环境,“动态生成选择器”

1
2
3
4
5
6
7
8
9
// 定义函数:为相同元素的兄弟节点添加间距
sibling-gap(gap)
{selector() + " + " + selector()} // 生成 "A + A" 选择器
margin-left: gap

// 使用函数
.btn
width: 100px
sibling-gap(10px) // 自动适配 .btn 选择器

编译后CSS

1
2
3
4
5
6
7
.btn {
width: 100px;
}
.btn .btn + .btn {
margin-left: 10px;
}

mixins混入用法

1
2
3
4
5
6
7
8
prefix = "theme-"

prefix-class()
namespace = replace("\.", "", selector())
--prefix-class: prefix + namespace

.component
prefix-class()

编译后CSS

1
2
3
.component {
--prefix-class: 'theme-component';
}

参考资料

选择器 | Stylus 中文网

nib - Stylus 的 CSS3 扩展

stylus选择器 - selector()用法和使用场景

https://blog.plcent.com/2025/10/05/stylus-docs-selector/

作者

Nolly

发布于

2025-10-05

更新于

2025-10-09

许可协议

评论