跳至内容

选择器

缩进

Stylus 是“pythonic”(即基于缩进)。空格很重要,因此我们使用缩进缩出替换 {},如下所示

body
  color white
body
  color white

编译为

body {
  color: #fff;
}
body {
  color: #fff;
}

如果愿意,可以使用冒号分隔属性和值

body
  color: white
body
  color: white

规则集

Stylus 就像 CSS 一样,允许你通过逗号分隔为多个选择器定义属性。

textarea, input
  border 1px solid #eee
textarea, input
  border 1px solid #eee

使用换行符也可以做到这一点

textarea
input
  border 1px solid #eee
textarea
input
  border 1px solid #eee

两者都编译为

textarea,
input {
  border: 1px solid #eee;
}
textarea,
input {
  border: 1px solid #eee;
}

此规则的唯一例外是看起来像属性的选择器。例如,以下 foo bar baz 可能是一个属性一个选择器

foo bar baz
> input
  border 1px solid
foo bar baz
> input
  border 1px solid

因此出于这个原因(或只是如果愿意),我们可以在后面加上一个逗号

foo bar baz,
form input,
> a
  border 1px solid
foo bar baz,
form input,
> a
  border 1px solid

父级引用

& 字符引用父选择器。在下面的示例中,我们的两个选择器(textareainput)都更改了 :hover 伪选择器上的 color

textarea
input
  color #A7A7A7
  &:hover
    color #000
textarea
input
  color #A7A7A7
  &:hover
    color #000

编译为

textarea,
input {
  color: #a7a7a7;
}
textarea:hover,
input:hover {
  color: #000;
}
textarea,
input {
  color: #a7a7a7;
}
textarea:hover,
input:hover {
  color: #000;
}

下面是一个示例,在 mixin 中使用父级引用为 Internet Explorer 提供简单的 2px 边框

box-shadow()
  -webkit-box-shadow arguments
  -moz-box-shadow arguments
  box-shadow arguments
  html.ie8 &,
  html.ie7 &,
  html.ie6 &
    border 2px solid arguments[length(arguments) - 1]

body
  #login
    box-shadow 1px 1px 3px #eee
box-shadow()
  -webkit-box-shadow arguments
  -moz-box-shadow arguments
  box-shadow arguments
  html.ie8 &,
  html.ie7 &,
  html.ie6 &
    border 2px solid arguments[length(arguments) - 1]

body
  #login
    box-shadow 1px 1px 3px #eee

生成

body #login {
  -webkit-box-shadow: 1px 1px 3px #eee;
  -moz-box-shadow: 1px 1px 3px #eee;
  box-shadow: 1px 1px 3px #eee;
}
html.ie8 body #login,
html.ie7 body #login,
html.ie6 body #login {
  border: 2px solid #eee;
}
body #login {
  -webkit-box-shadow: 1px 1px 3px #eee;
  -moz-box-shadow: 1px 1px 3px #eee;
  box-shadow: 1px 1px 3px #eee;
}
html.ie8 body #login,
html.ie7 body #login,
html.ie6 body #login {
  border: 2px solid #eee;
}

如果你需要在选择器中使用和符号,而不希望它像父级引用一样,你可以转义它

.foo[title*='\&']
// => .foo[title*='&']
.foo[title*='\&']
// => .foo[title*='&']

部分引用

选择器中的任何位置的 ^[N],其中 N 可以是数字,表示部分引用。

部分引用与父引用类似,但父引用包含整个选择器,而部分选择器仅包含嵌套选择器的第一个合并的 N 级,因此你可以单独访问这些嵌套级别。

^[0] 将为你提供第一级的选择器,^[1] 将为你提供第二级的呈现选择器,依此类推

.foo
  &__bar
    width: 10px

    ^[0]:hover &
      width: 20px
.foo
  &__bar
    width: 10px

    ^[0]:hover &
      width: 20px

将呈现为

.foo__bar {
  width: 10px;
}
.foo:hover .foo__bar {
  width: 20px;
}
.foo__bar {
  width: 10px;
}
.foo:hover .foo__bar {
  width: 20px;
}

负值从末尾开始计数,因此 ^[-1] 将为你提供 & 之前的链中的最后一个选择器

.foo
  &__bar
    &_baz
      width: 10px

      ^[-1]:hover &
        width: 20px
.foo
  &__bar
    &_baz
      width: 10px

      ^[-1]:hover &
        width: 20px

将呈现为

.foo__bar_baz {
  width: 10px;
}
.foo__bar:hover .foo__bar_baz {
  width: 20px;
}
.foo__bar_baz {
  width: 10px;
}
.foo__bar:hover .foo__bar_baz {
  width: 20px;
}

当你不知道在哪个嵌套级别调用它时,负值在 mixin 内部使用时特别有用。


请注意,部分引用包含到给定嵌套级别的选择器的整个呈现链,而不是选择器的“部分”。

部分引用中的范围

选择器中的任何位置的 ^[N..M],其中 NM 都可以是数字,表示部分引用。

如果你需要获取选择器的原始部分,或以编程方式获取部分范围,则可以在部分引用中使用范围。

如果范围从正值开始,则结果不会包含前一级的选择器,并且你会得到结果,就好像这些级别的选择器在样式表的根部插入,省略了组合器

.foo
  & .bar
    width: 10px

    ^[0]:hover ^[1..-1]
      width: 20px
.foo
  & .bar
    width: 10px

    ^[0]:hover ^[1..-1]
      width: 20px

将呈现为

.foo .bar {
  width: 10px;
}
.foo:hover .bar {
  width: 20px;
}
.foo .bar {
  width: 10px;
}
.foo:hover .bar {
  width: 20px;
}

范围中的一个数字是开始索引,第二个数字是结束索引。请注意,这些数字的顺序无关紧要,因为选择器总是从第一级呈现到最后一级,因此 ^[1..-1] 等于 ^[-1..1]

当两个数字相等时,结果将只是选择器的一个原始级别,因此你可以将前一个示例中的 ^[1..-1] 替换为 ^[-1..-1],它将等于最后一个原始选择器,但如果在 mixin 中使用,会更可靠。

初始引用

选择器开头的 ~/ 字符可用于指向第一个嵌套中的选择器,并且可以视为 ^[0] 的快捷方式。唯一的缺点是你只能在选择器的开头使用初始引用

.block
  &__element
    ~/:hover &
      color: red
.block
  &__element
    ~/:hover &
      color: red

将呈现为

.block:hover .block__element {
  color: #f00;
}
.block:hover .block__element {
  color: #f00;
}

相对引用

选择器开头处的 ../ 字符标记一个相对引用,它指向编译后的 & 选择器的上一个选择器。你可以嵌套相对引用:使用 ../../ 进入更深层级,但请注意,它只能用在选择器的开头。

.foo
  .bar
    width: 10px

    &,
    ../ .baz
      height: 10px
.foo
  .bar
    width: 10px

    &,
    ../ .baz
      height: 10px

将呈现为

.foo .bar {
  width: 10px;
}
.foo .bar,
.foo .baz {
  height: 10px;
}
.foo .bar {
  width: 10px;
}
.foo .bar,
.foo .baz {
  height: 10px;
}

相对引用可以看作是部分引用的快捷方式,其范围类似于 ^[0..-(N + 1)],其中 N 是使用的相对引用的数量。

根引用

选择器开头处的 / 字符是根引用。它引用根上下文,这意味着选择器不会将父选择器前置到它前面(除非你将它与 & 一起使用)。当你需要同时对某个嵌套选择器和另一个不在当前作用域内的选择器编写一些样式时,这很有用。

textarea
input
  color #A7A7A7
  &:hover,
  /.is-hovered
    color #000
textarea
input
  color #A7A7A7
  &:hover,
  /.is-hovered
    color #000

编译为

textarea,
input {
  color: #a7a7a7;
}
textarea:hover,
input:hover,
.is-hovered {
  color: #000;
}
textarea,
input {
  color: #a7a7a7;
}
textarea:hover,
input:hover,
.is-hovered {
  color: #000;
}

selector() bif

你可以使用内置的 selector() 来获取当前编译后的选择器。可以在 mixin 中使用它进行检查或其他巧妙的事情。

.foo
  selector()
  // => '.foo'

.foo
  &:hover
    selector()
  // '.foo:hover'
.foo
  selector()
  // => '.foo'

.foo
  &:hover
    selector()
  // '.foo:hover'

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

.foo
  selector('.bar')
// => '.bar'

.foo
  selector('&:hover')
// '.foo:hover'
.foo
  selector('.bar')
// => '.bar'

.foo
  selector('&:hover')
// '.foo:hover'

selector() bif 的多个值

selector() bif 可以接受多个值或逗号分隔的列表,以便更轻松地创建嵌套选择器结构。

{selector('.a', '.b', '.c, .d')}
  color: red
{selector('.a', '.b', '.c, .d')}
  color: red

将等于

.a
  .b
    .c,
    .d
      color: red
.a
  .b
    .c,
    .d
      color: red

并呈现为

.a .b .c,
.a .b .d {
  color: #f00;
}
.a .b .c,
.a .b .d {
  color: #f00;
}

selectors() bif

此 bif 返回当前级别的嵌套选择器的逗号分隔列表

.a
  .b
    &__c
      content: selectors()
.a
  .b
    &__c
      content: selectors()

将呈现为

.a .b__c {
  content: '.a', '& .b', '&__c';
}
.a .b__c {
  content: '.a', '& .b', '&__c';
}

消除歧义

诸如 margin - n 的表达式既可以解释为减法运算,也可以解释为具有单一减号的属性。要消除歧义,请用括号括住表达式

pad(n)
  margin (- n)

body
  pad(5px)
pad(n)
  margin (- n)

body
  pad(5px)

编译为

body {
  margin: -5px;
}
body {
  margin: -5px;
}

但是,这仅在函数中为真(因为函数既充当 mixin,又充当具有返回值的调用)。

例如,以下内容很好(并产生与上面相同的结果)

body
  margin -5px
body
  margin -5px

有 Stylus 无法处理的奇怪属性值?unquote() 可以帮助你

filter unquote('progid:DXImageTransform.Microsoft.BasicImage(rotation=1)')
filter unquote('progid:DXImageTransform.Microsoft.BasicImage(rotation=1)')

产生

filter progid:DXImageTransform.Microsoft.BasicImage(rotation=1)
filter progid:DXImageTransform.Microsoft.BasicImage(rotation=1)