[HN Gopher] Show HN: Compiled, buildtime atomic CSS in JavaScrip...
___________________________________________________________________
Show HN: Compiled, buildtime atomic CSS in JavaScript and all your
favorite APIs
Author : madou
Score : 47 points
Date : 2021-01-02 06:49 UTC (16 hours ago)
(HTM) web link (compiledcssinjs.com)
(TXT) w3m dump (compiledcssinjs.com)
| austinjp wrote:
| Personally I'm a fan of cxs [0] which is (or purports to be)
| atomic among other strengths. From the readme: -
| 0.7 KB (gzipped) - Zero dependencies - High
| performance ("fast af") - Deduplicates repeated styles
| - Dead-code elimination - Media queries and pseudoclasses
| supported
|
| Works with any framework or with none, apparently, although I've
| only used it with Preact. Supports themes. Everything I need and
| nothing I don't.
|
| [0] https://github.com/cxs-css/cxs
| jitl wrote:
| I think csx is probably the best choice amongst the compute-
| styles-at-runtime CSS-in-JS libraries. The brutal simplicity
| has a lot to offer. For most projects csx is perfectly fine.
| However it can't beat a more complex zero-runtime precompiled
| styles system on paper -- but it's an optimization tradeoff you
| could choose if you need it in the future.
| [deleted]
| pestatije wrote:
| What was wrong again with runtime CSS? By the smell of it seems
| to be performance, so: can somebody point to performance
| comparisons, or give a brief of the advantages?
| mStreamTeam wrote:
| There's nothing wrong with runtime CSS. Frontend devs just like
| to come up with elaborate solutions to problems that don't
| exist
| simonmales wrote:
| From my understanding of frontend performance, JS parsing is
| blocking.
|
| So reducing the JS "load" is a performance win on the client.
| jitl wrote:
| It's all about time to interactive.
|
| For a big complex app (eg, https://www.notion.so which I work
| on), a significant fraction of JS code size is spent describing
| styles. There can also be JS cycles spent doing color math like
| lighten, darken, hue shifting on base colors, etc. With runtime
| CSS-in-JS, all of that style JS code must be parsed and
| executed by the JS runtime _on every page load_ by _every
| user_. That's a lot of CPU time and user wait time multiplied
| out.
|
| Zero-runtime improves page load performance by moving this
| extra code from the JS vm to static CSS files. The majority of
| style computation happens at build time. The CSS can then be
| downloaded and parsed _in parallel_ with the JS (woo threads?).
| The separation _may_ improve caching compared to all-JS
| solution as well, depending on how granular the CSS and JS
| output files are.
| pii wrote:
| hamburger emoji for a menu icon is for sure an underused design
| pattern
| barbarbar wrote:
| Indeed. But it will take of now. Everybody wants to click that
| delicious hamburger.
| fastball wrote:
| Doesn't @emotion's babel plugin already do this, or am I missing
| something?
| lf-non wrote:
| Not quite. Emotion doesn't do the atomic splitting - ie. one
| class name per style rule. This splitting results in ugly
| looking HTML but if two components are using some common subset
| of CSS rules they will partially reuse the same css classes.
|
| It is closer to https://www.styletron.org/ in that regard.
| niksmac wrote:
| Isn't this the same as Styletron is doing?
| https://www.styletron.org
| jitl wrote:
| Styletron create "atomic" (single property) CSS classes as your
| application runs in production because it has no macro,
| compiler, or bundled plugin. "Build-time" means the CSS is
| somehow extracted from the JS files and inserted into HTML or
| static CSS files during the bundling process, so that the JS to
| compute the styles never runs on the client/production. There's
| only whatever code is needed to add the generated class names
| to the DOM nodes created by React (etc) when the app runs.
| [deleted]
| jitl wrote:
| The differentiating feature of Atlassian's @compiled package is
| not the "build time atomic css" - it's that you can distribute
| components that use @compiled on NPM without requiring your
| consumer to futz with Webpack include paths for e.g. CSS files.
| Do I have that right? @madou is the extraction shipping yet? The
| docs have a few places that say "coming in 2021" - what's the
| status?
|
| For those interested in build-time CSS in JS, also called Zero-
| runtime CSS in JS, you might also want to check out:
|
| - Linaria (https://github.com/callstack/linaria) I use on my
| personal site. I ran into trouble/bugs trying to integrate it
| with Notion's build process; the Webpack/babel bits are very
| brittle.
|
| - Treat requires that you write the JS that computes your styles
| in esperare xxx.treat.js files which is annoying from my point of
| view - I want single file components. (https://seek-
| oss.github.io/treat/)
|
| - No idea about this one, but it's more recent. Has some other
| interesting things in the inspiration section of the README
| https://github.com/CraigCav/css-zero
| nwienert wrote:
| I've been working on one that runs on top of React Native Web.
| Compiles to atomic CSS on web, and StyleSheet on native.
|
| It marries in-line style props (like JSXStyle) with SwiftUI
| style stack views.
|
| It's very much alpha, on my GitHub.
| have_faith wrote:
| Have also been using Linaria on a side project recently,
| enjoying it a lot so far. I skipped most of the other css-in-js
| solutions when I saw they where using runtime js to manipulate
| styling which intuitively just feels unnecessary for 99% of the
| pages style. Very happy with Linaria so far.
| [deleted]
| crituquie wrote:
| why? css exists because one shoud not need js just for styling!
| js is dangerous for me!
| mouzogu wrote:
| why is there such a prevalence of mawkish phraseology in the
| javascript community...
|
| i was reading the landing page for a js library and it said
| something like "battery-pack included", makes me feel kind
| sick....or maybe i'm just a grumpy sod
| iaml wrote:
| "Batteries included" was invented by rails folks IIRC.
| iddan wrote:
| I was building a similar solution 4 years ago [1] but got stuck
| with integration to Webpack. I'm very glad someone succeeded to
| do so. [1]: https://github.com/iddan/stylesheet
| christophilus wrote:
| There are already quite a few alternatives in the comments, but
| I'll just add that I have really come around to the Tailwind way
| of doing this. On my current project, I haven't had to write much
| CSS at all other than a handful of animations, and it all looks
| consistent and custom. It's a breath of fresh air.
| Traubenfuchs wrote:
| Could someone please explain the following line to me?
|
| export const Button = styled.button``;
|
| Why is there a string right after the field "button" of the
| object "styled"? How is this valid JS? What does it do?
| lucideer wrote:
| I don't know why that space is there, it could be accidental or
| a deliberate stylistic quirk of the author, but it seems
| harmless (if not idiomatic).
|
| > _How is this valid JS? What does it do?_
|
| I'm curious if Python (or a similar whitespace-sensitive
| syntax) is your first/familiar programming language.
|
| The extra whitespace here does nothing.
|
| The semicolon in JS is an (optional) expression separator,
| similar to in Bash/Shell. It can occur at the end of a line or
| at the beginning of a line, or in between lines. Or in between
| two expressions on a single line. Any whitespace chars before
| or after it are irrelevant/ignored.
| commotionfever wrote:
| checkout javascript "template literal tags"
|
| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
| [deleted]
| tobr wrote:
| Yet another case of documentation saying "JS" when they mean
| "React, specifically". Every single example I can see here uses
| React, but if this deserves the CSS-in-JS moniker, please give at
| least one example of usage with vanilla JS. It's like peak jQuery
| all over again.
| ljm wrote:
| We're probably at that point again where a developer 'knows'
| React but will completely flounder when faced with anything
| outside of that ecosystem. Same with jQuery, same with Rails
| and Ruby.
| RobertKerans wrote:
| I've started seeing this quite a lot recently when working
| with beginners. Worst one recently was someone who had
| extreme difficulty understanding how to make different web
| pages using only HTML, but much more mild versions of this
| have been cropping up in frequently for me over the last
| year.
| bryanrasmussen wrote:
| Since JavaScript evolved to incorporate many of the APIs that
| jQuery pioneered at some point knowing only jQuery was not
| such a problem.
|
| But even before this evolution much of jQuery was just sugar
| to make cross-browser problems manageable.
|
| I am not actually aware, I think, of any developer that just
| knows React but if they exist I suspect they would have an
| even harder time of it when deprived of their favored
| framework than those developers back in the day that just
| knew jQuery.
| austincheney wrote:
| Query selectors likely came from jQuery's Sizzle engine,
| but most of the jQuery APIs, all methods, were never
| adopted. The best I can think of that did get adopted is
| _closest_ which uses a query selector to find a matching
| ancestor node.
|
| The reason why most of the jQuery approach is not adopted
| is because it is so incredibly slow. First you have to
| consider that query selectors, at their best performance
| (Google Chrome), are about 460x slow than the old DOM
| methods. All the jQuery approaches would be slowness that
| multiplies on top of the already slow query selectors. In
| Firefox query selectors are about 10,000x to 250,000x
| slower than the standard DOM methods.
|
| From a standards perspective there is no incentive to go
| down that path as it cripples the interface it describes.
| jokethrowaway wrote:
| I see it all the time.
|
| Tons of developers coming out of bootcamps (and even a few
| designers with no coding experience) who know how to string
| together a few react components but have problems with basic
| JS.
|
| It's not necessarily bad, it's just higher level coding.
| What's bad is when these people get hired as engineers.
| swiley wrote:
| So you took something written in a regular grammar and made it
| into the same thing except with a very complex context free
| grammar with support for recursion?
|
| I hate to be a grumpy puss but using this sounds like a step
| backwards.
| jitl wrote:
| Well, in the long run we've learned that maintaining a large
| and complex UI's CSS by hand is very tedious and error-prone. A
| miss configured style that, for example, makes the Airbnb "Book
| It" unreadable for some % of the population can lose millions
| of dollars, but never throw a stack trace.
|
| So, engineers working on UI toolkits often reach for CSS code
| generation to ease maintenance. At first it was all PHP
| templates. Then it was Sass (206), is a popular purpose-built
| language for generating CSS which saw a lot of use in the Rails
| community. Sass is very good at its job because it handles a
| lot of CSS niceties in nice ways, but it's a lot of extremely
| domain specific complexity. A whole new Turing-complete
| language _JUST_ for CSS? Not ideal.
|
| The next step is to move all the UI definition into a single
| place, i using a single language that abstracts the underlying
| HTML/CSS/JS files & semantics. We do that by writing JS, and
| having a compiler program extract the CSS bits. This gets us
| ideal performance & ideal maintainability at the cost of build
| complexity. This is a worth while trade, because in the long
| run the compiler will get so good that the cost becomes
| minimal; compare to other ecosystems, for example the Kotlin
| compiler is quite complex, but I never think about x86 assembly
| when writing Kotlin.
| rualca wrote:
| > The next step is to move all the UI definition into a
| single place, i using a single language that abstracts the
| underlying HTML/CSS/JS files & semantics.
|
| That sounds like a gigantic step backwards, and one which
| does not follow the example you've mentioned.
|
| The point of Sass was to introduce backwards-incompatible
| changes to CSS which adds nice human-readable syntactic sugar
| to CSS. Being turing-complete is besides the point and even
| it's regular use. In fact, I worked in projects where Sass
| was introduced just for it's support for nesting and partials
| alone.
|
| Mixing content and presentation in scripts misses any of the
| lessons from the last couple of decades. It feels like yet
| another example of the cargo cult of javascript, where people
| mindlessly argue that dragging everything into a script
| solves anything at all.
| ratww wrote:
| _> Mixing content and presentation in scripts misses any of
| the lessons from the last couple of decades_
|
| If you're using React or Vue, chances are your content is
| coming from JSON in fetch requests, etc, not from the
| HTML/JSX in your components. In those cases _HTML /JSX is
| the presentation_. The content/presentation separation
| still exists.
| mattlondon wrote:
| > Mixing content and presentation in scripts misses any of
| the lessons from the last couple of decades.
|
| Agreed - although this is not a JavaScript thing, but a
| react thing I think (maybe also Vue? No idea about that).
| E.g. Angular still has CSS (actually SASS) and HTML in
| separate dedicated files, and then a another separate file
| that contains the JavaScript (actually typescript) for the
| logic itself.
|
| I do not see the benefit _at all_ of putting all these
| things in one single file, apart from trivial tiny simple
| things (angular allows you to create single-file components
| for instance) or for making "To-Do with React" type
| tutorials look easy. Once you get more than 100-200 lines
| of code + html + CSS then it is time to separate the files.
| jitl wrote:
| I would rather have my files be Page.component,
| Header.component, Details.component, Article.component
| than have my three files be Page.html, Page.css, Page.js.
|
| What is the benefit of separating code by file type? If
| your reasoning is to reduce coupling, I think this is
| false simplification - again, in complex applications
| with lots of interaction, there is no escaping the
| coupling of DOM nodes, JS logic, and styles. Any feature
| changes change is going to need to modify all three.
| Maybe for a mostly read-only site de-coupling these
| things makes sense, and you can achieve your goals with
| something like Bootstrap, where you compose a bunch of
| reusable CSS classes. But for the majority of work I've
| done over the last 8 years, that decoupling model doesn't
| work. It's an even harder nest of snakes when you
| multiply 3 screen sizes x 2 input methods x N pages where
| CSS could be used - again for something simple, it's fine
| to just collapse columns on mobile (the typical CSS
| column-css-6 style) but frequently you want this stuff to
| be much more responsive to user device and input than
| decoupled styles allows.
| rualca wrote:
| > I would rather have my files be Page.component,
| Header.component, Details.component, Article.component
| than have my three files be Page.html, Page.css, Page.js.
|
| ...except that Page.css at most only adds minor tweaks
| that cascade over the site's styling, and arguably
| already should be a part of the site's main styling
| definitions.
|
| > What is the benefit of separating code by file type?
|
| Separation of concerns. This lesson was learned the hard
| way. Must we keep on relearning it?
|
| > I think this is false simplification - again, in
| complex applications with lots of interaction, there is
| no escaping the coupling of DOM nodes, JS logic, and
| styles.
|
| This assertion is quite wrong and misguided. Styling is a
| property of a site's visual identity. It is not a
| property of a component or a specific interaction state.
| Any well-designed site follows a uniform visual identity
| which spans over all aspects pertaining to user
| interactions. Moreover, UI components are also uniform
| and reused. There is no excuse.
| robertoandred wrote:
| React doesn't require mixing styles and content. You can
| use regular CSS files just fine.
| jokethrowaway wrote:
| Then you go back to HTML with attributes to control style,
| which is where we were before CSS.
|
| It's good to have a level of separation between style and
| content. The problem with HTML and CSS is that often times
| you need to change your HTML to change the style of your
| application.
|
| This is because HTML+CSS was meant to be for documents. It
| took ages to evolve into what we have today and it still has
| a lot of baggage. Designing apps with it is a hack which
| became mainstream.
|
| If we want to improve the situation, I think we need a couple
| of standards to define application content and application
| style which can be compiled to HTML + CSS (as browsers are
| probably going to stay around for a bit longer).
|
| Component based libraries (like react) are well placed to do
| something like this and it would help developers faced with
| this uneven separation of style, content and markup.
| jitl wrote:
| I view the current Cambrian explosion of CSS-in-JS
| approaches as a distributed search for the "new standard".
| Better to have 1000s of developers working on the problem
| then have 6 people on a committee make another bad, short-
| sited standard that becomes "cruft" in 4 years.
|
| If you views React's JSX as the "content" part of
| content/style break, then we're not too far off. It
| compiles down to HTML :)
___________________________________________________________________
(page generated 2021-01-02 23:02 UTC)