Vanilla CSS is all you need
64 points by eduard
64 points by eduard
You don't "need" css for anything so I take the thesis statement of the article as "vanilla css is now easy enough you don't need build tools". Nothing in this article precedes build tools making any of these examples easier. The AI editing of the prose makes it annoying to read and the purple prose generated by the AI obscures any valuable observations - just "you can do this thing this way" with no mention of the trade-offs (or a trade-off framed as benefits, like "more custom css" as "HTML stays readable"). Maybe writing everything from scratch works when you're a team of highly skilled css experts but I don't think this makes the case for it.
(On an unrelated note I feel like this article was initially written by bunging all 3 css directories into some kind of LLM workspace and asking it to generate the article text.)
The article doesn’t read as AI written to me.
It’s unfortunate that we’ll always have this doubt from now on but I wish we’d stop saying everything is AI. There’s no way to reliably prove so. Every other article there’s someone in the comments claiming slop with really no way of telling.
It’s just dismissive in a different way. There’s plenty content in this article that is not regularly seen elsewhere and newer techniques worth discussing.
—————
Your non-LLM critique seems to be that nothing shown here existed before build tools therefore build tools helped drive these CSS innovations. That’s just not true for many of the techniques in the article, for example animations and starting style, capabilities-based media queries, or the circle text marker.
At the risk of veering away from the point of the article, I am seeing some telltale signs of LLM edited/written text. Here are specifics phrases that I know Claude uses a lot:
I think that the article still has valid points but these LLM-isms make it a very jarring read for me.
The more obvious sign is the footer saying
Ruby on Rails developer leveraging AI tools and practical workflows. Sharing my experiences and learnings.
but regardless of that, I think it's worth elaborating why it's jarring to read, rather that just saying "it's written by LLM" or coming up with examples that LLMs sometimes dish out.
A lot of the "sentences" are super short and omit so many words there's sometimes a chain of three or four incomplete sentences in a row. For me, that's very hard to read, especially when some of these three word-sentences make no sense given the context, or doesn't explain enough. For example:
The
background: currentColormeans it automatically inherits the text color. Works in any context, any theme, any color scheme. Zero additional assets. Pure CSS creativity.
In this case, why does this paragraph about currentColor talk about "Zero additional assets"? And I don't get why this is pure CSS creativity, as this is literally the CSS example for currentColor on MDN.
Sure, the last sentence is probably just flowery language, but reading a bit further, we get to dialog animations. There it says
[...] The modal smoothly scales and fades in. The backdrop fades independently. [...]
and I genuinely don't know what is meant by "The backdrop fades independently". This could be just nonsensical text generated by an LLM, but it could also be something important in the example here that I don't get.
I agree that the short sentences are harder to read. I think it’s because the reader must infer how those ideas relate to each other. For example, in this paragraph from the article:
This is CSS doing what you used to need JavaScript for. State management. Conditional rendering. Parent selection. All declarative. All in stylesheets.
Some of those sentence fragments are examples of “what you used to need JavaScript for”, and some are not. A phrasing that would make that clearer: “This is CSS doing what you used to need JavaScript for: state management, conditional rendering, and parent selection – all declaratively and within stylesheets.”
But I was able to figure out what the sentence fragments you quoted referred to after some thought. So, in reply to your comment:
In this case, why does this paragraph about
currentColortalk about "Zero additional assets"?
It’s probably comparing this approach with having two separate image assets, wavy-dots-white.svg and wavy-dots-black.svg. The designer would have to choose which of those images to embed depending on the background color.
It might also be comparing this approach of drawing dots with CSS radial-gradient and making them move with animation to having one additional image asset, wavy-dots-responsive.svg, that draws animated circles using SVG. (The reason a single SVG asset could work is that you could use CSS to make the fill color of the SVG circles responsive, using either currentColor or @media (prefers-color-scheme: dark)-specific rules.)
And I don't get why this is pure CSS creativity, as this is literally the CSS example for currentColor on MDN.
“Pure” is hyperbole, but I think the creativity is in noticing that the currentColor property can affect these CSS-drawn dots. The MDN example you linked only shows the color of text changing – it’s far from being “literally” the same as the article’s example.
I genuinely don't know what is meant by "The backdrop fades independently"
The sentence makes sense to me. It contrasts how the .dialog animates transitions of these two properties:
opacity from 0 to 1
transform from scale(0.2) to scale(1)
While the .dialog::backdrop animates transition of this one property, and that property has a different ending value:
opacity from 0 to 0.5
But I was able to figure out what the sentence fragments you quoted referred to after some thought.
It's good to see that it's possible to infer some meaning from it with a bit of effort, though I hope that obtuse stylistic writing forms won't replace clear sentences (man-made or otherwise).
The MDN example you linked only shows the color of text changing – it’s far from being “literally” the same as the article’s example.
I think it's silly to derail this even further with comments on your interpretations, but one thing I'll note is that the MDN example I linked to has this CSS:
.container {
color: blue;
border: 1px dashed currentColor;
}
.child {
background: currentColor;
height: 9px;
}
I agree that we can debate whether it's obvious or not (I think it is), but my main point was that background: currentColor; is literally used in the MDN example.
"This is CSS doing what you used to need JavaScript for: state management, conditional rendering, and parent selection – all declaratively and within stylesheets."
I find it funny you use this exact suggestion: if the article had contained this exact sentence how many people do you reckon would've called it out as likely being AI for using an em-dash?
I did think about that risk, which is why I purposely typed an en dash ‘–’ (and surrounded it with spaces) instead of an em dash ‘—’ (which never has spaces). But indeed, not everybody can tell the difference. I’ve even seen a commenter on another site perceive text like ‘foo - bar’ as containing an em dash.
Claude uses those phrases a lot because it was trained on text that uses those phrases a lot. The critique is basically that the author uses a lot of clichés, which is true, but clichés are by definition common.
It's valid to criticize writing for things you find jarring, of course. And I'd agree it's not the best writing. But it's not very strong evidence at all and it's not even particularly relevant to the discussion IMHO.
I also think it's a shame "Is this AI?" is a constant question now. At the same time, there was something about this article that made me go straight to the comments, because I wanted to know if other people were thinking the same thing! And I liked the article, but I was still distracted from the points he was trying to make.
Maybe it's better to say this: LLMs have made us all aware of a specific writing style that is grating, regardless of provenance. Even if no AI was involved, the author should still ease up on all those short clippy sentences.
There are very strong and obvious tells for anyone who uses AI tools extensively. At least to me, it was very obvious. Pangram [0] has a solid classifier, and it detected ~55% AI generated (ie, almost all the non-code parts). But again, I didn't need that tool because the tells were obvious. [1]
I definitely believe it's worth pointing out when we see AI-generated text, and dismissing the contents even when the content is solid. It's rude to push AI content on others because there's an asymmetry: it's easy to produce it unthinkingly, and more work to read, absorb and do all sorts of checks to see if the text isn't generated without sufficient context fed to it, or if there are any confabulations.
I write a bit more about this issue here, which I feel strongly about: https://atharvaraykar.com/slop/
[0]: no affiliation, I just like their product, it seems to be genuinely solid
[1]: this good summary of AI-isms, which go deeper than cosmetic em-dash type stuff. and also this comprehensive one from wikipedia
That wasn't my non-LLM critique at all. It just isn't demonstrated by the article that the benefits of doing this with pure css outweigh the benefits of using build tools and preprocessor, and no example made a substantive argument for it imo.
I think your first comment was misinterpreted because of this sentence: “Nothing in this article precedes build tools making any of these examples easier.” Perhaps you meant “prevents” instead of “precedes”.
The section “Utility Classes: Yes, They Still Exist” is unfair in its comparison of Tailwind with pure CSS. It doesn’t take into account Tailwind’s recommendation that “if you need to reuse some styles across multiple files, the best strategy is to create a component” in your front-end framework or templating language. So its example of a “typical Tailwind component” is incomplete.
A better comparison would use, for example, a React component:
function Button({ children }) {
return (
<button
className="inline-flex items-center gap-2 px-4 py-2 rounded-full
border border-gray-300 bg-white text-gray-900
hover:bg-gray-50 focus:ring-2 focus:ring-blue-500"
>
{children}
</button>
);
}
// Usage:
<Button>Save</Button>
This would counter all of the article’s arguments in favor of pure CSS:
class="btn btn--negative" tells you what something is, not how it looks.”
<Button color="negative">Save</Button> also concisely tells you what the element is.--btn-padding once, every button updates.”
Button once, every button updates..btn--circle without redefining every property.”
shape prop to the Button without the definition having to list every shared className again.dark:bg-black, can also be written inside the component definition.A better argument against Tailwind would be the added complexity of having a build system and a front-end framework or templating language, if your project doesn’t already have those for other reasons.
Last time i wrote complex css was in 2021, many of those are common since 2023, so good to know I don't have to use scss in my next silly project that needs frontend. I love nesting rules, but hate build systems
If HTML finally got some progressive updates basics like HTMX is adding, maybe we could get rid of the JS cancer that has ruined the web?