/
githubmirror
/
webpack
Обзор
Документация
Войти
/
githubmirror
/
webpack
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/configCases/css/minimize-selectors/style.css
230 строк
10 KB
Alexander Akait
perf(css): write selectors, An+B and more values in their shortest spelling (#21664)
11 авг 2026, 13:43
Не верифицирован
11 авг 2026, 13:43
4015bbd
Код
Авторство
О чём код?
/* Ported from lightningcss's `test_selectors` / attribute-selector cases and cssnano's `postcss-minify-selectors` suite. webpack only normalizes selector *spelling* (whitespace and attribute-value quoting) — it never rewrites what a selector matches — so the `:nth-child()` rewrites lightningcss performs are here as passthroughs, marking where a future optimization would show up. */ /*! lightningcss: [foo="baz"] */ [foo="baz"] { color: red } /*! lightningcss: [foo="foo bar"] */ [foo="foo bar"] { color: red } /*! lightningcss: [foo="foo bar baz"] */ [foo="foo bar baz"] { color: red } /*! lightningcss: [foo=""] */ [foo=""] { color: red } /*! lightningcss: .test:not([foo="bar"]) */ .test:not([foo="bar"]) { color: red } /*! lightningcss: .test + .foo */ .test + .foo { color: red } /*! lightningcss: .test ~ .foo */ .test ~ .foo { color: red } /*! lightningcss: .test .foo */ .test .foo { color: red } /*! lightningcss: .test:not(.foo, .bar) */ .test:not(.foo, .bar) { color: red } /*! lightningcss: .test:is(.foo, .bar) */ .test:is(.foo, .bar) { color: red } /*! lightningcss: .test:where(.foo, .bar) */ .test:where(.foo, .bar) { color: red } /*! lightningcss: ::-webkit-slider-thumb:active */ .custom-range::-webkit-slider-thumb:active { color: red } /*! lightningcss: :nth-child(2n) */ :nth-child(2n) { width: 20px } /*! lightningcss: :nth-child(2n+1) */ :nth-child(2n+1) { width: 20px } /*! lightningcss: :nth-child(odd) */ :nth-child(odd) { width: 20px } /*! webpack: shorter than lightningcss, which keeps :nth-child(1) */ :nth-child(1) { width: 20px } /*! webpack: ...and the other three the same way */ :nth-last-child(1) { width: 20px } :nth-of-type(1) { width: 20px } :nth-last-of-type(1) { width: 20px } /*! lightningcss: :nth-child(even of li.important) */ :nth-child(even of li.important) { width: 20px } /*! lightningcss: :nth-child(1 of li.important) */ :nth-child(1 of li.important) { width: 20px } /*! lightningcss: :nth-col(10n-1) */ :nth-col(10n-1) { width: 20px } /*! lightningcss: :nth-last-col(-n+2) */ :nth-last-col(-n+2) { width: 20px } /* Cases beyond the upstream suites, covering what webpack's own printer decides. */ /*! webpack: every attribute matcher unquotes the same way */ [a~="baz"] { color: red } [a|="baz"] { color: red } [a^="baz"] { color: red } [a$="baz"] { color: red } [a*="baz"] { color: red } /*! webpack: the case-sensitivity modifier stays separated */ [a="baz" i] { color: red } [a="baz"i] { color: red } [a="a b" s] { color: red } /*! webpack: whitespace the `[…]` grammar allows anywhere is dropped */ [ a ] { color: red } [ a = b ] { color: red } [ a ^= 'b' i ] { color: red } /*! webpack: a value that is not one ident keeps its quotes */ [a="1px"] { color: red } [a="-1"] { color: red } [a="-"] { color: red } [a="a.b"] { color: red } [a="a\"b"] { color: red } /*! webpack: a value that is one ident loses them */ [a="--baz"] { color: red } [a="-baz"] { color: red } [a="a-b_c"] { color: red } /*! webpack: whitespace around a top-level combinator is insignificant */ .a > .b , .c ~ .d { color: red } /*! webpack: the descendant combinator is not */ :not(.e) .f { color: red } /*! webpack: a compound selector a dropped comment must not split */ .g/**/.h { color: red } /*! webpack: An+B carries its own sign, which says nothing */ .i:nth-child(+3) { color: red } /*! webpack: a `[…]` in a value is a grid line-name list, not a matcher */ .j { grid-template-columns: [full-start] 1fr [full-end] } /* Escapes in an identifier, and the whitespace a query condition does not need. Ported shapes: Tailwind writes every `2xl:` / `sm:` utility as an escape, and every breakpoint as a Media Queries Level 4 range. */ /*! webpack: an escape's terminator goes when the next code point cannot extend it */ .\32 xl\:flex { color: red } /*! webpack: ...but stays when the next code point is a hex digit */ .\31 abc { color: red } /*! webpack: ...and when it is the identifier's own end */ .\31 { color: red } /*! webpack: ...and when a real space follows it (a descendant combinator) */ .\32 x { color: red } /*! webpack: an escape that ends the identifier keeps the compound together */ .a\31 .b { color: red } /*! webpack: an escape needing no escape at all is written literally */ .\41 bc { color: red } /*! webpack: ...including a 6-digit one */ .\000041 bc { color: red } /*! webpack: ...but not where the code point cannot start an identifier */ .\31 x { color: red } /*! webpack: ...nor where it is not an identifier code point */ .\3a hover { color: red } /*! webpack: ...nor where it is non-ASCII (that would make the encoding matter) */ .\e9 x { color: red } /*! webpack: an identity escape is what makes the code point literal */ .a\:b { color: red } /*! webpack: an id keeps its escape when unescaping would unmake the ident */ #\31 abc { color: red } /*! webpack: an id unescapes like any other identifier */ #\41 bc { color: red } /*! webpack: a value's identifier unescapes too */ .t50 { font-family: \41 rial } /* `@scope`'s parentheses hold selector lists, not a query condition — a `:` there starts a pseudo-class, and the whitespace before it is a descendant combinator, so trimming it would change what the rule matches. */ /*! webpack: a descendant combinator before a pseudo-class in a scope root */ @scope (div :hover) { .t51 { color: red } } /*! webpack: ...and in a scope limit */ @scope (.a .b) to (.c :where(.d)) { .t52 { color: red } } /*! webpack: a combinator's own whitespace still goes */ @scope (div > p) to (span + em) { .t53 { color: red } } /*! webpack: a query condition still loses the whitespace around its `:` */ @media (min-width: 100px) { .t54 { color: red } } /*! webpack: ...and `@supports` keeps behaving as a condition */ @supports (color: red) { .t55 { color: red } } /*! lightningcss: .t56:before — Selectors 4 §3.3 keeps the one-colon spelling */ .t56::before { color: red } /*! lightningcss: .t57:after */ .t57::after { color: red } /*! lightningcss: .t58:first-line */ .t58::first-line { color: red } /*! lightningcss: .t59:first-letter */ .t59::first-letter { color: red } /*! lightningcss: .t60:hover:before */ .t60:hover::before { color: red } /*! lightningcss: .t61:before .t61:after — one rule, both collapse */ .t61::before .t61::after { color: red } /*! webpack: the name's case is the author's, only the colon goes */ .t62::BEFORE { color: red } /*! webpack: ::selection came after CSS2, so it has no one-colon spelling */ .t63::selection { color: red } /*! webpack: ...nor do ::placeholder, ::backdrop or a vendor pseudo-element */ .t64::placeholder, .t65::backdrop, .t66::-webkit-scrollbar { color: red } /*! webpack: a `selector()` condition is an at-rule prelude, left alone */ @supports selector(::before) { .t67 { color: red } } /*! lightningcss: :before — a compound already implies its universal selector */ *::before { color: red } /*! lightningcss: .t68 */ *.t68 { color: red } /*! webpack: an id or attribute qualifies the compound the same way */ *#t69, *[data-t70] { color: red } /*! webpack: parted from the compound it is a descendant combinator */ * .t71 { color: red } /*! webpack: ...and on its own it is the selector */ * { color: red } /*! webpack: a namespaced universal is not redundant */ svg|*, *|*.t72 { color: red } /*! webpack: whitespace between two type selectors is a descendant combinator, so the comment parting these stays as an empty one */ a/*c*/b { color: red } /*! webpack: adjacent rules printing the same block are the one rule they stand for */ .t71 { color: red } .t72 > .t73 { color: red } /*! webpack: ...and a keyframe selector list is one too */ @keyframes t74 { 0% { color: red } 50% { color: red } } /*! webpack: the same selector twice is one rule */ .t80 { color: red } .t80 { margin: 0 } /*! webpack: ...and two identical rules are the one that can be read */ .t81 { color: red } .t81 { color: red } /*! declined: the earlier declaration of a property both set would be lost */ .t82 { color: red } .t82 { color: blue } /*! declined: a shorthand holds every longhand its name prefixes */ .t83 { background: red } .t83 { background-image: none } /*! declined: declarations after a nested rule are an implicit `&` rule */ .t84 { color: red; &:hover { top: 0 } } .t84 { margin: 0 } /*! webpack: a selector list is a set, so one order lets equal lists compare */ .t90b, .t90a { color: red } /*! webpack: ...and a repeat in it matches nothing the first did not */ .t91, .t91, .t92 { color: red } /*! webpack: ...which is what lets two rules naming one set become one rule */ .t93, .t94 { color: red } .t94, .t93 { margin: 0 } /*! declined: only the list's own commas split it */ :is(.t96, .t95) .t97, .t98 { color: red } .t99[title="b,a"], .t99a { color: red } /*! webpack: `An+B` carries its own whitespace, signs and case */ .t100:nth-child(2N + 1) { color: red } .t101:nth-child( +3 ) { color: red } .t102:nth-child(0n+3) { color: red } /*! webpack: ...an index under 1 matches nothing, so the step starts where it does */ .t103:nth-child(2n-1) { color: red } .t104:nth-child(3n-2) { color: red } .t105:nth-child(2n+2) { color: red } /*! webpack: ...`even` is longer than the step it names, `odd` shorter */ .t106:nth-child(even) { color: red } .t107:nth-child(odd) { color: red } /*! webpack: ...and a step selecting one child is the child that has a name */ .t108:nth-child(1) { color: red } .t109:nth-last-of-type(1) { color: red } /*! declined: a backward step never sweeps past what it started on */ .t110:nth-child(-n+3) { color: red } /*! declined: `An+B of S` selects among S, which no plain spelling names */ .t111:nth-child(1 of .t112) { color: red } /*! webpack: a selector function's argument is a selector, so the universal a compound implies says nothing there either */ .t113:not(*.t114) { color: red } .t115:is(*.t116, *.t117) { color: red } /*! declined: a lone universal is the selector, and a parted one is a combinator */ .t118:not(*) { color: red } .t119:not(* .t120) { color: red } /*! declined: a namespaced universal is not redundant */ .t121:not(*|*.t122) { color: red }