Add media query sorting
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:
-
sort-atomic-style-sheetwas used in stylesheet extraction (creating thecompiled-css.cssstylesheet for the project) -- it sorted pseudo-selectors and now also sorts media queries. -
sort-at-rule-pseudosonly sorted pseudo-selectors that appeared inside at-rules (like@mediaqueries). It was used in conjunction with@compiled/react/runtimewhich organises the pseudo-selectors into buckets when stylesheet extraction is not turned on... each bucket being a separate<style>element, with one bucket for each pseudo-selector.
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
- 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: trueis 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/runtimetoo?~ I tested this with a toy example and looks like the postcss processing makes@compiled/react/runtime100x 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.
- This is not an issue when using Webpack, and
Checklist
- [x] Complete tests
- [x] Update
packages/css/src/plugins/sort-at-rule-pseudos.tsso that media query sorting isn't dependent on stylesheet extraction being turned on lol - [x] Determine whether it is worth it to have this running in
@compiled/react/runtimetoo?- My answer is: nah
- [x] Update snapshots
- [x] Better distinguis
packages/css/src/plugins/__tests__/sort-atomic-style-sheet.test.tsfrompackages/css/src/plugins/__tests__/sort-at-rules.test.ts - [x] Double-check that this works in an example app importing several
.compiled.cssstylesheets - [x] Improve docstrings for functions
- [x] Ensure that other at-rules are handled too (
@container) - [ ] Make PR to update Compiled website
- [ ] Detail the limitations around media query sorting when importing
.compiled.cssstylesheets, and when using Parcel in development mode (no stylesheet extraction) - [ ] Detail the limitations that atomic CSS and
@layershould not be used together, because our sorting can wreck@layerbehaviour
- [ ] Detail the limitations around media query sorting when importing
- [x] Add support for device-width, device-height
- [x] Add changeset
- [x] Verify that this doesn't crash for Atlassian products (platform, jira)
🦋 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
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?
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: trueis 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/runtimetoo?~ I tested this with a toy example and looks like the postcss processing makes@compiled/react/runtime100x 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.