Live data from Hacker News

UnCSS: Remove unused styles from CSS

github.com

11–20 of 50 posts

Re: UnCSS: Remove unused styles from CSS

#11
Have used tools like this before, and invariably end up accidentally stripping styles from an component with a dynamically assigned className or something equally silly.

It's such a hard problem to solve and the Stylesheet Snowball is one of the most frustrating pieces of technical debt a large site can pick up.

It makes me wonder if scoped CSS modules, despite fundamentally breaking CSS with their hyper specific hybrid BEM-class-ids might be the best preemptive solution even when you're not scaling up to massive SPAs.

Edit. Meant CSS modules, wrote CSS components. I am not a clever man.

Re: UnCSS: Remove unused styles from CSS

#13
post #11

Have used tools like this before, and invariably end up accidentally stripping styles from an component with a dynamically assigned className or something equally silly. It's such a hard problem to solve and the Stylesheet Snowball is one of the most frustrating pieces of technical debt a large site can pick up. It makes me wonder if scoped CSS modules, despite fundamentally breaking CSS with their hyper specific hyb…

> with a dynamically assigned className or something equally silly.

How is that silly? Assume e.g. a very simply dynamic list, where you just want highlight rows after clicking on them. Should it set the CSS properties of the directly? It makes more sense to dynamically add/remove a CSS class such as "selected-row". However, since initially no row is selected that class does not appear in the initial HTML.

> scoped CSS components

Not sure if this is the same, but I had very good experience with component-oriented frameworks where each component has an HTML snippet and CSS snippet attached to it. The CSS is written in a way that it affects only the responsibility scope of the component, nothing outside the component, nothing inside child components.[1] Then, these CSS snippets are simply collected into a large (and perhaps compressed) CSS file.

[1] This is usually done be either prefixing all CSS rules with a component-specific class name, or by using a component-specific custom HTML element and selecting on that. Stepping into children is avoided by using only child selectors ("a > b > * > * > c" instead of "a b c"), so the rules don't reach deeply except for the cascading properties of CSS itself.

Re: UnCSS: Remove unused styles from CSS

#14
AFAIK, this could also be written as a transform in AssetGraph [https://github.com/assetgraph/assetgraph], which does all of the loading, parsing and traversing for you. At least the given description reads like the internals of the population/loader-system in AssetGraph.

As an added benefit, you'll get de-duplication, minification, inlining (with fallbacks) and, with a little work, image-spriting thrown in almost for free.

If you want to play around easily, take a look at https://github.com/assetgraph/assetgraph-builder

Re: UnCSS: Remove unused styles from CSS

#15
I've done something similar nearly two years ago[1]. The problem is rather difficult, especially with all the JavaScript frameworks in existence right now. I've tried to build a state machine for handling those frameworks but never got around to finishing it. There's basically and endless amount of combinations one can do, thus you probably want to limit depth or something. You also have to be able to detect ::after and similar kind of selectors, which isn't always straightforward with querySelector and needs quite a bit of cleaning. I ran into a few other (edge) cases, which I cannot remember right now.

Nonetheless, it is a challenging and fun problem to solve.

[1]: https://github.com/Kevin-A/css-detector

Re: UnCSS: Remove unused styles from CSS

#16
post #15

I've done something similar nearly two years ago[1]. The problem is rather difficult, especially with all the JavaScript frameworks in existence right now. I've tried to build a state machine for handling those frameworks but never got around to finishing it. There's basically and endless amount of combinations one can do, thus you probably want to limit depth or something. You also have to be able to detect ::after…

My naive opinion is that this should be done by the browser, perhaps in the developer tools. You would be marking a session as "integration tests" and at the end it would give you a simplified css file without the unused rules during testing.

Re: UnCSS: Remove unused styles from CSS

#17
Clutch timing! Been working on several projects amassing a multi-purpose stylesheet (currently ~600 lines) having already conceded that a tool which accomplishes exactly this would be needed.

Edit: seems overkill, the theoretical solution I had in mind would just take a few arguments;

ie:

trimCss mybloated.css mypage.html > mytrimmed.css

Re: UnCSS: Remove unused styles from CSS

#19
post #6

I've been hoping someone would write a similar tool, but using a browser, so that I could run a webapp, click around (using a checklist, to cover all of the views) and get a resulting list of used CSS rules from the browser. That would have the advantage of supporting complex webapps written in any language/environment.

There's a "Coverage Support" experiment in Chrome DevTools which does css + js coverage in a way you describe it. The CSS part was shown on Chrome DevSummit 2016 [1]

[1] https://www.youtube.com/watch?v=HF1luRD4Qmk

Re: UnCSS: Remove unused styles from CSS

#20
post #13
post #11

Have used tools like this before, and invariably end up accidentally stripping styles from an component with a dynamically assigned className or something equally silly. It's such a hard problem to solve and the Stylesheet Snowball is one of the most frustrating pieces of technical debt a large site can pick up. It makes me wonder if scoped CSS modules, despite fundamentally breaking CSS with their hyper specific hyb…

> with a dynamically assigned className or something equally silly. How is that silly? Assume e.g. a very simply dynamic list, where you just want highlight rows after clicking on them. Should it set the CSS properties of the directly? It makes more sense to dynamically add/remove a CSS class such as "selected-row". However, since initially no row is selected that class does not appear in the initial HTML. > scoped C…

Oh dynamically setting class isn't silly, but the times i accidentally removed the 'unused' style because it's not explicitly coded into that app and was flagged by the tool, I felt pretty silly!

I got as far as starting to build us a tool to traverse our raw jsx to identify these programmatically generated classes, but my implementation was a bit flakey for various reasons and required too much config to make it worthwhile so I binned it off.

Post reply on HN