I like the simplicity provided by scoped CSS, and I tend to name classes in a way that essentially accomplishes scoping. However, there's this nagging feeling at the back of my mind that if every component in your app has its own stylesheet, your style is maybe not consistent? It just seems like the ideal website with a consistent and good UI design should be able to have a single stylesheet (probably written in Stylus/SASS). I don't know if this ever happens in practice, but it's just something I think about.
Less on-topic, I feel like the title of this article is wrong: you're not "Just Writing CSS" if you're writing scoped CSS, which requires some sort of build system.
> However, there's this nagging feeling at the back of my mind that if every component in your app has its own stylesheet, your style is maybe not consistent?
I think we can distinguish two orthogonal uses for CCS styles. One is applying a global style to the page/app ("theming", "branding", etc) and the other is for defining the layout of a component. For technical reasons they have lived together, but with shadow DOM One can put the former on a global CSS and the latter togheter with the component. By doing this I think you can remain consistent, in fact I suspect that it may improve consistency since it is better clear what is part of the style (and thus should be respected/changed with care) and what is an implementation detail of a single piece of a page.
Of course the risk of a component "going rogue with styles" exists, but maybe (and now I am just speculating) by adding CSS variables to the mix we can help the single components to be more consistent with the rest of the app.
You can use a global set of variables for typography, colors, borders, box-shadows, and spacings. This could be CSS variables, SASS, or Javascript variables in CSS-in-JS.
Typography and colors are something almost everyone tries to keep within a bounded set, but spacings are often overlooked. If the designer has defined a clear set of spacings - like 8px for small, 24 for medium, and 48px for large, then we can build consistent interfaces by using that as a primitive. Button paddings will be $small-spacing, while sections can be separated by $large-spacing etc.
The stylesheet at this point is just an application of all these base values to the HTML structure of the particular component, and that arrangement can be unique to each component depending on how its HTML is laid out.
http://tachyons.io does this really well - @mrmrs_ has teased out a universal set of base values that can cover most designs, and has built out a complete UI kit out of it. There are many experience reports online, here's how DNSimple went about it - https://blog.dnsimple.com/2017/01/CSS-journey/.
Tachyons is so good that I would find it difficult to go back to plain css. I usually cringe looking at non Tachyons stylesheets. I'm not even totally sure how I worked before it.
Yep, changing government department colours in my case. About 6 departments wanted the same components and each had small themeing changes, really just colour and font.
I debated whether to title it something else for that exact reason. But I went with 'just writing CSS' because the code you're writing is just CSS, with all the benefits it entails — it's basically just like writing JS inside an IIFE rather than polluting the global namespace.
You make a good point about consistency. Personally I'll often have a small global stylesheet that implements basic typography/colour/etc rules — it's more important to ensure that your component styles don't leak out than avoiding global styles leaking in, in my experience.
Yes, but consistency of design should be enforced by the design process, not the technology. By the time the developer is implementing the feature the (inconsistent) design has already been signed off.
All global styles achieve is to make it difficult to break out of conventions when our layouts and designs diverge on purpose.
Instead of thinking of it as a 'single stylesheet' for consistent UI, but instead a 'library of styles', just like if you were writing code (JS or whatever). When you need to DRY and reference something in your library, just import it. CSS Modules does this really smartly with `composes`.
An example may be, graphic designer shop gets a contract to update the company 'style guide'. It gets done and there are a lot changes that are cross-cutting w.r.t. components, starting with fonts, borders, margins, border styling etc.
Also, what's not fully clear to me, what if - as usually is the case - the components are nested? Changing eg. font in the outer component would leave inner components fully intact?
Totally — I'll often have a small global CSS file for that exact reason. (Scoped CSS is about preventing your components from clobbering each other rather than preventing the desirable aspects of the cascade.)
If components are nested, inheritance still happens (unless you're compiling to web components with Shadow DOM, which Svelte allows), but cascading doesn't unless you opt-in per-selector with the global:(...) modifier borrowed from CSS modules.
Re isolation, if I've understood correctly, then state in components is indeed isolated.
I don't get what you are trying to say. If you put your stile inside a div, and set the "scoped" attribute, it's scoped. What build system is required?
About the overall consistency, yes, some things must be global. It would be best if CSS allowed you to define those in one place and apply in another one. Yet it doesn't, so you must keep all the declarations touched by global data at a global style. That's bad, but what is even worse is putting the local declarations there too.
The "scoped" attribute is not what this article recommends, nor would I recommend that anyone else use it. MDN describes it as deprecated. [1] It was dropped from Chrome in v35.
Instead, the article calls for using Svelte and its build tools to automatically add unique attributes to HTML elements and add corresponding selectors to CSS.
Svelte is awesome, but there's no doubting that it is a build tool, and I think it's fair to argue that if you're committing to a build tool either way, maybe you'd be just as happy using a richer build tool based on TypeScript and styled React components or whatever floats your boat.
The client-side polyfill for Shadow DOM requires executing JS before paint, which is slow. For optimum performance, you have to polyfill it server side, with a build tool. At that point, you might as well just pre-process it for all browsers, at which point, maybe you'd enjoy something more flexible than Shadow DOM, e.g. something that lets you share styles between components.
I'd double check your performance assumptions. Polymer-based sites are usually at the top of the list for perf shootouts, even though they tend to be purely runtime rendered. The key is only executing very little JavaScript and very carefully managing DOM creation.
The ShadyDOM/ShadyCSS Shadow DOM shims are quite fast, and the benefit is that you don't need them when you have native Shadow DOM, vs a compile-time solution that you're likely married to and is proprietary. Shadow DOM gets faster automatically as browsers adopt standards, and portable and lasting knowledge is worth a lot.
Safari's Shadow DOM implementation has improved a ton over the last year. Polymer 2.0 defaults to using it over the polyfills. caniuse.com needs to be updated - the second bug listed is fixed now.
It depends on what you measure. Google argues that "time to interactive" is the correct number to optimize for; that's where Polymer-based sites shine.
But nobody can beat streaming server-rendered (or ServiceWorker-rendered) HTML + CSS on a "time to paint" basis. Google claims that "time to paint" is the wrong measure, but if you're using progressive enhancement, TTP is all you need.
Shadow DOM mostly sucks anyway for lack of a good way of sharing styles between shadow roots. (It's awesome that we can encapsulate CSS with shadow DOM, but that was too much encapsulation.)
I’m writing scoped CSS in SASS - I’d postulate that that is the maximum you should require (and most sass systems will have a way build on request to your server).
Just adding it here as well: if one likes editing CSS files in Chrome Dev Tools, then activating Workspaces will save such changes into the source file. This Dev Tools integration with the Svelte approach is so useful that it might actually tilt the choice in favor of CSS files over the more abstract, thus Chrome-uneditable CSS-in-JS (Workspaces are doable with SASS too as per https://www.amazeelabs.com/en/How-to-write-Sass-within-Chrom...).
Worth mentioning that CSS-in-JS _and_ CSS-in-CSS hot reload in any modern build system anyway. So using workspaces used to be super useful but it's not a big selling point any more.
I'd agree with it were it not for the huge difference between the view refresh latencies. Within the browser, it's near-intantaneous. Hot module reloading (which is still experimental) is relatively fast, yet there's a couple of seconds of a trip; also depends on what and how changes. Full page reload can take even longer, there's compilation time, bundling and the unavoidable cost of reloading stuff in the browser. Sure a couple of seconds doesn't sound bad but it's still a couple of seconds longer than what it should be (immediate) and it breaks my (work)flow.
And you lose state, unless you've carefully designed your app around that problem by using something like Redux. Which is a fine thing to do, but not everyone wants to.
The chrome dev tools API has a neat function to inject new source code by only replacing all functions from the new code, thereby keeping any state. I've used this when building wright (https://github.com/porsager/wright) to allow for hot reloading of anything (no need for redux). CSS reload is also instantaneous with wright, so might even make sense for you to use with the setup you described - No need for copy pasting ;)
You can see it in action here https://porsager.com/wright/example.mov - The start is editing js code (a mithril app) that is going through rollup, but there's also editing of raw css files at the end.
Insanely cool demo. Learning Wright has been near the top of my TODO list for longer than I want to admit — I just never manage to get through the other items on my open source TODO list :(
TL;DR: People love to hate CSS, but it's the reality. People have various solutions to deal with the major problems with CSS (i.e. cascading global styles mean impact of any is unpredictable) but recently people have begun tying the CSS to the particular HTML collection it applies to, and the author likes that and points out some particular implementations he likes (I'm assuming "Rich" is/identifies as male).
Scoped CSS really is the most forward-thinking CSS IMHO. It's 'plain' enough to be adopted into most workflows and it doesn't really stray very far from the original CSS language.
Scoping CSS is great, you can do static analysis, idiot-proof just-in-time stylesheet loading, and when done correctly it eliminates a lot of specificity issues. It doesn't scale well though. Eventually you develop http-call bloat, and unless your CSS is written by a single and very devoted person, consistency becomes nearly impossible to maintain.
Visual consistency begs for DRY CSS, and DRY CSS tends to bend back towards single global stylesheets.
The http call bloat is a by-product of how your build process works though — if your CSS lives in your components then you can easily bundle it just like you bundle your JavaScript. The ability to lazy-load individual components and their styles if you wish is a feature, not a bug.
It's fine to still have a (preferably fairly small!) global stylesheet that covers fonts, colours and so on. The key is to avoid your components potentially clobbering each other, which is what SFCs accomplish.
I don't think so. In fact, 'scale' is specifically when scoped CSS is its strongest. It allows you break things out and move quicker and develop easier to maintain styles.
1) http-call bloat is mitigated by a built process (which you would probably already have to use if you're using a Scoped CSS method like CSS Modules.
2) Visual consistency and DRY aren't affected. Think about it like regular code - when we want to repeat a unit of code we break it out into a seperate compassable function. We can do the same thing in CSS Modules with composes. You could also (carefully) introduce a preprocessor like LESS/SASS/Stylus/etc for variables and mixins and what not.
correct — he/his/him. Yes, exactly, the key here is that CSS is meaningless except in the context of markup: if you can statically analyze the two things together, good things happen.
I find that keeping what I do simple and small and well documented makes the simple stuff I do easy to maintain.
Yes, I can write you (another) 100kloc of Java or C++ or JS if you really want, but I did also enjoy Standard ML and Prolog over more and more imperative code with exciting race and portability issues.
One thing i learned with css is that as a programmer you have to take it seriously. We generally don't consider it a programming language so we work on it the least, more often then not we don't even include it in our completion estimate.
To do CSS at scale requires organization and planning from the very beginning. If you start with bootstrap, you can't just deviate down the line. If you follow the BEM convention you not only have to stick to it, you have to enforce it so everyone in the team follows it.
Currently I work on 2 MVC project, and just like every component has a view, each also has it's own css file. We don't have to wait for compilation since .net has a realtime css update, and php doesn't need to compile in the first place. But for each project, i have to train new members to follow the convention.
> One thing i learned with css is that as a programmer you have to take it seriously. We generally don't consider it a programming language so we work on it the least
Agree with this. I've seen frontend work collapsing under its own weight because the CSS was kept in one huge file, you couldn't tell what was dependent on what, JavaScript was being used to alter the DOM based on classes and window resizes, there were around 20 different media query size widths, nothing was shared as variables...changing anything was terrifying and took forever.
You need to keep CSS modular, stick to naming conventions, reduce duplication and keep code concise; exactly like you do with regular programming languages. You can get far with CSS without any programming knowledge but at a certain scale you need to understand good coding fundamentals.
How is Svelte solving these problems in Vue Components?
> 2. A child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS.
> 5. Be careful with descendant selectors in recursive components! For a CSS rule with the selector .a .b, if the element that matches .a contains a recursive child component, then all .b in that child component will be matched by the rule.
It's not the same. Styles declared in a Svelte <style> block only pertain to that component, unless you opt-in to the cascade with a little bit of extra syntax borrowed from CSS modules: `:global(.foo) {...}`.
You can also compile Svelte components to custom elements, which use shadow DOM to enforce complete style isolation (though this is a new and experimental option).
If scoping CSS is such a big deal, I've got to ask if its not easier to just go with inline-CSS instead. It's a matter of whether specifying styling rules separately from content markup is a good fit to your app or doc, or if you're rather working around an undesired far-distance effect of CSS. If you need complete style isolation from the rest of your site, then you're really writing HTML markup to express an UI, so why not express it in a single artifact or dynamically generated HTML along with properties in plain old HTML style attributes?
I'm completely dumbfounded how everyone has missed that the simple problem of scoping in CSS is naming.
I work with Vue and Stylus. You already have to give your JS components a name. Your styles can use that name. I don't need my styles inside the .vue files. I just keep them in a separate file: /styles/components/foo.styl. At the top of your Stylus file you give the name of the component (.foo) once. Even further, you can prefix it (.my-foo). That's the namespace. Then all your styles can be written under that with a methodology like BEM. Now you get scoping AND you can still load up your variables/settings first, via a main.styl. Otherwise, if you put styles in your .vue files then you need to remember to import variables each time. Also it becomes an issue to discern which classes in the component are from you and which are from a vendor (ie. Bulma, Boostrap). Then think about libraries. You can't work with styles that are in the vendor's .vue files (without adding more specificity). I wish that library would have provided me its separate SCSS/Stylus styles instead. Am I missing something here Rich? (btw, love your work in Rollup!)
I personally prefer the co-location of styles and markup, because it means I'm context-switching a lot less. And it's essential that the compiler can analyze the styles in the context of the markup to which it applies in order to do things like dead code elimination.
But support for external files and preprocessors is on our roadmap.
I have setup my own methodology for loading external files and preprocessing (ala postcss and whatnot) which works to my preference. As well, one can still namespace to match. Win-win.
Alright, this discussion got me thinking. I think this is the way to go now. The bullet list:
-- All separate style files (for non-vue-component styling, such as variables, functions, and CSS-only components) use BEM. All styles inside Vue components also use BEM. Consistency!
-- Use Stylus in the Vue components. Vue-loader supports preprocessors. Why a preprocessor? Mainly for theming. Why Stylus? It’s just so beautiful.
-- Using BEM inside vue components means I don’t have to worry about collisions (with global, or children, or vendors).
-- Mental context-switching is reduced now since component styling lives inside the .vue files.
-- I don’t mind using #app to override vendor component styling.
-- Better scenario for Dead Code Elimination to work with when putting styles in .vue files.
-- I don’t mind importing variables/functions/theming to each component until this is solved in the future. Plus, I could create a bootstrap.styl (not to be confused with Twitter Bootstrap) to import everything I need so I’m only adding a single file to each Vue component. Any changes made are made within boostrap.styl and Vue components would not need to be updated.
> The biggest problem with CSS
Everything in CSS is global. Because of that, styles intended for one bit of markup often end up affecting another. Because of that, developers often resort to wild namespacing conventions (not 'rules', since they're very difficult to enforce) that mostly just increase your risk of RSI.
Hmm, I don't find namespace issues a problem to be honest. Generally I use a framework (e.g. Bootstrap) where I don't reuse any of its names, I have some global styling (e.g. buttons, forms, typography), each major screen/component gets it's own file with its own class identifier (e.g. page-home for the homepage) then in SASS/SCSS I make sure everything everything in each file is nested under the screen/component identifier (e.g. so everything to do with the homepage is nested under .page-home). It's going to be very obvious if you get a naming conflict and they're not hard to resolve.
Is there anything wrong with the above approach? You'd need something different if you were designing your own framework or general components across a huge website but for SPA and typical websites I don't see the need to make it more complex than this.
The problem I see with that approach is that it doesn't leave a lot of room for reusability in different types of design components.
Many times in larger web applications, designers will have similar design themes that span multiple pages (more than just simple things like forms). So there may be a callout with a border and all text inside is blue across 5 separate pages.
You may approach this as #homepage .callout at first but it begins to become hard to manage when you realize you need to refactor it into a side wide style.
Generally I approach everything in attempts to make it re-usable. And organize what I can into components. I'd rather write more css classes in the markup than have to specify names for certain cases where 'this heading is bold here but underlined in this case' yada yada, when I can just write .bold .underline .h5.
> You may approach this as #homepage .callout at first but it begins to become hard to manage when you realize you need to refactor it into a side wide style.
So one approach would be to have a "callout" css file, nest everything under ".callout" and have several callout styles you can use inside that file (e.g. ".callout .warning")?
> Generally I approach everything in attempts to make it re-usable. And organize what I can into components
Personally, I find very little CSS can be reused between different projects as designers want completely different looks so I let things like Bootstrap take care of the basics and customise from there. It takes time and effort to make things reusable (same with code) so you need to weigh up how likely you are to actually reuse things and how much time that would save you.
Sometimes duplication between projects saves time compared to maintaining the code for some generic widget that has to work in many scenarios. For me, I don't think it would save much time as each component is usually small and simple but I could understand if you were to create e.g. a calendar widget where it involves a lot of complex styling and code.
If you're just using Bootstrap and its classes, then you're probably not in the 'target market' for something like this.
I think you've actually agreed that Scoped CSS is really useful, but you just implement it manually by using a naming convention. What if you didn't have to worry about that and the language just worked like that normally?
> I think you've actually agreed that Scoped CSS is really useful, but you just implement it manually by using a naming convention. What if you didn't have to worry about that and the language just worked like that normally?
I agree scoping is universally useful in coding, I just can't empathise that the lack of proper namespacing in CSS is a huge headache when it takes little effort to emulate it by nesting classes. Unless there's more to it? Language support is nice though.
I wouldn't really say there's huge effort. CSS Modules provides scoping in the same way that C++ added scoping to C (AFAIK) - it just mangles the names transparently at 'build' time.
That's one of the unresolved questions. A couple of possible solutions:
* have a small global stylesheet with styles that are common to many components
* put the styles in a mutual parent component and opt-in to the cascade with the :global(...) modifier (from CSS modules)
* you don't. This is often the answer I prefer. DRY code is less flexible, and I've often found it far better to have some duplication 5 minutes before I ship rather than be desperately trying to change some CSS on this component without also affecting those components
But yes, this is an area we still need to work on.
On top of that the CSS working group is working on ::part and ::theme pseudoselectors to help theming across components. Brief intro in this Polymer Summit 2017 talk: https://youtu.be/rvpJ5O0W_6A?list=PLNYkxOF6rcIDP0PqVaJxqNWwI... (skip back to 16:17 to hear why the CSS mixins proposal didn't work out)
> It warns on and removes any unused rules, then it minifies the result and lets you write it out to a .css file.
So... is `el.classList.add('error')` going to do nothing if the source contains an otherwise unused error class? Is there some comment flag that prevents this behavior? Do you need to shut off the analyzer completely, or add extra hidden markup to also consume your dynamic classes?
Does it handle media queries? Or new/upcoming CSS features like the replacement for the attempted mixin standard? (:theme and... something or other...)
I'm all for finding dead rules, but if it automatically eliminates them I worry it'll be easy to accidentally trick.
For the static analyzer to work, you'd need to add that error class to the template (`<div class='{{error ? "error" : ""}}'>` or something). But that's okay — it's the whole point of state-drive UI, and happily it's much easier than manually manipulating the DOM in a way that keeps track of state. It's a feature, not a bug ;)
Yep, it handles media queries. It should handle ::theme just fine (since it doesn't know what it is, it'll just ignore it), but since it's not implemented anywhere I haven't tested that yet!
Ah, that's a good point. Despite using Polymer, React, etc...
for side projects, my primary browser target remains IE8 in quirks mode, so I forgot modern UI patterns for a moment.
* As the author of that article was talking about, I keep as much CSS scoped to the component level as possible.
* Any layout-oriented styling(how a component is positioned and sized on a given page) is separated into its own style sheet per page. That way how a page is laid out is separated from how a particular component looks & behaves.
* To deal with the lack of container/element queries, a big roadblock in making components truly reusable, a component style sheet exposes Sass mixins that represent how the component looks at different sizes. The layout CSS for a given page, as mentioned in the last bullet point, includes these mixins at different media query breakpoints. The advantage to this is that the layout can manipulate a component at different breakpoints to create responsiveness without needing to have any knowledge of a component's internal workings.
An example of my third point is a component I'm currently working on right now called `incidents-grid`, which is merely a grid of items. The `components/incidents-grid.sass` stylesheet has mixins called `incidents-grid--xl`, `incidents-grid--lg`, `incidents-grid--med`, `incidents-grid--sm`, `incidents-grid--xs`. Other components follow the same convention. For my page, I have a `layout/index.sass` to deal with how I lay out my components on the page. At different media query breakpoints, I will include the incidents-grid mixins to change how the component looks at different sizes; at different sizes, this component may show or not show a thumbnail, or show smaller icons, or no icons, or omit some information. The layout can make these things appear/disapper at different screen sizes without a bunch of CSS specific to the component saying things like `.incidents-grid__thumbnail {display: none}`. Rather, my layout stylesheet can say something like `#l-index__incidents-grid { @include incidents-grid--sm }` in a media query to accomplish the same thing.
Granted, this can't be done with plain CSS without some JavaScript. But I've found being able to separate layout CSS from pure styling CSS, as well as abstracting the internal workings of components with mixins, to be a very sane approach.
Ultimately it's something you can DIY in ~30 lines of JavaScript, and over the weekend (just for fun, just to see how far back the ideas worked) I got it running in IE8, IE7, and even IE6 - so it's definitely something you can use today! https://twitter.com/innovati/status/903998563738415104
Note that the benefits of scoped CSS are completely independent from single-file components.
The key idea is that with CSS and DOM scoping you write simpler, easier to understand, stylesheets and templates, which massively improves maintainability.
In Polymer elements, because of Shadow DOM, selectors are considerably simpler and shorter, often just using a tag name or id. Templates for a single component often fit in one screen, so you can more easily see if a selector is used.
As we get into more declarative template formats and better static analysis, we'll be able to see if selectors are used even for dynamic classes and attributes.
> "But at the end of the day, you have to know CSS anyway"
If you string-replace "CSS" with "assembly", most of Bret Victor's "The Future of Programming" [1] still seems to apply. People used to argue this passionately that knowing how to write assembly by hand was critical to being a good programmer.
> "Love it or loathe it, you must at least learn it."
This might be true today, but it would be a shame if tooling didn't level up to a degree where CSS becomes mostly a compile target (just like assembly is today).
At the end of the day, CSS provides styling tools for a massive medium, one that should be accessible much further beyond the 0.25% of the world that knows how to code. The main way we can unlock that is with better tools and better abstractions. It's wholly unrealistic to get everyone to be as good at hand-crafting CSS as the author, nor should it be the goal.
CSS is getting more and more powerful and more complex, and it's unrealistic for folks to continue hand-crafting in perpetuity. Even today, with some of the world's best software engineers, I routinely see this:
* Most devs don't know how to create a radial gradient from memory
* Most devs don't know how to hand code shape-outside code, especially polygon
* Most devs guess-and-check repeatedly as they work with Flexbox props and use cheatsheets even after years of practice (while designers are running circles around them using visual abstractions like [2])
* CSS Grid minmax formats, don't get me started...
I personally love crafting CSS by hand, there's a certain satisfaction to it. But if that's the primary way that folks are styling stuff on the web 5 years from now, to me that would imply that we did a bad job of exposing this wonderful technology to orders of magnitude more people.
> Most devs don't know how to create a radial gradient from memory
I think I largely agree with you — giving more people the ability to build and design stuff with web technologies is something I care a lot about. To me, the answer is to build better tools around CSS, rather than creating a multitude of abstractions and creating tools that target those.
My belief is that CSS tooling hasn't evolved as quickly as JS tooling (and hence CSS-in-JS) because the JS community has often had a bit of a snooty attitude towards CSS and people who write it. That's something I hope we can change.
I don't work at the Guardian any more, I'm at the New York Times, where we are starting to use Svelte for some stuff (see e.g. https://www.nytimes.com/interactive/2017/08/09/upshot/game-o...). Though I haven't spent a lot of time evangelizing it to my coworkers here to be honest — if people are happy with their current tools then I've got no interest in shoving Svelte in front of them.
> I'm just a bit lairy of adding yet another proprietary tool to my buildchain to try and bend the web platform to my will.
By using Svelte I've found that I no longer need to bother with any CSS pre/postprocessors or minifiers (I was mainly using them for scoping, which is no longer necessary), and I don't need to faff around transpiling JSX. So you might find you add one build tool but get rid of two others!
I think there are other reasons for dismissing BEM, it's quite an opinionated and shallow structuring, good for some stuff and not for others. Very HTML tag oriented, for which we have, well, HTML tags already. Its claims are simply not true (eg. "Reduces style conflicts by keeping CSS specificity to a minimum level."). Even in syntax, it saves on silly things (".btn"?) and wastes much more on, in effect, introducing Hungarian notation to CSS. I could go on but no time rn
Perhaps if the web had started off as dynamic instead of static we'd have several styling minilanguages to choose from, that worked the same on all browsers, rather than the mess introduced by letting the browser wars dictate web standards.
So, as someone who currently has no background in web stuff, but is leaning that way, should I be paying a lot of attention to this, or put it on the shelf for now? How does this fit in or compare to Less or Sass?
The article is primarily talking about keeping your CSS modular... writing CSS that applies only to one "component" of a page (e.g. a box in the sidebar or a header logo or a navigation menu or whatever).
LESS and SASS have more to do with the fine-grained details of CSS syntax... primarily reducing repetition (via nesting, mixins, variables, etc).
I personally wouldn't worry about any one particular technology (other than CSS itself), but I have found over the years that the most immensely helpful technique when working with CSS is keeping things as modular as possible. Basically, ignore the "C" (Cascade) in CSS, either with compiled / scoped components (like the linked article is talking about) or through a naming convention like BEM or SMACSS.
If you have no background in CSS+HTML, you probably want to actually start by learning a clear mental model for how CSS and layout actually works. Otherwise, working with CSS is going to feel like https://imgur.com/gallery/Q3cUg29. If you are actually able to predict what layout would result from a small snippet of CSS and HTML, it makes things much easier.
5) With all that open, work through http://book.mixu.net/css/
As you are going through it, test things out yourself and take notes. Make flashcards that test your ability to remember why certain things work the way that they do. Also make flashcards for things that seem surprising. Try to keep them small and focused.
The CSS developer experience is just one small aspect of the framework. The advantages are spelled out more fully in [this blog post](https://svelte.technology/blog/frameworks-without-the-framew...) — Svelte compiles your components to lean, very fast JavaScript. It handily outperforms React, and your app will almost certainly be smaller and start quicker.
You're unlikely to find a postcss plugin that can eliminate dead code. Unless it can analyse your CSS in the context of your markup, it has no way of knowing what's safe to remove. For that, you need statically analyzable single file components.
We did this for a long time but we still ran into problems where people would use the same CSS class name in two places and styles would interact poorly.
It's easy to just say "don't do that then" but with a large enough codebase, and devs of many different skill levels, it's easier just to move to a model that prevents CSS cross-talk altogether.
The article advocates for using Scoped CSS, which it clearly sounds like you're not using. Mitigating against your problem is the entire point of Scoped CSS ;)
In our codebase (using import './styles.css' w/CSS Modules) every single component has a className called .root at the very top. Never conflicted once.
I'm just a dumb bug, but it's possible that this dude is betting on keeping it simple by avoiding alien syntax and additional transpilation steps. In browsers, this usually makes errors more relatable to the canon, readable source code your team uses.
The model of html/css is not designed for the ground up for modern layout. It was a tool designed for a separate purpose with features hacked on over the years to make it work.
Nowadays a website is no longer just a document. It's an application. Why have html/css the one crude way to make a web application? In the backend we have a constellation of apis, frameworks and languages to build an app, but in the front end it's HTML/CSS/JS. The role JS played is generalized by WebAssembly, it's time to do the same for HTML/CSS.
The primary reason behind WA is not for performance. If performance is all they cared about then browser developers can continue to work on optimizing the speed of the JS vms.
The advantage of a low level pixel based api is for people who don't like HTML/CSS. It's to make web application development truly about application development by allowing developers access to a whole universe of layout engines rather then just one.
Less on-topic, I feel like the title of this article is wrong: you're not "Just Writing CSS" if you're writing scoped CSS, which requires some sort of build system.