/
githubmirror
/
webpack
Обзор
Документация
Войти
/
githubmirror
/
webpack
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/configCases/css/minimize-declined/style.css
101 строка
6 KB
Alexander Akait
feat(css): join adjacent rules and fold more value spellings (#21648)
10 авг 2026, 08:55
Не верифицирован
10 авг 2026, 08:55
3197f80
Код
Авторство
О чём код?
/* Transforms the other CSS minifiers make and webpack does not, each with the reason. Measured against esbuild, csso, clean-css, lightningcss and cssnano on Bootstrap and Tailwind (`yarn benchmark:css-minifiers`). Rounding, unit conversion and a hex alpha used to be here too. Each was measured against headless Chromium — 682 of Bootstrap's and Tailwind's own rewritten declarations, and all 256 alpha bytes, computing identically — and moved out, so what is left is the set that changes a value rather than its spelling. Every case here is a passthrough. A snapshot entry that stops being one means webpack started making the trade, which is a decision, not a detail. */ /*! declined here only because this case builds for no particular target — with `output.environment.cssColorHexAlpha` false it stays, and otherwise it is `#0000` (see the `minimize-environment` case) (lightningcss: #0000) */ .t05 { background-color: transparent } /*! declined here only because this case builds for no particular target — with `output.environment.cssMediaQueryRange` false it stays, and otherwise it is `(width>=1200px)` (see the `minimize-environment` case) */ @media (min-width: 1200px) { .t06 { color: red } } /*! declined: a declaration between them that writes the same family would be stepped over by the merge — `mdn-data` maps `margin-top` back to `margin` alone, so the whole `margin*` prefix is blocked rather than trusted */ .t07 { margin-top: 1px; margin-right: 2px; margin-inline: 9px; margin-bottom: 1px; margin-left: 2px } /*! declined: `bolder` and `lighter` are relative to the parent's weight, so they have no fixed number (lightningcss: bolder) */ .t08 { font-weight: bolder } /*! declined: `getPropertyValue()` hands a custom property's value back as written, so respelling it builds a different CSSOM from the same document — what `SyntaxBrowserEquivalence` checks (lightningcss: .5rem) */ .t10 { --radius: 0.5rem } /*! declined: ...including the unit (cssnano: .5s) */ .t11 { --duration: 500ms } /*! declined: a `*` parted from the compound is a descendant combinator, not a redundant universal selector (every tool keeps this one) */ * :before { color: red } /*! declined: a substitution can expand to the second component `translateX` rejects, so converting it would revive a dropped declaration (lightningcss: translate) */ .t12 { transform: translateX(var(--x)) } /*! declined: a `/*!` banner is kept, as cssnano, csso and clean-css also do (lightningcss drops it) */ .t13 { color: red } /*! declined: a rule between two that share a block, so joining them reorders the cascade (csso, cssnano) */ .t14 { color: red } .t14b { color: blue } .t15 { color: red } /*! declined: a pseudo may be one the engine cannot parse, which would invalidate the whole list */ .t16:hover { color: red } .t17:hover { color: red } /*! declined: a nested rule's `&` would become the list, and `:is()` takes its most specific selector */ .t18 { color: red; & i { color: blue } } .t19 { color: red; & i { color: blue } } /*! declined: not identical, so the first is a fallback for an engine that cannot read the second — dropping it is how esbuild and lightningcss lose this pair (csso, cssnano and clean-css keep it too) */ .t16 { color: #fff; color: color(display-p3 1 1 1) } /*! declined: inside `calc()` a bare `0` is a `<number>`, so the expression stops parsing (every tool keeps this one) */ .t18 { width: calc(0px + 1px) } /*! declined: a channel landing on a `.5` boundary is the one place engines disagree — this one's blue is exactly 93.5 (cssnano: #40bf5e) */ .t19 { background: hsl(134, 50%, 50%) } /*! declined: the same, and the case esbuild and lightningcss answer differently (esbuild: #00c3ff, lightningcss: #00c4ff — headless Chromium says #00c3ff) */ .t20 { background: hwb(194 0% 0%) } /*! declined: outside the sRGB gamut, so a hex would clip it to a different color rather than respell the same one */ .t20a { background: lab(50% 100 -100) } /*! declined: ...and in the Lab family a channel within 0.1 of a boundary, since webpack's matrix chain and the engine's disagree by up to 0.035 of a byte */ .t20b { background: lab(20% 40 0) } /*! merge-longhand: a duplicate declaration resolves to the last of them */ .t21 { color: red; color: red } /*! ...whatever stands between */ .t22 { color: red; background: blue; color: red } /*! ...and however the earlier one was spelled */ .t23 { color: #FF0000; color: red } /*! ...including a custom property */ .t24 { --x: 1; --x: 1 } /*! declined: a nested rule parts the declarations around it into their own rules, so the first is read at its own place rather than resolving to the second — dropping it loses a rule the engine builds */ .t24b { color: red; & i { top: 0 } color: red } /*! declined: the importance differs, so they are not the same declaration */ .t25 { color: red; color: red !important } /*! declined: a prefixed spelling is a different property */ .t26 { display: -webkit-flex; display: flex } /*! declined: a `@supports` condition is the declaration being tested, so rewriting its value asks a different question — the engines that read `#0000` are not the ones that read `rgba(0,0,0,0)` (esbuild, clean-css and lightningcss leave it alone too; csso rewrites it) */ @supports (color: rgba(0, 0, 0, 0)) { .t27 { color: red } } /*! declined: ...at any nesting depth, and under `not` */ @supports not ((color: rgb(0, 0, 0)) and (color: hsl(0, 100%, 50%))) { .t28 { color: red } } /*! declined: the two blocks join, but the rules meeting at their seam print different blocks — the seam pair is held to the same rules as any adjacency */ @media (min-width: 500px) { .t29 { top: 0 } } @media (min-width: 500px) { .t30 { color: red } } /*! declined: ...and a seam rule holding a nested rule would be re-parented */ @media (min-width: 600px) { .t31 { top: 0; & i { top: 1px } } } @media (min-width: 600px) { .t32 { top: 0; & i { top: 1px } } }