I tried this approach years ago. Now I consider it an anti-pattern. You really don’t want the look of your website/document to be dependent on its structure. Things like li:has( > a + p) - it seems so clever initially, but then you need to have a button instead of an a, or an icon, or a wrapper over entire thing; but only for a single item on the list. You either end up with messy CSS that covers all these scenarios, or you just go back to classes.
I kinda see a potential usefulness of custom attributes, but I’m still not entirely sure how they’d be better than classes. What’s the advantage of [shape-type="1"] over .shape-type-1?
I love the clean approach with classless. Documents do have a structure and is makes it easy to change by just swapping out the CSS without touching the document.
But could you not just add the class only when you really really need to break the structure? The middle ground for me would to do my utmost to avoid classes within reason. So as few exceptions as possible. I know this is selling elastic bands by the meter.
On the other end you have Tailwind CSS. I know many are happy with it and find it has a nice developer velocity. But I find it overly verbose and "framework of the day"-ish.
So for me it is classless until my head hurts. Then I'll sprinkle in a class to get work done.
We tried this 20 years ago with "CSS zen" and the Bad Old Days of "semantic CSS". It failed because you cannot completely couple HTML structure and presentation.
Usually you have more complex styles and visuals than your HTML can express and trying to invent selectors / HTML heirarchies to describe them gets difficult very quickly
In addition you often need to support multiple style systems on a single web application whilst the design evolves, or else it becomes an all or nothing rollout when you change stuff.
It's common for engineers who weren't around back then to look at the abstractions that modern FE systems provide, and question if they're even necessary. That's healthy. What's not healthy is assuming they were only invented for fake or historical reasons, and telling everyone to just abandon them for commercial projects.
I recently went down a similar path to build the FE of an app. It worked fine at first and I learned a whole lot about recent updates to CSS. And boy, has it come a long way. Cascade layers, nesting, and the :has selector tripple-handedly change how views can be written for the better.
It is a solid solution for blogs and apps with a distinct document feel, but for anything beyond that I found it too limiting and brittle. Back to components and Tailwind.
I don't get this comment at all; you say CSS is too limiting but somehow Tailwind, which is just applying CSS using classes is liberating?
Tailwind actually complicates a lot more things, when you have to specify variants for example, there you go installing tw-variants, writing Javascript just so you can get different sorts of buttons.
This is fine for larger component libraries like shadcn-ui, but for simplicity, I'd pick up pure CSS for something like button .error; and button .secondary.
(yes I know you can just @apply whatever you want inside those blocks, but what's the benefit of tailwind then?)
I think that's fair. It's not semantic information (I mean in a way I guess it is, but you wouldn't want a screen reader to present it as such), so classes are fine there.
Well, HTML was supposed to be a generic language to describe typical documents. Most websites don't need more than the default elements.
From an outside perspective, it is perplexing to see the constant back and forth webdevs do between making website more complex and rediscovering the simpler first principles
I am sorry but its not the devs who want complexity. Users and Designers want a snappy interactive UI with lots of animations to get the "vibe" right. Devs are usually fine with websites looking like they are straight out of 2003 (considering all the language doc pages I've seen)
Personally, I would first try to get the semantic structure of HTML right for the content I want to display. Then I would look at what I can do in CSS to make it look nice, but without going full overboard. Stick to things that are now standard in browsers, and that are responsive and resize and float nicely. Perhaps, if necessary even something like the checkbox hack, but probably try to avoid it, since it is a hack. Then the site already looks sufficiently good usually. At no point in this comes JavaScript into play, because this is about visuals, and that should be handled by HTML and CSS. I will use JS, when I have something dynamically changing and/or interactive on a page, and I will try to make a noscript alternative, perhaps usable by the user simply reloading the page.
However, I have also seen a lot of frontend devs, who just throw JS framework at everything and since everything is JS anyway, they also do things that could be simple HTML and CSS using JS instead. The result are those pages, where one is greeted by a blank white page, when not running JS.
So there definitely are a lot of devs, mostly frontend devs, that do this kinda thing, and it often secures their job by introducing complexity under the guise of looking fancy.
Example from a previous job: Making buttons that have 2 corners cut off, but the main navigation bugs regarding responsiveness, that led to broken layout took 3 months to fix. Transferring a navigation from one project to another? 3 weeks.
Frameworks are a lot simpler than building with vanilla html, css and js. At least that's my experience... Requires a lot less boilerplate too.
Regarding the noscript alternative solution. I do not know a single modern website relying on users refreshing the page to update content. Except for HN maybe. This approach is very very outdated and will frustrate users.
The refresh page thing is, as I explained, a fallback for users, who don't want to run or cannot run JS. 99% or more of the users will never see this. I personally would be grateful, if web devs took precautions and paid attention to also having a no-JS workflow for things where it is relatively simple to implement. It also has to do with accessibility. A JS-only page, that results in a blank white page has exactly zero accessibility.
I love this - and I applied the lessons to my own site. It was fascinating to see just how often I'd slapped a class on something which was never going to be re-used.
Similarly, WordPress spams tonnes of classes everywhere. Most are unused.
So I took a look at rewriting my CSS to target by logical structure, rather than just random names dotted about. It mostly worked well, although it did mean that I occasionally had to write a selector like:
I really like the concept of this. I'd love a html reference guide (pattern library?) with plain html no CSS or JS to document the basic building blocks of the web.
I like it. Nice effort. Plus I like the visual style a lot too.
I feel there's a mismatch between creating novel "semantic" elements, and then customising them in the markup, rather than the contextual approach (nesting, rich selectors). The mismatch is that the new elements still apply a "what" approach, but the attributes used for customisation apply a "how" approach and leave it in the mark-up. It's still like `<p class="red" />` rather than `main p { background-color: red; }`.
I get that there's a trade-off between purity and code that's nice to work with, and I think you've hit a very readable, appealing and creative balance.
> I removed a non-trivial amount of CSS (now about ~5KB of CSS over the wire for the entire site)
That's around 2% of the size of the single page of that article, it absolutely is a trivial amount, especially when it complexifies so much the maintenance or addition of the website.
In fairness, the page loads two enormous fonts. Lots of blogs just use system fonts, so the advice is generally useful if you're trying to reduce your own site size. The total payload without the fonts are around 12kb, so reducing the CSS to 5kb is a fairly big deal. Without the fonts, the entire site could be delivered in the first TCP packet.
I can see whole lines and select the text in a desktop Firefox, but the fonts are messed up (thinned and otherwise tweaked) and colors are set to reduce the contrast, making it hard to read. As with most of the design-related articles, I had to use the reader mode to actually read it. But the content can be guessed from the title (with a hint that it is about CSS) anyway: they have simply removed CSS class selectors, replacing them with element selectors, adding combinator selectors, pseudo-class selectors, and so on.
I tried this approach years ago. Now I consider it an anti-pattern. You really don’t want the look of your website/document to be dependent on its structure. Things like li:has( > a + p) - it seems so clever initially, but then you need to have a button instead of an a, or an icon, or a wrapper over entire thing; but only for a single item on the list. You either end up with messy CSS that covers all these scenarios, or you just go back to classes.
I kinda see a potential usefulness of custom attributes, but I’m still not entirely sure how they’d be better than classes. What’s the advantage of [shape-type="1"] over .shape-type-1?
Is there no middle ground?
I love the clean approach with classless. Documents do have a structure and is makes it easy to change by just swapping out the CSS without touching the document.
But could you not just add the class only when you really really need to break the structure? The middle ground for me would to do my utmost to avoid classes within reason. So as few exceptions as possible. I know this is selling elastic bands by the meter.
On the other end you have Tailwind CSS. I know many are happy with it and find it has a nice developer velocity. But I find it overly verbose and "framework of the day"-ish.
So for me it is classless until my head hurts. Then I'll sprinkle in a class to get work done.
We tried this 20 years ago with "CSS zen" and the Bad Old Days of "semantic CSS". It failed because you cannot completely couple HTML structure and presentation.
Usually you have more complex styles and visuals than your HTML can express and trying to invent selectors / HTML heirarchies to describe them gets difficult very quickly
In addition you often need to support multiple style systems on a single web application whilst the design evolves, or else it becomes an all or nothing rollout when you change stuff.
It's common for engineers who weren't around back then to look at the abstractions that modern FE systems provide, and question if they're even necessary. That's healthy. What's not healthy is assuming they were only invented for fake or historical reasons, and telling everyone to just abandon them for commercial projects.
I recently went down a similar path to build the FE of an app. It worked fine at first and I learned a whole lot about recent updates to CSS. And boy, has it come a long way. Cascade layers, nesting, and the :has selector tripple-handedly change how views can be written for the better.
It is a solid solution for blogs and apps with a distinct document feel, but for anything beyond that I found it too limiting and brittle. Back to components and Tailwind.
I don't get this comment at all; you say CSS is too limiting but somehow Tailwind, which is just applying CSS using classes is liberating?
Tailwind actually complicates a lot more things, when you have to specify variants for example, there you go installing tw-variants, writing Javascript just so you can get different sorts of buttons.
This is fine for larger component libraries like shadcn-ui, but for simplicity, I'd pick up pure CSS for something like button .error; and button .secondary.
(yes I know you can just @apply whatever you want inside those blocks, but what's the benefit of tailwind then?)
> you say CSS is too limiting but somehow Tailwind, which is just applying CSS using classes is liberating
If you read the article you'll see what they're talking about. It's not "CSS is too limiting" it's "CSS only applied to elements is too limiting".
Looks like I threw myself in to a Tailwind flamewar. I should've known better.
TW+TSX is easily the most productive way for me to write UIs and has been for 5 years. Don't like it? Don't use it but please leave me alone.
> Don't like it? Don't use it but please leave me alone.
That's not how HN works. HN is for discussion. If you make a comment, people can discuss.
If you want to be left alone, then perhaps "don't use" the comments section.
I've never heard anyone complain that CSS is too limiting. If anything it's the opposite.
[flagged]
Right click -> view source.
Found "<span class=..." — What?
Read the page.
Footer : "I only got 99% of the way there. I use 11ty’s syntax highlighting plugin, which uses classes for styling."
I think that's fair. It's not semantic information (I mean in a way I guess it is, but you wouldn't want a screen reader to present it as such), so classes are fine there.
It says no class though.
Yeah, that title is absurd. The page contains 175 "class=..." attributes.
Well, HTML was supposed to be a generic language to describe typical documents. Most websites don't need more than the default elements.
From an outside perspective, it is perplexing to see the constant back and forth webdevs do between making website more complex and rediscovering the simpler first principles
I am sorry but its not the devs who want complexity. Users and Designers want a snappy interactive UI with lots of animations to get the "vibe" right. Devs are usually fine with websites looking like they are straight out of 2003 (considering all the language doc pages I've seen)
That depends very much on the type of developer.
Personally, I would first try to get the semantic structure of HTML right for the content I want to display. Then I would look at what I can do in CSS to make it look nice, but without going full overboard. Stick to things that are now standard in browsers, and that are responsive and resize and float nicely. Perhaps, if necessary even something like the checkbox hack, but probably try to avoid it, since it is a hack. Then the site already looks sufficiently good usually. At no point in this comes JavaScript into play, because this is about visuals, and that should be handled by HTML and CSS. I will use JS, when I have something dynamically changing and/or interactive on a page, and I will try to make a noscript alternative, perhaps usable by the user simply reloading the page.
However, I have also seen a lot of frontend devs, who just throw JS framework at everything and since everything is JS anyway, they also do things that could be simple HTML and CSS using JS instead. The result are those pages, where one is greeted by a blank white page, when not running JS.
So there definitely are a lot of devs, mostly frontend devs, that do this kinda thing, and it often secures their job by introducing complexity under the guise of looking fancy.
Example from a previous job: Making buttons that have 2 corners cut off, but the main navigation bugs regarding responsiveness, that led to broken layout took 3 months to fix. Transferring a navigation from one project to another? 3 weeks.
Frameworks are a lot simpler than building with vanilla html, css and js. At least that's my experience... Requires a lot less boilerplate too.
Regarding the noscript alternative solution. I do not know a single modern website relying on users refreshing the page to update content. Except for HN maybe. This approach is very very outdated and will frustrate users.
The refresh page thing is, as I explained, a fallback for users, who don't want to run or cannot run JS. 99% or more of the users will never see this. I personally would be grateful, if web devs took precautions and paid attention to also having a no-JS workflow for things where it is relatively simple to implement. It also has to do with accessibility. A JS-only page, that results in a blank white page has exactly zero accessibility.
I love this - and I applied the lessons to my own site. It was fascinating to see just how often I'd slapped a class on something which was never going to be re-used.
Similarly, WordPress spams tonnes of classes everywhere. Most are unused.
So I took a look at rewriting my CSS to target by logical structure, rather than just random names dotted about. It mostly worked well, although it did mean that I occasionally had to write a selector like:
`li[itemtype="Comment"] > article > div[itemprop="author"] {}`
I really like the concept of this. I'd love a html reference guide (pattern library?) with plain html no CSS or JS to document the basic building blocks of the web.
I like it. Nice effort. Plus I like the visual style a lot too.
I feel there's a mismatch between creating novel "semantic" elements, and then customising them in the markup, rather than the contextual approach (nesting, rich selectors). The mismatch is that the new elements still apply a "what" approach, but the attributes used for customisation apply a "how" approach and leave it in the mark-up. It's still like `<p class="red" />` rather than `main p { background-color: red; }`.
I get that there's a trade-off between purity and code that's nice to work with, and I think you've hit a very readable, appealing and creative balance.
That's why I like using PicoCSS on small projects, it instantly adds style without much classes needed.
The dark option is definitely the most readable but wow those other themes on this site are super nice looking!!
So even almost classless websites can be laggy websites.
It was super snappy for me. The snappiness actually stood out. In us east
In the EU on Firefox mobile and was weirdly slow.
> I removed a non-trivial amount of CSS (now about ~5KB of CSS over the wire for the entire site)
That's around 2% of the size of the single page of that article, it absolutely is a trivial amount, especially when it complexifies so much the maintenance or addition of the website.
It'd be even more irrelevant if the site didn't do "public,max-age=0,must-revalidate" on the CSS file.
The 5KB is trivial. They don't mention how much was actually removed. Maybe 200KB? Who knows
It has also vastly simplified the maintenance of the website.
In fairness, the page loads two enormous fonts. Lots of blogs just use system fonts, so the advice is generally useful if you're trying to reduce your own site size. The total payload without the fonts are around 12kb, so reducing the CSS to 5kb is a fairly big deal. Without the fonts, the entire site could be delivered in the first TCP packet.
:%s/;/:
Great job!
But, I'm sticking to tailiwnd :D
Hah that's a cool and creative exercise. Love the writing style as well
It also has no style
I can only see ~half of each line on my phone and cannot scroll, so whatever they are doing, they are doing it badly.
Also, can't seem to be able to select text, for one reason or another.
I can see whole lines and select the text in a desktop Firefox, but the fonts are messed up (thinned and otherwise tweaked) and colors are set to reduce the contrast, making it hard to read. As with most of the design-related articles, I had to use the reader mode to actually read it. But the content can be guessed from the title (with a hint that it is about CSS) anyway: they have simply removed CSS class selectors, replacing them with element selectors, adding combinator selectors, pseudo-class selectors, and so on.
I love the design of his blog -- the use of dots, link highlights etc.
It also brings back memory of 2000s internet, but merged into Today's design standards. I assume this was intentional.
[dead]