8 ms·
> I got curious about what writing more semantic HTML would feel like. I've been teaching semantic HTML / accessible markup for a long time, and have worked ex
by TonyAlicea10 5mo ago
> I got curious about what writing more semantic HTML would feel like.
I've been teaching semantic HTML / accessible markup for a long time, and have worked extensively on sites and apps designed for screen readers.
The biggest problem with Tailwind is that it inverts the order that you should be thinking about HTML and CSS.
HTML is marking up the meaning of the document. You should start there. Then style with CSS. If you need extra elements for styling at that point, you might use a div or span (but you should ask yourself if there's something better first).
Tailwind instead pushes the dev into a CSS-first approach. You think about the Tailwind classes you want, and then throw yet-another-div into the DOM just to have an element to hang your classes on.
Tailwind makes you worse as a web developer from a skill standpoint, since part of your skill should be to produce future-proof readable HTML and CSS that it usable by all users and generally matches the HTML and CSS specs. But devs haven't cared about that for years, so it makes sense that Tailwind got so popular. It solved the "I'm building React components" approach to HTML and CSS authoring and codified div soup as a desirable outcome.
Tailwind clearly never cared about any of this. The opening example on Tailwind's website is nothing but divs and spans. It's proven to be a terrible education for new developers, and has contributed to the div soup that LLMs will output unless nudged and begged to do otherwise.
- freedomben 5mo agoYou're not wrong, and I mostly agree with you. I die inside when I see the div soup that a lot of sites have become. However, I think there is value in being able to have the important parts of CSS merged into the HTML a bit. Where that line is, is certainly up for debate (and I don't have the answer), but I've found a lot of my tailwind sites are more readable to me than my pre-tailwind sites, often because I don't have to context-switch and open a different file to be able to reason about the styling on an element. For big stuff the second file can be nice, but there's a lot of style tweaking that is great to be able to do right there in the HTML. Tailwind does really lead you to ignore the css file though (or keep it highly minimal), which I agree is becoming an anti-pattern.
- TonyAlicea10 5mo agoThe "open a different file" reasoning piece is a common pro-Tailwind statement and I do see the upsides. I think that upside became more prevalent in the reusable components era, whereas previously CSS was targeting an entire HTML file (and thus the reasoning was more like SQL query than "this one element's styling"). With LLMs I think this upside is much smaller now though.
- troupo 5mo ago> With LLMs I think this upside is much smaller now though. With LLMs Tailwind wins. Because it's a very restricted set of classes. With regular "separation of concerns" CSS, LLMs will happily just pile on more and more and more CSS because they can't really analyze the code that's already there, and will miss and re-create huge chunks of CSS. Or write increasingly hyper-specific CSS to fix reported issues. Anecdotally: in a side project I now have 10k lines of "pure" CSS generated by LLMs on top of Tailwind. The web part of the app is ~20k lines (not all of them are rendering anything on screen). No idea how to fix it :)
- skydhash 5mo agoIt seems that everyone is forgetting the web inspector as a tool for designing web pages. You can tweak properties and styles in a live environment, and then transfer your preferences to the css files.
- hikosan 5mo ago[dead]
- reaperducer 5mo agoI don't have to context-switch and open a different file to be able to reason about the styling on an element Unless you're coding on a VT100 terminal, you just put the HTML in one window and the CSS in another. Subdivide as necessary, or as your monitor space allows. Heck, we were doing that back in 1989 on IBM PCs with MDA displays. If your CSS is so out of control that you can't wrap your brain around it, it's time to refactor or split into individual CSS component files.
- flossly 5mo agoWhile I agree I do think there's some "aspiration of purity/correctness" in your approach that I've long let go of. I look at the royal mess that is HTML/CSS/JS as a necessary evil, required when we want to target browsers. To me it's "just the presentation layer". In my work I put a lot more emphasis on correctness in the db schema, or business logic in the backend. When it comes to the messy presentation layer I prefer to write a little as possible, while still ending up with somewhat maintainable code. And for this Tailwind fits the bill really well: LLMs write it very well, new devs understand it quick, and it's quite easy to read-back/adjust the code later. I 100% agree a Tailwind project is not the best way for a new dev to learn HTML/CSS. But then I prefer the new dev to focus on great db schemas, intuitive APIs, test-able biz logic, etc. Fiddling with the mess that's HTML/CSS is not the place where I consider human attention is best spent on (or where developers pick up skills to become much better developers).
- TonyAlicea10 5mo agoThis isn't about "purity/correctness" it's about the real experience of a blind person. Accessibility means caring about the HTML. Your comment only mentions developers as the audience of HTML authoring, as opposed to users, which is a common attitude and the core problem with Tailwind.
- flossly 5mo agoI use Tailwind and have all kinds of "screen reader" directives in my templates. Not sure if it helps, but if we get our first blind user I will gladly make some admends to make it more usable for them. It seems that Tailwind is now blamed for the mess that is HTML/CSS. Tailwind certainly allows for accessible designs; it may not be the ideal solution, sure, but what we aim for is "good enough".
- reaperducer 5mo agoif we get our first blind user I will gladly make some admends to make it more usable for them. Not good enough. You have to be accessible before it is needed in order to avoid legal liability. And how do you expect to get a blind user if they already cannot use your product? None of the doctors I build web sites for are currently blind. I know this because I talk to them regularly. But I still build the web sites for the future, when HR might hire a doctor or nurse or other person who is blind, or partially sighted, or has trouble with their muscles, or has difficulty distinguishing colors. Doing the right thing isn't that hard. Not doing it is just lazy.
- vehemenz 5mo agoA few counterpoints: Treating markup and styles separately is great, in principle, but you'll always need additional markup for certain things. We knew this going back to the early 2000s. There is nothing about Tailwind itself that forces you to use divs and spans instead of the appropriate HTML tag. Documents and interfaces are different. Tailwind makes a lot more sense for interfaces. You can use Tailwind for the interface and scoped HTML selectors for other content. Tailwind is around 4x faster and has practically no overhead compared to writing a complex CSS codebase. Whatever you think of it, this is always a benefit in its corner.
- efortis 5mo agoBenchmarks?
- spiderfarmer 5mo agoAs someone who wrote CSS for 20 years and who was against using Tailwind because of “principles” I must say that Tailwind is just awesome. Every minute spent trying to make sense of the structure past you or your colleagues came up with is a minute that could be spent on something more important. Every time someone says that Tailwind sucks, it’s like hearing the old me speak.
- ncphillips 5mo agoSame here. It’s super weird take to me now. Maybe if you’re just writing plain HTML and CSS tailwind would be worse, but assuming there’s a component system you’re going to be just fine. The cascade of CSS is such a foot gun. Localized styles work great and tailwind abstracts away hardcoded values with relative ones
- paulhebert 5mo agoI prefer writing plain CSS over Tailwind But I get component-scoped CSS (via Vue) and use custom props to abstract away hardcoded values Tailwind isn’t the only option for those features
- 5mo ago
- 7bit 5mo ago> Tailwind instead pushes the dev into a CSS-first approach. You think about the Tailwind classes you want, and then throw yet-another-div into the DOM just to have an element to hang your classes on. I wholeheartedly disagree. That mindset is not caused by Tailwind, but by being ignorant. You can perfectly create an HTML document with semantic meaning and the add Tailwind just as any other CSS framework or pure CSS to it. And DIVs do not carry meaning, they are specifically to add functionality or styling, so you can throw in as many as you like. Using them abundantly isn't good style, but the way you make it sound that they're evil isn't good either.
- TonyAlicea10 5mo agoThe HTML spec says divs are the element of last resort. This issue isn’t that they’re bad. The issue is they are reached for far too quickly. Also if you think massive numbers of nested divs don’t have a performance impact in the DOM when reusable components are nested (because “styling”), you’re wrong.
- troupo 5mo ago> The HTML spec says divs are the element of last resort. This issue isn’t that they’re bad. The issue is they are reached for far too quickly. The problem is that HTML gives us very few tools to do anything useful. And you can only push certain elements so far. Div and span are generic elements with no semantics attached. You want a layout? Div. You want a change to a part of text? Span. The only reason they are called "elements of last reserve" because it's only true if you remember that HTML is, has been, and forever will be a tool to display static text, badly. That's why you have article, section, p, and other text-oriented elements. But the moment you want something beyond that? Welcome to divs.
- TonyAlicea10 5mo ago> You want a change to a part of text? Span. You haven’t read the HTML spec. There are an incredible amount of elements, including for changing just a piece of text (b, i, strong, em, and many more). Plus elements for visual aspects like images. You need divs and spans for extra structure that isn’t there for anything but visual purpose. For things you wouldn’t describe to someone who couldn’t see the page. That’s a lot less than you think. HTML authoring and choosing the right elements can be fun. But you have to stop thinking visually and start thinking semantically.
- uxcolumbo 5mo agoWhat's a good source to learn how to develop like this - to create HTML / CSS structure that's accessible? EDIT: ignore. I can see you have some links in your profile. Will check it out.
- reaperducer 5mo agoHTML is marking up the meaning of the document. You should start there. Then style with CSS. This is precisely how I do it. Code that generates HTML. Once I can see all the content on the screen in some kind of Netscape Navigator 1.0 nightmare, then I go back and add styles to make it look pretty. It's not hard. It just requires thought and planning. (The best planning tool I've found is a pencil and grid paper, not the web design SaaS-of-the-moment. However, it's surprisingly hard to find good pencil sharpeners these days.)
- antran22 5mo ago> Tailwind instead pushes the dev into a CSS-first approach. You think about the Tailwind classes you want, and then throw yet-another-div into the DOM just to have an element to hang your classes on. To be fair plopping a `div` everywhere started way before Tailwind. I blame React and the mess that is CSS in JS for this.
- evilduck 5mo agoDivitis was a thing long before React came along. It was a common solution to styling problems even in the jQuery/Dojo days. Getting stuff to look similar across IE6 and FF before CSS3 relied heavily on divs.
- ncphillips 5mo agoIt did for sure. And Tailwind absolutely doesn’t need to be done this way. I think this is a correlation-not-causation issue
- TonyAlicea10 5mo agoI disagree. With Tailwind you think in nested classes which ergonomically encourages “I need a div for this class”. Very similar to early React where every component had to return a single real parent element (now you can return a fragment) so people chose div.
- mhitza 5mo agoUsing tailwind doesn't lead to any inherent concession of accessibility. How do you come to that conclusion? If I look at their component library, they also do the work of including aria attributes for you https://tailwindcss.com/plus/ui-blocks/marketing/sections/pricing https://tailwindcss.com/plus/ui-blocks/marketing/sections/pr... (first exsmple with free code I've found). If we're not talking landing pages, which are more like digital brochures, I always start with markup and then add css classes on top.
- TonyAlicea10 5mo agoWho said inherent. The design loop of “I need a div for my CSS class” is an ergonomic problem not a concession.
- xigoi 5mo ago> If I look at their component library, they also do the work of including aria attributes for you Using ARIA attributes instead of semantic elements is bad for accessibility.
- rhdunn 5mo agoHow are ARIA roles/attributes bad for accessibility? Sure, if there is a HTML element that works then use it, but not every UX pattern is expressible in HTML without specifying roles/attributes (e.g. tabs [1]) and not all browsers support recent HTML elements/attributes (such as using details/summary for accordions). ARIA patterns [2] has a list of examples for UX components and their examples specify/use ARIA roles/attributes. [1] https://www.w3.org/WAI/ARIA/apg/patterns/tabs/ https://www.w3.org/WAI/ARIA/apg/patterns/tabs/ [2] https://www.w3.org/WAI/ARIA/apg/patterns/ https://www.w3.org/WAI/ARIA/apg/patterns/
- extra88 5mo agoWAI's APG patterns exist to document how ARIA attributes should work, they don't advocate for them to be used in place HTML elements. They also don't test to confirm that they actually work in browsers or with assistive technologies (some specific patterns are fine). For web developers, they're helpful for documenting expected keyboard interaction support and other norms. Are you still coding to support Internet Explorer? All browsers have supported details/summary since an Edge switched to Chromium in 2020. https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/details https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
- danaw 5mo agoyou're unfairly conflating things and putting the blame for a lack of care or understanding on tailwind vs on the dev themselves. nothing about tailwind forces you to build inaccessible or "div soup" apps can tailwind be used poorly? absolutely. but that's true of any tool i've been writing CSS for ~20 years and am quite capable with it, having used CSS, Less, SASS/SCSS, Stylus, PostCSS etc. the reason i have settled on Tailwind for the last few years is precisely because it enables me to build more robust application styling. tailwind frees you from having to spend excessive time building abstractions of styles/classes that will invariably change. placing the styles directly into the markup that is affected by it reduces cognitive load, prevents excessively loose selectors affecting styles unintentionally and really aids in debugging. jumping into codebases with bespoke css frameworks is always more complex and fragile than a tailwind codebase for anything but the most simple sites/apps add to that the ability to have consistent type, color and sizing scales, reduced bundle sizes, consistency for any developer who knows tailwind and a very robust ecosystem (and thus llms are very familiar with it) and tailwind is a really excellent choice for a lot of teams tailwind is like most tools; it can be used well or poorly depending on who is using it
- superfrank 5mo ago> nothing about tailwind forces you to build inaccessible or "div soup" apps Totally agree. I feel like this was more a by product of React. Not that React forced this either, but it felt like the rise in both went hand in hand for some reason. While I think it's true that none of the current top FE technologies force the div soup, they don't discourage it either. It would be nice if what ever FE technologies catch on next did try to encourage better practices around things like accessibility. Make the path of least semantic HTML the path of least resistance and allow people to fall into the pit of success, ya know?
- TonyAlicea10 5mo agoReact encouraged this for years by requiring a single parent element being returned from all components. They also showed a div as the option of choice. They fixed this later with Fragments but the damage was done.
- troupo 5mo ago> HTML is marking up the meaning of the document. You should start there. Then style with CSS. If you need extra elements for styling at that point, you might use a div or span (but you should ask yourself if there's something better first). > Tailwind instead pushes the dev into a CSS-first approach. You're putting the cart before the horse. Or forgetting either the cart or the horse. Tailwind doesn't force anything. And "semantic HTML" or "semantic CSS" are not really a thing, and have as much bearing on how many divs a page has, as Tailwind. And the reason is simple: there's literally nothing else in HTML than divs and spans. The amount of usable primitives is absolutely laughable, and trying to combine them in any useful manner results in as much soup with Tailwind as without Tailwind. > since part of your skill should be to produce future-proof readable HTML and CSS that it usable by all users and generally matches the HTML and CSS specs. Which part of Tailwind isn't readable, isn't future-proof, or doesn't match HTML and CSS specs? How is "px-4" none of that, but ".ytp-big-mode.ytp-cards-teaser-dismissible .ytp-cards-teaser-label" (Youtube's CSS) or ".swg-button-v2-light[disabled]" (Washington Post) or "legacy-popover--arrow-end-bottom:after" (Spotify) are? > The opening example on Tailwind's website is nothing but divs and spans. Oh no! And what are the opening examples on any of the "proper pure-as-god-intended CSS" sites?
- xigoi 5mo ago> Oh no! And what are the opening examples on any of the "proper pure-as-god-intended CSS" sites? The first example on https://developer.mozilla.org/en-US/docs/Learn_web_development/Getting_started/Your_first_website/Styling_the_content https://developer.mozilla.org/en-US/docs/Learn_web_developme...: <p>Instructions for life:</p> <ul> <li>Eat</li> <li>Sleep</li> <li>Repeat</li> </ul> p { font-family: sans-serif; color: red; } li { background-color: greenyellow; border: 1px solid black; margin-bottom: 5px; } No divs and spans in sight.
- troupo 5mo agoTrue! And Mozilla is one of the good guys. What I should've said in my hastily written comment should have been: "and other implementations of the same (or other) functionality isn't divs and spans?" I think my only true criticisms for Tailwind example would be: - should've probably used h2/h3 for card titles. Though this is dependent on where and how the card is used - should've done more with the meta (number / date). But in a real world these would probably still be spans (for example, to mark them in different colors etc.) HTML doesn't have a card element. So when you create one, you... use whatever's available. And divs and spans in HTML+CSS literally exist to manipulate layout and text. BTW, my favorite accessible card is this one: https://inclusive-components.design/cards/ https://inclusive-components.design/cards/ And it's probably even more weird. Demo: https://heydon.github.io/Inclusive-Components/cards-redundant-click-read-more/ https://heydon.github.io/Inclusive-Components/cards-redundan... (check the CSS also)
- mgraczyk 5mo agoCSS is badly designed and uses a confusing, separate DSL with arbitrary rules designed before the Internet was widely used, before web apps existed, before smartphones etc It's trash and throwing it out is good. Not learning it is good. Tailwind is a solution to a real problem. More importantly, AI is good at it already and it's unlikely humans will need to understand HTML/CSS at all within a year or two. There's no reason to spend time learning how the gears work, just put the cover back on
- ramesh31 5mo ago>It's trash and throwing it out is good. Not learning it is good. Tailwind is a solution to a real problem. Yup. Spent a decade of my career writing CSS every day, I was what you would call a "guru" and have written easily hundreds of thousands of lines of it over the years. Haven't touched a class or a stylesheet in nearly a year now, and probably never will again. Good riddance.
- simsation 5mo agoSame for me, I started web development with Netscape and IE5, and all the browser specific CSS declarations and media queries, checking on so many different browsers. Then all the trouble with positioning by inline blocks/float, then flex boxes. Now AI does all the HTML structure and CSS. Never have to do it again.
- odnckwmxkwdj 5mo ago“CSS is bad” Why? “Because reasons.” Care to explain? “No need to learn it anymore, my AI can do it for me” Okay, but why is it bad to learn it “Reasons” Uh… what?
- deleted 5mo ago[deleted]
- u_fucking_dork 5mo ago[flagged]
- BobbyTables2 5mo agoI find your comment quite refreshing. 25 years ago, I was appalled how Microsoft Frontpage could transform a very simple word document (with little formatting) into an utterly indecipherable mess of HTML that rendered correctly. With very simple transformations, I could paste the text of the document into notepad and add just a few heading tags for the same rendered result but a much more understandable source. CSS had a lot of promise for simplifying the HTML content, but the world tried its hardest to prevent that. Now we have multi-megabyte monsters for simple webpages (before even counting graphics).
- gofreddygo 5mo agoI agree with the criticism of tailwind. IMO any good criticism warrants at least an opinion on what should be done instead or some corrective or remedial patterns. there is a reason why tailwind got as popular as it is today. And it only highlights the gaps in either what HTML and CSS provide for the task at hand or the difficulty in that approach. This must not be lost in any criticism. another observation is none of technical user interface decisions or discussion emphasis on the tree data structure that is inherent to every major user interface rendering mechanism relevant today. there are inherent benefits and drawbacks of it being a tree structure that neither of the developers nor the framework leverage. when thought of as a tree, it benefits from adding certain constraints and naming conventions that allow more artistic expression using just HTML and CSS that I have not seen tailwind or any other framework encourage
- alwillis 5mo agoIt's unfortunate Inverted Triangle CSS (ITCSS) isn't more popular. Instead of resisting the cascade, it embraces it and makes it work for the developer. The summary: write your CSS in specificity order [1]: /scss/ ├── 1-settings. <- global settings ├── 2-design-tokens <- fonts, colors, spacing, etc. ├── 3-tools <- Sass mixing, CSS functions, etc. ├── 4-generic <- reset, box sizing, normalize, etc. ├── 5-elements <- basic styles: headlines, buttons, links ├── 6-skeleton <- layout grids, etc. ├── 7-components <- cards, carousels, etc. ├── 8-utilities <- utility and helper classes ├── _shame.scss <- hacks to be fixed later └── main.scss ITCSS basically does away with specificity wars in a CSS codebase. Usually the only place !important is the utility layer. [1]: https://matthiasott.com/notes/how-i-structure-my-css https://matthiasott.com/notes/how-i-structure-my-css
- infamia 5mo agoThis is brilliant, I was not aware of ITCSS. Thank you for sharing! The link you shared fits my brain a lot better than pure BEM/CUBE, which works but always felt weird and uncertain to my style. Sprinkling a bit of BEM on top of ITCSS feels just right. shame.scss is the snarky cherry on top. Thanks again, you have enlightened at least on person today! :)
- alwillis 5mo agoIn hindsight, ITCSS is so obvious. Makes you wonder why so many people think CSS is difficult.
- funksta 5mo agoAren't Cascade Layers [1] a more reliable, native solution to the specificity problem? In 2026, why not lean on them instead of source order? [1] https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Cascade_layers https://developer.mozilla.org/en-US/docs/Learn_web_developme...
- SquareWheel 5mo ago
- SkiFire13 5mo ago> HTML is marking up the meaning of the document. You should start there. Then style with CSS. If you need extra elements for styling at that point, you might use a div or span. IMO this is the fundamental problem with HTML and CSS. You'll always have some part of the styling in the HTML due to needing extra divs and spans. At that point splitting the styling outside into the CSS splits your attention and Tailwind "solves" that by moving everything back into HTML. Note that I don't like Tailwind, but I would rather have a way of styling that does not need to rely on the existance of extra divs and spans to work.
- srcreigh 5mo agoWhich semantic element(s) would you use to build the example from the Tailwind website?
- mcv 5mo agoI agree. I don't really like Tailwind, nor similar CSS frameworks. The whole idea was to separate styling from HTML, and Tailwind is putting it back into HTML through the backdoor. It's just a way to do styling from your HTML without having to touch the CSS, by inserting styling info in your HTML. That's exactly what we were trying to move away from.
- aleksiy123 5mo agoI think this assertion is where most of the conflict comes from. There is a fair amount of people that disagree with the premise that it should be separated in that way (Including me). I personally like this essay by the author of htmx on the topic https://htmx.org/essays/locality-of-behaviour/ https://htmx.org/essays/locality-of-behaviour/ Also just better composition imo. Practically I think this means components of scoped css, html, js. People never seem to have the same complaint about mixing or separating app code and sql in the same way?
- mcv 5mo agoI separate those too. Queries get their own file. Sometimes their own framework.
- aleksiy123 5mo agoSorry maybe that wasn’t the best example. It’s not really about separation of files. But how they connect. In sql your code may be in a seperate file but your app code is still clearly calling the sql. The inlining vs not inlining is just abstraction. You could use a function, or a separate file or not, a different language or not. But there is a clear single call chain at the points where that behaviour is being applied and a single definition. With css that’s not necessarily true. There’s a bunch of different rules that may or may not apply.
- skydhash 5mo ago> With css that’s not necessarily true. There’s a bunch of different rules that may or may not apply. There's only one algorithm, the cascade. And it's described here[0]. And just like any code you write, try not to write complex selectors. If you're not sure two styles are equal, it's better to write two different rules. And just like styling works in any system, you go from generic (standard html elements) to very specific ones (the link in the hero section of the about page) [0]: https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascade/Introduction https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Casc...
- dalemhurley 5mo agoThat has nothing today do with TailwindCSS, we have been having the exact same thing since 1999.
- therealpygon 5mo agoIt does make that easier for people to choose to do, but I would argue that it shouldn’t be held against tailwind that people do this. Also, sorry, but I’m doubtful that when using CSS that no markup would be changed to better accommodate the final layout…just like tailwind? If the first tool in your tool chest is to change the markup, then it doesn’t matter which method of styling you apply. If your first goal is clean markup and accessibility…then It doesn’t matter which method of styling you apply.
- wellpast 5mo ago> HTML is marking up the meaning of the document. Is this true at all anymore, except for SEO optimized sites/content? For apps, it’s all layout, isn’t it — and HTML, JS, CSS have all evolved heavily to support UI-first, haven’t they?
- mb2100 5mo agoYeah, while you certainly can write semantic HTML with Tailwind, it absolutely doesn't encourage it. It's funny how Tailwind is conceptually going back to inline styles. But sure, if you have <Title>, <Header> and <Button> components etc. instead of using HTML elements <h1>, <header>, <button> etc. directly, then why not stuff the CSS into the components as well? It all depends on whether you prefer to use components, HTML elements or a combination as your favourite abstraction.[0] [0]: https://mastrojs.github.io/blog/2025-11-27-why-not-just-use-inline-styles-tailwind/ https://mastrojs.github.io/blog/2025-11-27-why-not-just-use-...