[HN Gopher] The Evolution of Scalable CSS
___________________________________________________________________
The Evolution of Scalable CSS
Author : remrem
Score : 90 points
Date : 2022-11-12 11:57 UTC (11 hours ago)
(HTM) web link (frontendmastery.com)
(TXT) w3m dump (frontendmastery.com)
| krono wrote:
| There is actually a W3C working group working on a standardised
| design token schema specification and on adoption by design
| tooling.
|
| Several big names such as Adobe are actively involved, so this
| has some weight to it.
|
| https://github.com/design-tokens
| smrtinsert wrote:
| Isn't this is a solved problem? Look at tools that provide
| themes. You can't use anything like semantic css or business
| related naming. It has to be widget based styling and that seems
| to be the end of it.
| azangru wrote:
| > The Evolution of Scalable CSS
|
| The evolution of practices described in this article is followed
| up to about ten yeas ago... and then stops, followed by Tailwind.
| Where is consideration of web components with shadow DOM, which
| solve the CSS encapsulation problem, the naming problem, and the
| dead code problem? Where is treatment of CSS variables that
| pierce the shadow DOM and allow global theming of such
| components? They are the next step in the evolution of scalable
| CSS, and yet they are noticeably absent from the discussion.
| dxchester wrote:
| We wrote about our journey[0] to sanity after Tailwind:
|
| _The answer is to do it all in strategic moderation: Use a
| subset of tailwind just for spacing and layout and revel in
| simple things being simple. Use modular CSS for UI patterns and
| revel in the readability of your HTML and visual consistency of
| your UI. And then use custom scoped CSS where required, and
| revel in interesting things being only as hard as need be,
| without ruining everything else along the way._
|
| [0]: https://frameable.com/company/tech/how-we-found-sanity-
| in-a-...
| jacobr wrote:
| Great post. It's similar to CUBE, https://cube.fyi and the
| creator of CUBE even wrote about using "Tailwind as the U in
| CUBE"
| Gualdrapo wrote:
| > Where is treatment of CSS variables that pierce the shadow
| DOM and allow global theming of such components?
|
| I feel like, at least with that one, was left behind because
| there's some work left to do in that regard.
|
| For the redesign of my portfolio, miler.codeberg.page, I used
| icons I did for the previous one (and did some new ones, but
| all are a bunch of <symbol>s in a single file) but instead of
| "injecting" the SVG code in the HTML I tried to use them from
| CSS as pseudoelements (as a 'content' fragment identifier) and
| style them (stroke color).
|
| The state of things right now, as I learned, is that it's
| impossible to do that - neither with some obscure parameter
| within the SVG fragment identifiers. I had to do some crop
| filter trickery to "change" their stroke color.
| azangru wrote:
| > I tried to use them from CSS as pseudoelements (as a
| 'content' fragment identifier) and style them (stroke color).
|
| Isn't this just the general problem of loading an svg as an
| image via a link as opposed to injecting it into the DOM as
| inline svg? How would any of the existing CSS approaches help
| (or how would web components hider) this one?
| alwillis wrote:
| There's also no mention of CSS Cascade Layers [1].
|
| [1]: https://css-tricks.com/css-cascade-layers/
| tln wrote:
| The article does mention them... I'm just finding out about
| this, it could be very useful!
|
| https://frontendmastery.com/posts/the-evolution-of-
| scalable-....
| dtagames wrote:
| Indeed. It's web components and the shadow DOM that fix all of
| this.
| aphexairlines wrote:
| There's still no good way of publishing an npm package with
| multiple components, stylesheets per component, and transitive
| consumers using only the stylesheets for the components they
| reference while rendering fully server side. CSS is still not
| scalable.
| spankalee wrote:
| This is what native CSS module scripts solve.
|
| You can import CSS directly into JavaScript modules:
| import styles from './styles.css' assert {type: 'css'};
|
| https://web.dev/css-module-scripts/
|
| Live example:
| https://lit.dev/playground/#gist=f0bdd3b5db5e4a404297e695305...
| jacobr wrote:
| SSR was mentioned though.
| c-smile wrote:
| FYI, component styles in Sciter can be placed directly in JS
| module using `CSS.set` string literal (gets compiled at runtime
| to special style set object).
|
| The style set is a collection of styles rules local (rooted at)
| to the component. :root denotes the component to which styleset
| is applied.
|
| The style set definition is strictly local to the component -
| rules inside it do not pollute global style table. That is close
| to <style scoped> to anyone who remember such thing.
|
| Here is how styled component.js module looks like:
| const padding = "12px"; const styleset = CSS.set`
| :root { color: var(--theme-color);
| padding:${padding}; background: var(--theme-back);
| } :root > em { color: gold;
| }` export class TestComponent extends Element {
| render() { return <div styleset={styleset}>
| Hello <em>Embedded</em> Style Set </div>; }
| }
|
| IMHO, that's the best of two worlds - components may have local
| styles principal for their operation, and to use global styles
| that define macro properties like themed colors, etc.
| spankalee wrote:
| This is almost exactly how Lit works in browsers. CSS is
| included with a css`` template string, that contains standard
| CSS. :host is used to select the host element, as is standard.
| @customElement('simple-greeting') class SimpleGreeting
| extends LitElement { static styles = css`
| :host { display: flex; }
| p { color: blue; } `;
| render() { return html`<p>Hello, World!</p>`;
| } }
|
| So you get CSS that loads with components, is scoped, and
| bundles without plugins. It's pretty great.
| c-smile wrote:
| Yes, that's close.
|
| Only one thing: that static styles construct shall eventually
| go into a separate <style> DOM element inside shadow root.
| Probably not a big deal if there are not that many such
| components.
| spankalee wrote:
| Actually, we add the stylesheet objects directly to the
| shadow root, so they're shared and there's no <style> tags
| (on supported browsers).
| abathur wrote:
| > Let's take a break from all these principles and architectures,
| and remember that CSS is ultimately about implementing visual
| designs.
|
| I enjoyed the overview (though the web component/shadow Dom bits
| others noted here would have been nice) but I feel like there's a
| missing realization lurking at the center of this history: the
| separation of concerns in the web stack was designed for
| documents, not layouts or visual designs.
|
| Much of the struggling we've seen over the decades is because the
| separations aren't aligned with how we're using them. It makes
| sense for documents to have separate stylesheets. It doesn't make
| sense to fragment the implementation of a layout across several
| files and complexly-interacting languages.
|
| This isn't really a fault of the article. I only just realized
| this in the past year myself and I've been writing html since the
| all caps era. I took a first swing at writing about this recently
| in: https://t-ravis.com/post/doc/what_color_is_your_markup/
| TimTheTinker wrote:
| Jesse James Garrett (the early web luminary who coined the term
| "ajax") was already talking about the dual purposes of the web
| in the year 2000. He called them "Web as software interface"
| and "Web as hypertext system".
|
| In _The Elements of User Experience_ (2000) he writes: "The
| Web was originally conceived as a hypertextual information
| space; but the development of increasingly sophisticated front-
| and back-end technologies has fostered its use as a remote
| software interface." [0]
|
| [0] http://www.jjg.net/elements/pdf/elements.pdf
| wwweston wrote:
| > I feel like there's a missing realization lurking at the
| center of this history: the separation of concerns in the web
| stack was designed for documents, not layouts or visual
| designs.
|
| I think that realization had solidly set-in throughout the
| industry by 2010 or so, and why so much effort over the most
| recent decade went into things that do lend themselves to an
| app-like focus such as native flexbox & grid capabilities,
| shadow dom, and even recent things like :has().
|
| But personally... I think that "apps as documents" paradigm has
| actually worked out pretty brilliantly, even considering how
| squirrelly CSS can be. The inspectability of the UI layer is
| one of the reasons why the browser is so much more than the VM
| that lived, and HTML/CSS has so much flexibility that many
| native UI toolkits lack. It's not right for every situation,
| but for the common case I think there are reasons it's often
| what people reach for first.
| abathur wrote:
| It's an incredibly flexible toolkit. Not calling it bad!
|
| It just isn't cut along the seams we'd cut it along if we
| were building it fresh.
|
| There's tons of evidence in the record-of-innovation that
| people are iterating around these problems--so I suspect
| there are plenty of people who have indeed internalized this
| to some degree. But I also see a lot of continual coverage
| that indicates this realization hasn't diffused.
|
| (I don't want to pretend to have invented the wheel, but for
| example I see the fights around semantic VS functional
| tailwind-style css as hinging on this. Functional css makes
| sense for layouts as it collapses pointless separation;
| semantic classes make sense for documents which are more
| likely to evolve or get restyled without new markup.)
| stevebmark wrote:
| Good article. I would have liked to see the article sternly
| advise against all CSS naming schemes like OOCSS. All CSS classes
| go into the global namespace, the solution is obviously not hand
| written naming conventions, it's getting rid of the global
| namespace itself. OOCSS is like saying "we have to put our entire
| program in index.js at the top level, how do we name things to
| avoid conflicts?"
|
| CSS is a fully solved problem: CSS modules combined with global
| utility classes. You probably want sass too, but the important
| thing is you're writing CSS, and font have to figure out the DSL,
| translation, and plugins needed to use CSS features.
| spankalee wrote:
| It's solved natively without build tools too: native CSS module
| scripts for importing and shadow DOM for applying the styles
| with scoping.
| andix wrote:
| Tailwind is the solution to most CSS issues. You can also add so
| many customizations into their config file. There are just a few
| things that can't be done with tailwind natively.
|
| With tailwind and react you now only write JSX files. Not
| separate files/sections for HTML, JavaScript and CSS your mind
| constantly needs to connect, although they are split up. Huge
| plus for someone with a goldfish brain like me, that's getting
| super confused with more then 5 files open in the editor.
|
| And with tailwind 3.2 they finally allow multiple config files,
| so you can easily have multiple tailwind instances inside one
| project. For example one config for the website and another one
| for the admin-panel.
| swyx wrote:
| this is a great history of the development of CSS up til
| Tailwind. I think there us one more subtle benefit to tailwind
| not mentioned:
|
| Using "design system" values - every color and width variable
| comes with well chosen constraints!
|
| (from my take on this https://www.swyx.io/why-tailwind)
| zagrebian wrote:
| How do I disable dark mode on that website? I can't read text
| very well in dark mode.
| vulcan01 wrote:
| I don't think there's that option, but the page does work well
| with reader mode.
| [deleted]
| ozten wrote:
| Is there a resource designed for both designers and developers to
| aid adopting design tokens?
| krono wrote:
| This W3C Design Tokens working group might be of interest to
| you: https://github.com/design-tokens
|
| Ever so slightly more details in my own top-level comment
| https://news.ycombinator.com/item?id=33575191
| Eduard wrote:
| I never understood this with BEM: .nav {
| &__link { } }
|
| Why not this?: .nav { a { }
| }
| achairapart wrote:
| To avoid CSS inheritance & specificity, the "Cascading" part of
| CSS is the actual root of all evil. If you think about it, all
| the modern approaches to CSS (BEM, Atomic CSS, OOCSS) try to
| avoid it all cost.
| jaredcwhite wrote:
| Exactly. I've never written strict BEM, mainly just take a few
| cues from it now and then. When writing components and
| especially now that we have awesome low-specificity selectors
| like :where or cascade layers (and soon :has !!), it's really
| better to just target the DOM structure with semantic/custom
| element names, parent-child relationships, states like aria,
| etc. and not saddle every single element with some kind of
| naming convention. (I honestly don't use `class` much at all
| anymore.)
| matsemann wrote:
| My favorite implementation of CSS systems has to be elm-css. Your
| CSS is just normal elm code included in your view code. E.g.
| everything is an expression, so can import reusable CSS, compose
| it from different blocks, have functions calculating the CSS
| runtime etc. Then runtime the rules are compiled to classes and
| applied to the elements.
|
| One nice thing about this is that instead of using classes, you
| can instead statically import the definition and apply it to your
| element, making it even fail compilation time if you remove some
| global styling some component still relies on.
|
| And the CSS itself is typed. So the project will not compile if
| you write invalid css.
| jamescostian wrote:
| For anyone else trying to understand how this fits in, it's
| either the "Inline Styles" section or the "CSS in JS" section,
| as long as you use typescript and follow the same rules
| mentioned here
| matsemann wrote:
| If I were to explain it in terms of react, it would be to use
| <Component style={{mystyle: someValue}} /> everywhere. Except
| that you also can define nested stuff, media queries,
| hover/active states, pseudo-elements etc. So yeah,
| syntactically a bit more like CSS in JS / JSS, but much more
| ergonomic, and much more easily composable.
| MrJohz wrote:
| Fwiw, most CSS-in-JS libraries don't use `style` directly,
| and so also allow the same features. One thing I've seen
| often is to use a `css` pseudo-prop so that it looks a bit
| like using `style` (but you've still got access to the full
| force of normal CSS rules).
|
| My favourite variation of this so far has been typestyle,
| which I believe works along essentially the same principles
| as in Elm.
| jamescostian wrote:
| It sounds like you have experience with the string-heavy
| CSS in JS. Here's some examples showing how this can be
| achieved using `csstype.Properties` objects:
| https://emotion.sh/docs/typescript
|
| I'm sure you can imagine how easy it is to compose
| functions that accept and return `csstype.Properties`
| objects, and then at the end, you call `styled` with it to
| make a styled component. You can even pass styled a
| function, which takes in runtime-adjustable props, and of
| course, that function can itself use other functions,
| passing around those same or some derived runtime-
| adjustable props.
|
| That said, I have no idea what you mean when you talk about
| ergonomics being better, can you elaborate? I re-read your
| initial comment but there wasn't anything in it not
| achievable in TS using the kinds of things mentioned in the
| "CSS in JS" section, perhaps there's something else I'm
| just not aware of? I do not know elm, let alone have
| experience writing it in non-trivial production codebases,
| so a concrete example would be great
| matsemann wrote:
| Thanks for some explanation. And yeah, I'm probably not
| up to date on CSS-in-JS, just remember it being really
| clunky to use before I ended up in an elm-shop a few
| years back. I'd say that emotion does look similar to
| what I've described, and nearly there. And I don't think
| there is anything doable in elm that's not doable in
| TS/React (it's rather the opposite, elm is the restricted
| one, mainly on purpose). My point about ergonomics was
| mostly that it's just elm all the way. No strings or
| objects or new concepts. The CSS you write in elm is
| mostly indistinguishable from the other elm view code
| (html etc) you write, it's all the same syntax etc. While
| for emotion and others, there is a clear divide in what's
| React and what's styling, and difference in how you do
| stuff.
| jacobr wrote:
| > Tailwind and CSS in JS libraries that pre-compile to Atomic CSS
| solve the problems of bloated CSS files full of duplicated rules.
|
| > With Atomic CSS, the growth of CSS is tied to the number of
| unique styles used, not the amount of features developers are
| shipping.
|
| > For example, it's common to reuse certain properties like flex
| everywhere. Rather than have these duplicated in stylesheets
| under different class names, we only pay that cost once. This is
| true for each property/value combination.
|
| This is true in theory and when you stick to the very basic
| stateless utility classes. Check the CSS of any larger site using
| Tailwind and search for a CSS rule, you will see things like
| .opacity-100 { opacity:1 }
| .hover\:opacity-100:hover { opacity:1 }
| .group\:focus-within .group-focus-within\:opacity-100 {
| opacity:1 }
|
| and that's not counting media queries, dark mode, etc. In
| practice, the global CSS file that you load for every single page
| _does_ grow for every feature you ship, since you use more of
| Tailwind.
| jaredcwhite wrote:
| Reading an article about the evolution of CSS and ending up
| at...Tailwind...really feels like a bait and switch. I don't
| consider Tailwind at all a "solution" for writing scaleable CSS.
| It's a non-standard DSL for providing styling commands to a build
| tool, and the HTML/CSS output overloads class attributes
| everywhere in an absurd way. The "just use @apply" retort is also
| a non-starter if you want to write stylesheets that aren't
| vendor-locked to Tailwind's build tooling.
|
| I'm actually working on a large design system that's in the
| process of stripping Tailwind _out_, because it's in fact _not_
| scaleable if you want to provide vanilla component styling APIs
| via custom properties. And as some others here have mentioned, we
| 're not even talking yet about web components, shadow DOM, shadow
| parts, etc.
|
| Scaleable CSS should adhere to the actual spec of CSS and how its
| evolving in browsers. Tailwind is a massive, non-standard
| deviation from the development of CSS.
| alehlopeh wrote:
| The conclusion I took from the article was that CSS simply
| isn't scalable. I've been hearing about web components for
| years and nothing seems to have materialized. I've never built
| something where I thought to even use shadow DOM. Tailwind is
| the only solution that meets the stated aims. If tailwind
| doesn't adhere to the dogma for how CSS should work in
| principle, well that's a lovely problem to have.
| dogcomplex wrote:
| Tailwind's just a shorthand style for writing [a particular
| snapshotted older version of] CSS based on the theory that
| saving on keystrokes is worth more than understandable naming.
| It then leverages this brevity to let people over-define styles
| directly in the HTML, which would otherwise take paragraphs of
| normal CSS and therefore be unwieldy to do (so you'd just alias
| it into a new CSS property in a separate file). That's about
| it.
|
| While brevity is a nice feature, and we should always strive to
| make the dev experience as elegant and simple as possible,
| methinks Tailwind is just asking to become yet another dead-end
| standard which I very much hope has a standardized compiler
| back to vanilla CSS. (Does it not?)
___________________________________________________________________
(page generated 2022-11-12 23:01 UTC)