atlassian-labs / compiled

A familiar and performant compile time CSS-in-JS library for React.
https://compiledcssinjs.com
Apache License 2.0
1.98k stars 68 forks source link

Add media query sorting #1666

Closed dddlr closed 3 months ago

dddlr commented 4 months ago

Add a deterministic sorting to media queries and other at-rules in Compiled. We use a simplified version of what the sort-css-media-queries package does - sorting min-width and min-height from smallest to largest, then max-width and max-height from largest to smallest

We also merge the sort-at-rule-pseudos and sort-atomic-style-sheet postcss plugins into one, as they have a lot of overlap. Previously:

Now the two are one and the same. Technically when stylesheet extraction is not turned on, pseudo-selectors will get sorted twice: (1) pseudo-selectors are sorted as part of the aforementioned postcss plugin in the build stage, then (2) the pseudo-selector styles will get collated and organised into buckets (separate <style> elements) at runtime. This is necessary because step (1) only sorts the styles for a single component, not all the styles for the current page.

Limitations

Checklist

changeset-bot[bot] commented 4 months ago

🦋 Changeset detected

Latest commit: fc275af3f3f8652336dbb02503738b03065e1eb8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages | Name | Type | | ------------------------------------ | ----- | | @compiled/babel-plugin | Minor | | @compiled/css | Minor | | @compiled/webpack-loader | Minor | | @compiled/parcel-config | Minor | | @compiled/parcel-transformer | Patch | | @compiled/babel-plugin-strip-runtime | Minor | | @compiled/parcel-optimizer | Patch |

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

itsdouges commented 3 months ago

Over arching question before sending it: Should this be under a config option so we can turn it off just in case things go wrong?

As a follow up: What happens during runtime / non-extracted mode? If nothing, what about increasing specificity just during dev?

dddlr commented 3 months ago

Over arching question before sending it: Should this be under a config option so we can turn it off just in case things go wrong?

good point yeah @itsdouges i'll add that in a commit

As a follow up: What happens during runtime / non-extracted mode? If nothing, what about increasing specificity just during dev?

ah this is covered in the PR description, let me know if anything is unclear (i'm not aware of any practical way to increase specificity for media queries - @layer would decrease specificity for all Compiled styles compared to Emotion etc., and we can't know in advance how many :not(#\#) to add)

  • PostCSS plugins only act on the styles for a single component at a time. Media queries will lose their sorting when the styles of multiple components in the same page are concatenated together by @compiled/react/runtime.
    • This is not an issue when using Webpack, and extract: true is turned on for @compiled/webpack-loader. However, this is an issue for Parcel when in development mode, because stylesheet extraction is disabled in development mode there: https://github.com/atlassian-labs/compiled/issues/1306
    • ~Should we add a sorting step to @compiled/react/runtime too?~ I tested this with a toy example and looks like the postcss processing makes @compiled/react/runtime 100x slower... this doesn't seem to be worth it to me, so I didn't put any effort looking into it further. Happy to reconsider if y'all think it's worth the performance degradation.