Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

☂️ CSS Formatter #1285

Open
8 of 11 tasks
faultyserver opened this issue Dec 21, 2023 · 34 comments
Open
8 of 11 tasks

☂️ CSS Formatter #1285

faultyserver opened this issue Dec 21, 2023 · 34 comments
Assignees
Labels
A-Formatter Area: formatter L-CSS Language: CSS

Comments

@faultyserver
Copy link
Contributor

faultyserver commented Dec 21, 2023

Description

This issue will act as the hub for tracking the CSS formatter as it gets built out. Listed here are all of the different pieces that will need to be implemented to get "complete" support in place. For the most part, this means compatibility with Prettier, and the implementations will inevitably take on the same shape, but we are not currently aiming for perfect parity with Pretttier, as their implementation and tests lean heavily into PostCSS and other facets that we are not yet ready to support.

How to Contribute

Everyone is welcome to contribute pieces here! If you'd like to tackle something, please leave a comment below this issue for which item(s) of the checklist below you'd like to pick up. We will create a separate issue and assign it to you to simplify tracking.

Note

In order to have the issue assigned to you, you must comment on this issue.

When choosing an item to work on, there are often various pieces that will fit together or be dependent on each other, like attribute_selector requires attribute_name, attribute_matcher, and attribute_matcher_value to be implemented at the same time to get full support.

Also, please only pick a single piece or group to work on at a time, and try to have time available to work on the piece when you select it so that we can keep progressing quickly. If you need any help or have any questions about how to implement formatting in Biome, feel free to ask in the dev-formatter channel in Discord.

Testing

We don't currently have Prettier tests for the CSS formatter, again because much of Prettier's implementation focuses on supporting PostCSS, beyond just standard CSS that Biome supports currently. Instead, please add spec tests under crates/biome_css_formatter/test/specs/css for the feature you are working on. For the most part, Prettier's CSS tests do provide a lot of coverage and examples to pull from.

Node Checklist

The CSS Parser is still in progress, so the set of nodes that need to be formatted is constantly changing. All of the current nodes have been implemented, but as new ones are added, they will need to be formatted as well. Since it's moving so quickly, the list won't be updated here. Instead, there are a number of other general things that need support, listed below.

Once the parser reaches a mostly complete and stable state, we will flesh out the list of remaining types that need formatting support and add them here.

Features and bug fixes

These are features, bug fixes, and other adjustments that need to be made to the formatter to get closer to parity with Prettier.

Formatting Infrastructure

Listed here are various things that are ready to be implemented or fixed that apply to the CSS formatter in general.

Testing:

  • Add usable Prettier tests (ignoring postcss syntax)

Releasability

These tasks need to be completed for the CSS formatter to be "publicly available" and on-par with the JS formatter.

  • Support CSS files in the playground
  • Support CSS configuration options in the playground
  • Enable/remove the can_format_css_yet flag from biome_service.
@faultyserver
Copy link
Contributor Author

faultyserver commented Dec 21, 2023

I'm working on Comment Placement now

@ematipico ematipico added A-Formatter Area: formatter L-CSS Language: CSS labels Dec 22, 2023
0xdevalias added a commit to 0xdevalias/chatgpt-source-watch that referenced this issue Jan 5, 2024
0xdevalias added a commit to 0xdevalias/chatgpt-source-watch that referenced this issue Jan 5, 2024
0xdevalias added a commit to 0xdevalias/chatgpt-source-watch that referenced this issue Jan 5, 2024
@ematipico ematipico pinned this issue Jan 5, 2024
@tom-sherman
Copy link
Contributor

tom-sherman commented Jan 5, 2024

Is this the first step in implementing a CSS linter? Or could that be worked on in parallel? (the parser code seems pretty fleshed out already to my naked eye)

@denbezrukov
Copy link
Contributor

Is this the first step in implementing a CSS linter? Or could that be worked on in parallel? (the parser code seems pretty fleshed out already to my naked eye)

The issue is only related to CSS formatting. I believe that the linter and formatter can work in parallel.
Meanwhile, the parser is still under development (the cst nodes aren't stable and can be changed).

Any help is welcome!

@faultyserver
Copy link
Contributor Author

Agreed, the parser is pretty far along, but there will be many changes before it can effectively lint full CSS files (for example, we're adding parsing for exact properties now, and each one will have a new node type, so writing lints for them now would require rewriting them entirely later on).

0xdevalias added a commit to 0xdevalias/chatgpt-source-watch that referenced this issue Jan 6, 2024
0xdevalias added a commit to 0xdevalias/chatgpt-source-watch that referenced this issue Jan 7, 2024
@itsjavi
Copy link

itsjavi commented Jan 8, 2024

I guess this is only about a pure CSS formatter, but what are your plans/thoughts about SCSS?

@faultyserver
Copy link
Contributor Author

what are your plans/thoughts about SCSS?

It's unlikely that we'll add any non-standard CSS dialects in the short term. SCSS and other dialects like Less and even PostCSS end up diverging pretty far from standard CSS and require very different parsing to handle all of their extensions to the language syntax (e.g., mixins in sass and less, @value in postcss, and so on). Additionally, these dialects have different behavior and rules for the same syntax that ends up being added in future CSS specifications, which makes it more difficult to support them all at the same time.

We may consider adding some support in the future, but for the forseeable future we will be focusing on supporting all of latest, standard CSS.

@finnan444
Copy link

BTW if sass is not supported why in documentation css super languages are mentioned?
--css-formatter-enabled=<true|false> — Control the formatter for CSS (and its super languages) files.

@KurtGokhan
Copy link

In my opinion, no amount of new CSS features will be enough to replace Sass completely. For me, Sass is more useful for having a modular code structure. It is like a missing piece between the CSS and the bundler. Although Tailwind and other no-CSS libraries are quite popular lately, I think Sass is still the best tool for anyone writing their own design system.

But I understand it expands the scope a lot. So maybe it can be added as a plugin later (not sure if plugin system will support this), or it can have a minimal set of features (quotes, spacing, no prettier compatibility).

@Netail
Copy link
Contributor

Netail commented Jul 1, 2024

In my opinion, no amount of new CSS features will be enough to replace Sass completely. For me, Sass is more useful for having a modular code structure. It is like a missing piece between the CSS and the bundler. Although Tailwind and other no-CSS libraries are quite popular lately, I think Sass is still the best tool for anyone writing their own design system.

But I understand it expands the scope a lot. So maybe it can be added as a plugin later (not sure if plugin system will support this), or it can have a minimal set of features (quotes, spacing, no prettier compatibility).

Fully agree on this one, it could be a plugin or like jsonc options within the base language (in this case css)

@spartanatreyu
Copy link

In my opinion, no amount of new CSS features will be enough to replace Sass completely. For me, Sass is more useful for having a modular code structure. It is like a missing piece between the CSS and the bundler. Although Tailwind and other no-CSS libraries are quite popular lately, I think Sass is still the best tool for anyone writing their own design system.

But I understand it expands the scope a lot. So maybe it can be added as a plugin later (not sure if plugin system will support this), or it can have a minimal set of features (quotes, spacing, no prettier compatibility).

Just curious, what parts of Sass are you using, or what makes it the best for someone writing their own design system?

@itsjavi
Copy link

itsjavi commented Jul 24, 2024

The facts that Sass is adopting standard CSS nesting rules, and that functions/mixins are coming to CSS are good reasons enough to focus only on CSS.

So because how everything is evolving, I think Biome should only focus on CSS.

Then you have PostCSS to cover everything else. But I understand it's a matter of preferences at the end.

@ematipico
Copy link
Member

In my opinion, no amount of new CSS features will be enough to replace Sass completely. For me, Sass is more useful for having a modular code structure. It is like a missing piece between the CSS and the bundler. Although Tailwind and other no-CSS libraries are quite popular lately, I think Sass is still the best tool for anyone writing their own design system.

But I understand it expands the scope a lot. So maybe it can be added as a plugin later (not sure if plugin system will support this), or it can have a minimal set of features (quotes, spacing, no prettier compatibility).

It was mostly a scope decision. Writing a CSS recoverable parser isn't an easy task, so we wanted to be realistic and start small. We will consider SASS down the line once our base CSS parser is more stable.

@conioX
Copy link

conioX commented Jul 31, 2024

can we add support for emotion or styled component?

@ematipico
Copy link
Member

@conioX that's called embedded formatting, which is tracked in a separate issue

@aberba
Copy link

aberba commented Aug 2, 2024

@conioX that's called embedded formatting, which is tracked in a separate issue

Where is it being tracked?

@uncenter
Copy link
Contributor

uncenter commented Aug 2, 2024

@conioX that's called embedded formatting, which is tracked in a separate issue

Where is it being tracked?

A quick issue search finds #3334.

@ashishsurya
Copy link

I saw that recently biome added support for CSS, does that mean SCSS is also supported
@ematipico

@matthiask
Copy link

@ashishsurya No, CSS is supported, SCSS isn't.

@ashishsurya
Copy link

@ashishsurya No, CSS is supported, SCSS isn't.

Is that on the way or still in the Roadmap? @matthiask

@vohoanglong0107
Copy link
Contributor

@ashishsurya It's not on the roadmap yet. We would consider it once CSS parser is stable enough.

@Netail
Copy link
Contributor

Netail commented Sep 21, 2024

@ashishsurya It's not on the roadmap yet. We would consider it once CSS parser is stable enough.

Would love that, don't see scss usage lowering any time soon.

@spartanatreyu
Copy link

spartanatreyu commented Sep 24, 2024

Would love that, don't see scss usage lowering any time soon.

SCSS usage is already lowering right now.

Looking at the last 5 years of usage, it reached its peak in 2017 and usage remained plateaued until early 2023. It's been declining ever since.

Most of SCSS's features are already widely supported in CSS. Some have been subsumed by newer more powerful CSS features. The majority of new projects don't need to reach for SCSS any more, and legacy projects are migrating away from it to speed up build times.

The last niche advantages of SCSS appear to be conditionals, loops, and mixins. But all 3 of them have current workarounds today and active css extension proposals getting worked out with current and future concerns in mind.

Those that would be working on adding new major features to SCSS are focussing instead on adding those features to CSS instead.

@Netail
Copy link
Contributor

Netail commented Sep 24, 2024

SCSS usage is already lowering right now.

No it's not

Screenshot 2024-09-24 at 09 39 49

As @KurtGokhan mentioned;

In my opinion, no amount of new CSS features will be enough to replace Sass completely. For me, Sass is more useful for having a modular code structure. It is like a missing piece between the CSS and the bundler. Although Tailwind and other no-CSS libraries are quite popular lately, I think Sass is still the best tool for anyone writing their own design system.

But I understand it expands the scope a lot. So maybe it can be added as a plugin later (not sure if plugin system will support this), or it can have a minimal set of features (quotes, spacing, no prettier compatibility).

For big organisations working with design systems it's still a good choice as a tool between CSS & the bundler. e.g. Maps, sets, functions, mixins, looping. And yes CSS is slowly catching up, but I doubt it will replace sass within the upcoming 2 years.

@spartanatreyu
Copy link

spartanatreyu commented Sep 24, 2024

SCSS usage is already lowering right now.

No it's not

It actually is. Long winded explanation in this expanding section

You've made a few statistics mistakes.

  1. You're using npmtrends.com which is fine, but you need to zoom out to see the trend properly. Set it as far out as you can.
  2. You need to look at more than just the sass package, you also need to add node-sass to the graph to get the real historical usage. https://npmtrends.com/node-sass-vs-sass
    • just remember to zoom out again, they don't include the zoom levels in their urls
  3. You'll need to switch the y-axis from linear to logarithmic. npmtrends doesn't do this, but npmcharts does. Here's a link here: https://npmcharts.com/compare/sass,node-sass?interval=90&start=5000&log=true
    • Why? Because popularity works on a logarithmic scale. It's much harder for a project with only 1 million total downloads to get to 2 million total downloads then it is for a project to get from 10 million total downloads to 11 million total downloads. Even though the difference between both pairs of numbers is 1 million, the additional growth is 100% vs 10%.
    • Note, I've set the interval to 90 days to smooth out the weird stuff that happens during the xmas holidays.
  4. You need to add both curves together to get the real usage curve. That real curve is what we're looking at going forwards.
  5. Now we need to look at the tangent along the curve.
  6. What we can see is that the growth was small, then it accelerated a lot, and then it decelerated a lot but is still moving up ever so slightly.
  7. So this means that scss usage is still going up right? No, it specifically means that downloads are going up, there is a difference. Since there's no official usage stats, we've been looking at downloads this whole time to try and glean the usage. When a person install scss, the download counter ticks up. But that's not the only time it ticks up. There's a whole bunch of github actions and other ci/cd jobs downloading scss that we need to consider. If every single developer stopped installing scss today, then tomorrow's download stats would still be higher, because we didn't alter or disable all those ci/cd jobs that are still getting triggered when people make other changes to their projects as well.
  8. So putting it all together, we need to add curves in a logarithmic scale and take a ci/cd bias into account to see if the usage is growing or shrinking. We can see by eye that it's shrinking. But looking at the numbers to confirm, the curve of the sass library for the last year has 5.33% growth, plus the curve of the node-sass library for the last month has -14.76% growth for a total growth of -9.43%. Then that number gets even smaller when we remember that we need to subtract all the ci/cd jobs downloading it.

Conclusion: SCSS usage is falling.


In my opinion, no amount of new CSS features will be enough to replace Sass completely.

What if the features you use overlap?

What would be the purpose of using Sass at that point?

For me, Sass is more useful for having a modular code structure.

Sass and modular code are unrelated to each other. You can have non-modular sass, modular sass, non-modular css, and modular css. You just use your filesystem and your import method of choice. (e.g. Sass' @use and CSS' @import)

I think Sass is still the best tool for anyone writing their own design system. [...]
For big organisations working with design systems it's still a good choice as a tool between CSS & the bundler. e.g. Maps, sets, functions, mixins, looping.

Well my dinner's ready now so I'll have to rush past the rest of this.

Most designs systems written a few years ago used scss because its maps/sets/functions/mixins/loops were the best way to do what we wanted, which was making certain tasks easily and programmatically tweakable. For example:

  • Make a bunch of shades of certain colors
  • Create a typographic scale
  • Make a named set of viewport size based modifiers.

But now, we have better ways:

  • We can use custom properies and oklch() to make our shades (or you can use postcss if you want to both use modern relative color syntax and support older browsers).
  • We can use clamp(), em/rem, and viewport units to make a better more fluid typographic scales.
  • We can use intrinsic design principles and container queries rather than the outdated notion of sm, md, lg, xl modifiers.

There's a lot more I could write about not needing to design things using techniques built on assumptions that no longer hold true, but I'm getting quite hungry now.

@nemchik
Copy link

nemchik commented Sep 24, 2024

New to this thread but just wanted to express interest in scss support for a different reason: legacy projects.

"One toolchain for your web project" hopefully doesn't have to mean "One toolchain for your new web project".

I'm not a frontend dev, I do mostly backend and devops, but I often help other teams with tooling, configuration, and standardization. So far I love biome for new projects, but it's not a drop in replacement for existing tooling and configuration in every existing project yet. I'd love to bring biome into every project, new and old.

I think plugins would be a fine solution as well, once we have them.

Anyway I appreciate all the work being done on biome and the care being put into making it great. Thank you!

@ashishsurya
Copy link

New to this thread but just wanted to express interest in scss support for a different reason: legacy projects.

"One toolchain for your web project" hopefully doesn't have to mean "One toolchain for your new web project".

I'm not a frontend dev, I do mostly backend and devops, but I often help other teams with tooling, configuration, and standardization. So far I love biome for new projects, but it's not a drop in replacement for existing tooling and configuration in every existing project yet. I'd love to bring biome into every project, new and old.

I think plugins would be a fine solution as well, once we have them.

Anyway I appreciate all the work being done on biome and the care being put into making it great. Thank you!

👏🏻👏🏻👏🏻

@ashishsurya
Copy link

SCSS support will be greatly appreciated

@jens-struct
Copy link

jens-struct commented Oct 21, 2024

@spartanatreyu Although some of your points are very valid, the question is not if css can do everything that sass can do, but if it should all the time.

I like to keep heavy fluid calculations and other stuff abstracted away in the build/on the server with easy to use helpers, and use new css features only where it makes sense to use them. Why should i deliver hundreds of extra kilobytes to the browser/user, when i don't have to.

Sure css is not as ressource intensive as js, but it still uses resources. And the last design system i saw, which solely relied on css vars, had 300kb of core css vars and their semantic remapping, this is insane.

It depends on the use case at the end. Just wanted to point out, there are more reasons (and performance for example, is a big one), why you'd want to use sass as an extension to css.

@spartanatreyu
Copy link

@jens-struct focussing on CSS is almost never where we should be focussing our attention when it comes to peering through the lens of performance improvements since there's usually something else having a greater impact.

Why should i deliver hundreds of extra kilobytes to the browser/user, when i don't have to.

Sure css is not as ressource intensive as js, but it still uses resources. And the last design system i saw, which solely relied on css vars, had 300kb of core css vars and their semantic remapping, this is insane.

I'm guessing just by you mentioning 300kb of core css vars that this was a design based on openprops?

When it comes to 300kb of custom properties, there's a few possibilities that come to my mind. It's either:

  1. It's 300kb of predefined values AKA a design system meant to give a design consistency (e.g. All spacing is a multiple of 4px, all shadows are actually fit in dark mode and are not just inverted colors, etc...). An interesting effect of these design systems is that since they're just a few named values and variations on those named values, they have a lot of redundant information making them highly compressible. (e.g. Minified Open Props is 370kb but over the wire is compressed down to 6-ish kb, and you can always choose to use less of it instead of importing everything)
  2. There's something else embedded in the css. Probably an inlined base64'd background image. Just be aware that the base64 encoding actually increases filesizes by 33%. So just pull those images out and send them over the wire with a HTTP1 > web server.
  3. or, it's somehow a lot of disjointed custom properties. If you've got 300kb of it, then it's probably a bunch of old code that was only used during the initial iterative/experimental process of creating the design in the first place. Once that process crystalizes into a final design, that old code can be cleaned up. If that's too annoying to do by hand, you can always put it through a tool like PurgeCSS.
  4. or, it's somehow a lot of @property declarations to restrict values. I'm not sure why anyone would want to make 300kb of these unless they were making something like a web builder app, in which case you probably wouldn't want to use scss since it wouldn't be able to make use of @property anyway.

If your hesitation is instead towards having custom properties instead of scss variables because they're precomputed, it's worth pointing out:

Since Custom Properties are computed at runtime, they're not beholden to the requirements of static analysis. This means they can be granted greater power than SCSS variables could ever be granted (e.g. cascading, types, and all that follows from them) and you're trading that precompute for that extra power.

But if your hesitation is instead towards having custom properties instead of scss variables because they result in more calculations, it's worth pointing out:

Custom properties can often describe things in a more performant way than the equivalent SCSS. For example: CSS would use animation: [...] var(-t) [...] for the duration of an animation and set the value of -t in the :root psuedo-class which gets overridden to 0s in a @media (prefers-reduced-motion) block. The equivalent SCSS would likely have * { animation-duration: none !important; } which now forces the browser to walk the entire DOM tree to figure out which animations to halt when it instead could have just used the smaller custom property cascade tree that the browser already maintains when using custom properties.

@jens-struct
Copy link

jens-struct commented Oct 21, 2024

@spartanatreyu thanks for your answer.

focussing on CSS is almost never where we should be focussing our attention when it comes to peering through the lens of performance improvements since there's usually something else having a greater impact.

Oh, this is simply not true, in most cases. First, if you take performance seriously it is not only about optimizing the things that have the greatest impact, but things that have an impact in comparison to effort and improvement potential. Secondly, depending on your frontend architecture, CSS can be the single blocking ressource for the critical rendering path, which makes it normally a quite important ressource to optimize.

I'm guessing just by you mentioning 300kb of core css vars that this was a design based on openprops?

Not at all, i'm talking about a recent example i came across about a common architectural design token pattern (in the context of design systems), where you have core design tokens, like a complete color palette. And then remap some of these core design tokens (which are not meant to be ever used directly) to semantic design tokens (which are meant to be used directly). Doing this kind of stuff in the browser has no value to the user or the functionality of the frontend. It is just bloating the delivered CSS. But this is just one example.

And it's ok, there is no wrong way here, as nobody knows all the reasons, why someone in a specific project, with specific constraints and specific goals, has very valid reasons to use Sass as an extension to CSS for some things.

Don't get me wrong, CSS vars are great. You can even generate CSS vars with sass. It is not about one or the other, but choosing the right tool for a specific problem, depending on the context. If you ask me, Sass will probably never be obsolete, but i don't care if you decide not to use it anymore. Lets leave this choice to the biome users, if it at some points supports Sass. Although i guess your intention was to help and educate, at first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Formatter Area: formatter L-CSS Language: CSS
Projects
None yet
Development

No branches or pull requests