Remix.run Logo
webstrand 5 days ago

The problem is that, in the current state of CSS, it's a two way binding: The styles are dependent on structure to make the look, and the structure is dependent on styles to make the look. Often times you wind up needing to add a wrapper div, either to give a root for selectors or to provide some CSS context like stacking, containers, perspective, etc. And when you add that container class, your classes that are structural often all break in difficult to debug ways.

I used to follow CSS Zen, now I'm more of a "put a class on every element describing its purpose semantically". Then, when I need to change the structure of some component, adding a wrapper, changing an element type a -> button, etc, most of my styles keep working just fine. I'm not a fan of Tailwind, my method is more like BEM or Atomic CSS but with less naming-convention-rigour.

I should mention that most of my work is in building interactive components. You might be able to make the case for structural css for more flow-like content. But even then, when designers start asking for full-bleed elements in flow, you have to start breaking structural semantics and tying the two together.

taeric 5 days ago | parent [-]

I am not sure I understand. There is coupling between the styling and the structure. Somewhat by necessity? I'm curious how you would possibly avoid having any.

I think your point is that there are not enough structural items to distinguish things for some uses without also signaling them for others? I can agree with that.

So, as a maximalist position, I agree that you should consider it an anti pattern to force yourself into minimal markup. But I also have a hard time not thinking it is an anti pattern to go the other way? Lots and lots of divs because the only way we could consider abstracting things is yet another wrapper around things.

Gets worse when I look at the noise that are the classnames generated in so many frameworks.

webstrand 5 days ago | parent [-]

Perhaps a better way to think of it is: HTML doesn't provide enough distinct element types to accurately capture the semantic structure of modern interfaces.

You're right that some coupling is inevitable, but the question is where to put it. I'd rather couple my styles to semantic intent (what something is) than to DOM structure (where something sits).

I don't add classes where I don't need to style anything, and I'm not adding _extra_ divs. Instead of using HTML element names, I'm using my own semantic naming convention that is not strictly tied to the behavior of HTML elements.

For instance `<a class="navbar-button">`, `<button class="navbar-button">`, or `<div class="animation-wrapper"><button class="navbar-button">` can all be selected by the same `.navbar-button`. Whereas the equivalent structural selector `nav > ul > li > :is(a, button, .animation-wrapper > button)`, is fragile and complex. Additionally you can't use a descendant combinator instead to simplify, because there could be other non-navbar button descendants of a navbar item (for ex. a dark/light mode switch).

This gets even worse with modern CSS features. Say you want a hover animation that uses container queries - you'll need to add a wrapper div around your button to establish the container context. That single structural change breaks not just `nav > ul > li > button`, but also related selectors like `button + button` for spacing or `li:has(button)` for parent styles. Using structural selectors leads to selector complexity as you're forced to be more and more specific with your selectors to avoid parts of structure you shouldn't be styling.

I still use semantic markup wherever possible, I think its a great benefit for accessibility tools and automated information extraction. I just don't think its a good idea to use it for styling. And modern CSS gives us lots of tools to break HTML semantic markup like `display: contents` (especially useful for html table syntax).

taeric 5 days ago | parent [-]

Ok, I don't think I disagree that much. Was more just curious on what you meant. I view the structure as already something happening to describe things in ways that facilitate styling. But, this is a lot like the distinction between attributes and children in XML. I think people give it a little more thought than it warrants.

To that end, I think I can get behind the idea of "if you are going to use classes anyway, might as well use them for all of it." That is, having some that are done by structure and some that are done by class seems to be the a dangerous mix.