File: selectors.md

package info (click to toggle)
node-stylus 0.54.5-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 5,392 kB
  • ctags: 913
  • sloc: makefile: 38
file content (342 lines) | stat: -rw-r--r-- 8,688 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
---
layout: default
permalink: docs/selectors.html
---

# Selectors

## Indentation

Stylus is "pythonic" (i.e. indentation-based). Whitespace is significant, so we substitute `{` and `}` with an _indent_, and an _outdent_ as shown below:

    body
      color white

Which compiles to:

    body {
      color: #fff;
    }

If preferred, you can use colons to separate properties and values:

    body
      color: white

## Rule Sets

Stylus, just like CSS, allows you to define properties for several selectors at once through comma separation.

    textarea, input
      border 1px solid #eee

The same can be done with a newline:

    textarea
    input
      border 1px solid #eee

Both compile to:

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

**The only exception to this rule** are selectors that look like properties. For example, the following `foo bar baz` might be a property **or** a selector:

    foo bar baz
    > input
      border 1px solid

So for this reason (or simply if preferred), we may trail with a comma:

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

## Parent Reference

The `&` character references the parent selector(s). In the example below our two selectors (`textarea` and `input`) both alter the `color` on the `:hover` pseudo selector. 

    textarea
    input
      color #A7A7A7
      &:hover
        color #000

Compiles to:

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

Below is an example providing a simple `2px` border for Internet Explorer utilizing the parent reference within a mixin:

      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

Yielding:

      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;
      }

If you'd need to use the ampersand symbol in a selector without it behaving like a parent reference, you can just escape it:

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

## Partial Reference

`^[N]` anywhere in a selector, where `N` can be a number, represents a partial reference.

Partial reference works similar to the parent reference, but while parent reference contains the whole selector, partial selectors contain only the first merged `N` levels of the nested selectors, so you could access those nesting levels individually.

The `^[0]` would give you the selector from the first level, the `^[1]` would give you the rendered selector from the second level and so on:

    .foo
      &__bar
        width: 10px

        ^[0]:hover &
          width: 20px

would be rendered as

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

Negative values are counting from the end, so ^[-1] would give you the last selector from the chain before `&`:

    .foo
      &__bar
        &_baz
          width: 10px

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

would be rendered as

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

Negative values are especially helpful for usage inside mixins when you don't know at what nesting level you're calling it.

* * *

Note that partial reference contain the whole rendered chain of selectors until the given nesting level, not the “part” of the selector.

### Ranges in partial references

`^[N..M]` anywhere in a selector, where both `N` and `M` can be numbers, represents a partial reference.

If you'd have a case when you'd need to get the raw part of the selector, or to get the range of parts programmatically, you could use ranges inside partial reference.

If the range would start from the positive value, the result won't contain the selectors of the previous levels and you'd get the result as if the selectors of those levels were inserted at the root of the stylesheet with the combinators omitted:

    .foo
      & .bar
        width: 10px

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

would be rendered as

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

One number in the range would be the start index, the second — the end index. Note that the order of those numbers won't matter as the selectors would always render from the first levels to the last, so `^[1..-1]` would be equal to the `^[-1..1]`.

When both numbers are equal, the result would be just one raw level of a selector, so you could replace `^[1..-1]` in a previous example to `^[-1..-1]`, and it would be equal to the same last one raw selector, but would be more reliable if used inside mixins.

## Initial Reference

The `~/` characters at the start of a selector can be used to point at the selector at the first nesting and could be considered as a shortcut to `^[0]`. The only drawback is that you can use initial reference only at the start of a selector:

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

Would be rendered as

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

## Relative Reference

The `../` characters at the start of a selector mark a relative reference, which points to the previous to the `&` compiled selector. You can nest relative reference: `../../` to get deeper levels, but note that it can be used only at the start of the selector.

    .foo
      .bar
        width: 10px

        &,
        ../ .baz
          height: 10px

would be rendered as

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

Relative references can be considered as shortcuts to the partial references with ranges like `^[0..-(N + 1)]` where the `N` is the number of relative references used.

## Root Reference

The `/` character at the start of a selector is a root reference. It references the root context and this means the selector won't prepend the parent's selector to it (unless you would use it with `&`). It is helpful when you need to write some styles both to some nested selector and to another one, not in the current scope.

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

Compiles to:

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

## selector() bif

You can use the built-in `selector()` to get the current compiled selector. Could be used inside mixins for checks or other clever things.

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

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

This bif could also accept an optional string argument, in this case it would return the compiled selector. Note that it wouldn't prepend the selector of the current scope in case it don't have any `&` symbols.

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

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

### Multiple values for `selector()` bif

`selector()` bif can accept multiple values or a comma-separated list in order to create a nested selector structure easier.

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

would be equal to the

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

and would be rendered as

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

## selectors() bif

This bif returns a comma-separated list of nested selectors for the current level:

    .a
      .b
        &__c
          content: selectors()

would be rendered as

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


## Disambiguation

Expressions such as `margin - n` could be interpreted both as a subtraction operation, as well as a property with an unary minus. To disambiguate, wrap the expression with parens:

    pad(n)
      margin (- n)

    body
      pad(5px)

Compiles to:

    body {
      margin: -5px;
    }

However, this is only true in functions (since functions act both as mixins, or calls with return values). 

For example, the following is fine (and yields the same results as above):

    body
      margin -5px

Have weird property values that Stylus can't process? `unquote()` can help you out:

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

Yields:

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