compiled icon indicating copy to clipboard operation
compiled copied to clipboard

Add media query sorting

Open dddlr opened this issue 1 year ago • 3 comments

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-sheet was used in stylesheet extraction (creating the compiled-css.css stylesheet for the project) -- it sorted pseudo-selectors and now also sorts media queries.
  • sort-at-rule-pseudos only sorted pseudo-selectors that appeared inside at-rules (like @media queries). It was used in conjunction with @compiled/react/runtime which 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: 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.

Checklist

  • [x] Complete tests
  • [x] Update packages/css/src/plugins/sort-at-rule-pseudos.ts so 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/runtime too?
    • My answer is: nah
  • [x] Update snapshots
  • [x] Better distinguis packages/css/src/plugins/__tests__/sort-atomic-style-sheet.test.ts from packages/css/src/plugins/__tests__/sort-at-rules.test.ts
  • [x] Double-check that this works in an example app importing several .compiled.css stylesheets
  • [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.css stylesheets, and when using Parcel in development mode (no stylesheet extraction)
    • [ ] Detail the limitations that atomic CSS and @layer should not be used together, because our sorting can wreck @layer behaviour
  • [x] Add support for device-width, device-height
  • [x] Add changeset
  • [x] Verify that this doesn't crash for Atlassian products (platform, jira)

dddlr avatar Apr 23 '24 06:04 dddlr

🦋 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

changeset-bot[bot] avatar Apr 23 '24 06:04 changeset-bot[bot]

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?

itsdouges avatar May 07 '24 03:05 itsdouges

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.

dddlr avatar May 08 '24 04:05 dddlr