
The Zen of Just Writing CSS - rich_harris
https://svelte.technology/blog/the-zen-of-just-writing-css
======
dlbucci
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.

~~~
jasim
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](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/](https://blog.dnsimple.com/2017/01/CSS-journey/).

~~~
jacobr
Has anyone in practice updated brand colors without needing other major style
changes?

~~~
aplummer
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.

------
monfera
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...](https://www.amazeelabs.com/en/How-to-write-Sass-within-Chromes-
DevTools-using-Workspaces-and-Auto-reload)).

~~~
inglor
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.

~~~
monfera
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.

~~~
rich_harris
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.

~~~
porsager
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](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](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.

~~~
rich_harris
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 :(

~~~
porsager
Thanks a lot! I know that feeling, so many exciting things going on :) If you
get around to it, I'd love to hear about your experience.

------
ergothus
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).

~~~
madeofpalk
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.

~~~
braindouche
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.

~~~
rich_harris
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.

------
swlkr
I was using CSS in JS or CSS scoped to components, but what really solved my
problems was tachyons

~~~
joe_fro
not familiar with tachyons and just did a cursory look at it, what about
tachyons really solved your problem?

~~~
swlkr
The problem of locally scoped CSS vs shared styles across components
sometimes.

With tachyons I still wrap up styles in components but I also get globally
scoped CSS for consistency with fonts/spacing.

~~~
kilburn
Honest question: how do tachyons differ from a (well-thought-out) collecion of
less/sass mixins?

~~~
swlkr
Tachyons differs in that it gives you consistent typography/spacing but
without the added complexity of a build step.

------
DamonHD
I like the declarative nature of CSS.

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.

------
firefoxd
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.

~~~
seanwilson
> 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.

------
Kiro
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.

[https://github.com/vuejs/vue-
loader/blob/master/docs/en/feat...](https://github.com/vuejs/vue-
loader/blob/master/docs/en/features/scoped-css.md)

If it's the same in Svelte I don't see how scoped CSS solves anything. I still
need to be careful not to let the CSS bleed into the child components.

~~~
rich_harris
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).

~~~
spankalee
Shadow DOM is the real answer here.

------
tannhaeuser
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?

~~~
nateroling
Inline CSS is underrated. Sometimes you just need one big red button, not a
.big-red-button class.

~~~
y4mi
css doesnt constrain you to classes. there are other selectors as well.

------
prograhammer
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!)

~~~
rich_harris
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.

~~~
arxpoetica
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.

~~~
prograhammer
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.

------
seanwilson
> 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.

~~~
gibberishhh
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.

~~~
seanwilson
> 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.

------
barryhoodlum
How do you re-use CSS across components?

~~~
rich_harris
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.

------
balloob
> How can we reuse constants that are defined in a single place?

The answer for this is already in your browser: CSS custom properties
[http://caniuse.com/#feat=css-variables](http://caniuse.com/#feat=css-
variables)

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...](https://youtu.be/rvpJ5O0W_6A?list=PLNYkxOF6rcIDP0PqVaJxqNWwIgvoEPzJi&t=1180)
(skip back to 16:17 to hear why the CSS mixins proposal didn't work out)

------
reificator
> 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.

~~~
rich_harris
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!

~~~
reificator
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.

Sounds good, thanks for clarifying.

------
ravenstine
Here's how I generally deal with CSS:

* 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.

~~~
err4nt
For element/container queries I've written a few plugins:
[https://docs.google.com/spreadsheets/d/1erAKZq0p6dH3LjtU01hj...](https://docs.google.com/spreadsheets/d/1erAKZq0p6dH3LjtU01hj2PlZH7tZxbGxFUl5jn-
V_Hg/edit?usp=sharing)

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](https://twitter.com/innovati/status/903998563738415104)

------
spankalee
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.

------
callmevlad
> "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.

\---

[1] [http://worrydream.com/dbx/](http://worrydream.com/dbx/)

[2] [https://www.flexboxgame.com/](https://www.flexboxgame.com/)

~~~
rich_harris
> 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.

~~~
arxpoetica
THIS.

------
jbreckmckye
You seem to be calling out BEM as a "crazy namespacing convention" \- but as
awkward as those underscores are to type, they _do_ seem to do the job.

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.

~~~
NathanCH
Anyone who dismisses BEM because of the syntax is missing the point of BEM
entirely.

~~~
monfera
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

~~~
NathanCH
Please do go on. Can you explain what you're talking about re: HTML tags?
Maybe brush up here [http://getbem.com/naming/](http://getbem.com/naming/)

------
krmboya
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.

~~~
dfabulich
There is no real alternative to letting the browser vendors dictate web
standards.

------
s73ver_
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?

~~~
jordanlev
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.

------
sayurichick
i work in react, so i just create a <componentname>.css file in the same
directory and `import componentname.css` in my component.

I get the advantage of using either Sass or less or postcss with webpack and I
get all the features as expected from this workflow.

The only thing I don't have is that unused class feature with my workflow, but
I can probably find a postcss plugin which handles that.

I don't see any advantage of this library for me?

~~~
rich_harris
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...](https://svelte.technology/blog/frameworks-without-the-framework)) —
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.

~~~
madeofpalk
No reason why Webpack/`import css` couldn't eliminate the CSS from this

    
    
        // styles.css
        .root { background: grey; }
        .button { border: 1px solid blue; }
        .error { color: red }
        .alert { background: red }
    
        // Component.css
        import styles from './styles.css'
    
        return (
          <div className={styles.root}>
            <button className={styles.button}>Submit</button>
            {false && <div className={styles.error}>Error!</div>}
          </div>
        )
    

Both the .error and .alert are candidates for being removed.

Of course, I'm not aware of any solution for nothing this currently, but all
the bits and pieces are there for it to be feasible.

------
crimsonalucard
I think browsers need a pixel level api that someone can compile a layout
engine down to. Sort of like webassembly for layout instead of logic.

~~~
pier25
You mean like WebGL or canvas?

~~~
crimsonalucard
No, outside of canvas. Make the pixel api the parent and html/css the compile
target.

~~~
pier25
Can you elaborate?

~~~
crimsonalucard
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.

~~~
pier25
Yes, but what would be the advantage of having low level HTML/CSS?

WA gives us performance. Before WA you could already write with many languages
and output JS.

~~~
crimsonalucard
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.

------
swiftting
There's no better feeling when you can write some clean CSS in a wordpress
template to make it do what you want!

------
jlebrech
wasn't this all possible with tables and iframes.

we even had IDEs back in the day that compiled wysiwyg into that code.

we're repeating everything but just in a prettier way.

------
graphememes
Scoped styles don't work properly for child nodes.

~~~
rich_harris
What do you mean?

------
aethant
Pure zen is vanilla-css.com

~~~
castis
That 404s, did you mean vanilla-css.com?

~~~
aethant
Indeed. Thanks.

