← Back to context

Comment by PaulHoule

2 years ago

I thought "!important" was always about appealing to the emotions of overwhelmed and confused CSS authors as it seems to make the computer "listen to you" when it doesn't seem to be.

I remember this notorious book

https://www.amazon.com/Creating-Killer-Sites-David-Siegel/dp...

about techniques used to get pixel perfect results with HTML back in the 1990s. The author of that book was quite impressed with CSS as it really does give designers great tools to work with, but it's still got the problem that designers find it hard to be disciplined with. That is, a lot of designers are stuck in a "let's draw a pretty picture" mindset but find it hard to think like "let's develop a system that makes it easy to draw lots of pretty pictures". Thus we get a lot of things like bootstrap and tailwind that erode the idea of CSS classes being somewhat semantic and being related to the structure of the system (e.g. this particular toolbar as it manifests in this application) as opposed to "a generic toolbar that comes out of a framework" or "something that has 15px of margin".)

Well the `!important` is a good example if general misunderstanding of the core basics of the CSS: the cascade. People usually think it means something like "override everything what was declared up until now in a way I don't need to check the selector specificity", while in reality it means *"teleport this certain declaration to the higher mirror cascade origin realm"*, what is way cooler yet mostly unknown concept of CSS.

    There are _Browser_ styles, that are overridden by parts of —
    — _User_ styles, that are overridden by parts of —
    — _Author_ Styles, that are overridden by —
    — !important parts of _Author_ Styles, that are overridden by —
    — !important parts of _User_ Styles, that are overridden by —
    — !important parts of _Browser_ Styles.

What is a neat mechanism, isn't it? The "weakest" can have the last word here.

Sadly neglected concept of the web standards is that they were conceived not as rigid projectors of what authors create, but as a platform where individual user agents process authors' contents and negotiate the way how their users want to consume it. One of the first Håkon Wium Lie's CSS proposals even had some "weights" for individual attributes, so that user could express "I prefer serif fonts for headings this much" and author could express that "I suggest this sans serif font for heading with such weight, but it is not so important and my content will make sense in different font faces as well, but it is crucial that this particular text will be slanted, otherwise user would miss important aspect of information."

-- https://www.w3.org/People/howcome/p/cascade.html

  • Whoa, that's weird. So once there is `!important`, the order of precedence flips? I'm sure there was a good reason for that...

    • Your OS had a dark theme, that gets represented in the browser as a not !important user style. The website should be able to override this to avoid the white text on white background problem.

      But then if the user is tweaking a specific site, the user should be able to override anything with ! important if they really mean it.

      2 replies →

Kind of hard to see Bootstrap and Tailwind so casually lumped together with regard to how they break semantics, as they are at least an order of magnitude apart in that. Bootstrap will throw in a p-0, but Tailwind is designed to essentially make everything a p-0.

And that's an important distinction, as I think the current challenge with CSS for designers (and everyone) is that it now sits between design and development. That is, we've long departed the document model use case, wherein you're simply laying out a static Website that you just want to be consistently styled across pages and easily changeable (perhaps the optimal semantic use case).

We now build apps wherein we encourage essentially inline styles to be co-located with components. That itself is a complete rejection of the semantic CSS model. And it's exactly why Tailwind—being explicit about its purpose in an application development context—goes that order of magnitude beyond Bootstrap.

But, how does a designer work semantically in this context?

I think there are a lot of things wrong with Web development these days and styling at the component level is an example of one. Tailwind is the right tool for the wrong job. It solves a problem that shouldn't exist. And, in doing so, tempts some to believe CSS is the problem.

Edit: Don't get me wrong. CSS has its own problems and a good number of them. But it can't be blamed for not being used semantically in the current Web development environment.

  • The designer doesn't work semantically. Working with tailwind is like digging the hole for a pool with a spoon instead of a bulldozer.

    They repeat the same tailwind classes 20,000 times and if the application gets bigger they repeat it 40,000 times and if they have to change the way it looks it is the mother of all cut and paste jobs.

    There is an unholy convergence of the tools being almost but not quite adequate, the platform being driven by companies that have overly favorable unit economics (Google could care less if it cost $2M to make a simple web site) and a designer mindset that is all too comfortable with trading a bulldozer for a spoon.

    Tailwind would be a lot more appealing to me if it was coupled with some system where I could say "class X inherits from tailwind classes A, B and C" and thus have a layer of abstraction over just writing properties.

    • I am a reluctant convert to tailwind. I've been doing HTML since the 90s, before CSS was even really usable for things like page layout. I mean, we didn't even use div in those days - it was table based layouts and spacer gifs.

      CSS appeals to a programmers mindset. Cascading seems like a good idea. Having classes that are reusable seems like a good idea. Complex selectors seem like a good idea. These are all forms of abstraction, almost like functional composition but not quite.

      But after decades of fighting with it, I have to admit that it just doesn't work. The myth that you could change an entire site design just by changing the CSS is a complete myth. I've been party to more than a few whole site redesigns and I can assure anyone unfamiliar that it involved a heck of a lot more than updating CSS (and more than HTML in almost every case as well).

      In fact, almost all advancements in CSS (including Sass and Less) seemed to tend toward isolating the effect of changes. Pretty soon most projects had a compenent.html/component.scss pair for every fragment and naming conventions like BEM [1] became the norm. Reusability for things like fonts and colors were handled with CSS variables.

      Tailwind is proof to me that isolation is more important for visual design than abstraction/inheritance/cascading. Inline styles would be the same advantage but they are way too verbose.

      1. https://getbem.com/

      8 replies →

    • Exactly. It's the frameworks driving the abuse.

      I actually think CSS is the wrong tool for modern webdev. Or rather, it should be the output of a compile process instead of something that designers and developers wrestle with.

      In general, we're building these complex SPAs, and still working directly in standards that were intended for a static document model. Part of the reason is we somehow believe we need infinite customizability, so for that we're writing in Assembly.

      But, the truth is that user interfaces are largely consistent and should be. Still, even if we did want maximal customizability, we should use tooling that generates the CSS, etc.

      And that tooling should be visual. I mean think about the fact that we're trying to hand code visual designs with text. Or that it was so accepted that we're only recently trying to generate the code from design tools like Figma, which is still imperfect.

      So many thousands of developer hours lost to this effort. Bass-ackwards to be sure.

      3 replies →

    • > Tailwind would be a lot more appealing to me if it was coupled with some system where I could say "class X inherits from tailwind classes A, B and C" and thus have a layer of abstraction over just writing properties.

      I feel the same. Give the component a class and then in the SCSS assign the setting there. But inlining each individual CSS setting? I don't get it. Sure maybe great for a quick prototype / MVP. But as a permanent tool? I don't see it.

    • > Tailwind would be a lot more appealing to me if it was coupled with some system where I could say "class X inherits from tailwind classes A, B and C" and thus have a layer of abstraction over just writing properties.

      This mindset is the problem. You don't want or need this abstraction in the CSS, what you want is to encapsulate these styles properties in a reusable "HTML component", and then use that component wherever needed. It then carries those style properties into every instantiation. What use are semantic style classes in this context? Atomic CSS makes perfect sense in this context and makes composable development a breeze by comparison.

      2 replies →

  • > Tailwind is the right tool for the wrong job. It solves a problem that shouldn't exist. And, in doing so, tempts some to believe CSS is the problem.

    This articulates a problem I’ve had with Tailwind for a while, and not quite been able to put words to.

> Thus we get a lot of things like bootstrap and tailwind that erode the idea of CSS classes being somewhat semantic

If everyone is using CSS wrong, then I think that's pretty good evidence that the design is flawed. The semantic/cascade model has proven to be challenging for designers (as you suggest in your comment), difficult to maintain (inheriting a mess of somebody else's CSS is a nightmare), and counter to the component-based encapsulation that seems to be the trend in modern web dev patterns.

`!important` was our ultimate weapon designing unbreakable embeddable widgets that other sites will drop in to their webpages at their whims.

  • Exactly -- that's what is missing in the (at least conventional) HTML and CSS stack.

    One of the great ideas from Ted Nelson's

    https://en.wikipedia.org/wiki/Project_Xanadu

    was transclusion: any document could embed part of some other document. Now Ted saw that being done by a special kind of hyperlink (you're not copying the target but linking to it) and he imagined there was a micropayments system such that I get 10 cents for the document and author of the target gets 1 cent.

    In the case of HTML it would be great if you could snip a piece of HTML out of a document together with CSS and associated assets and then incorporate these into another document and have it "just work". I mean, if it was easy to do we wouldn't see people collect and post so many screenshots from X, they could just make an HTML page that embeds the content.

    I prototyped a server-side templating system that would break HTML down into a DOM graph and made some progress on the problem of rewriting identifiers such as classes and identifiers in a donor document to address problems similar to the "hygenic macro" problem when it is embedded in a host document. I got it to work in some simple cases but wasn't sure how general I could make it. (In some cases you are going to have to modify the CSS to make the donor work inside the host, for instance, and that probably does involve judgement calls.)

    It's quite a miracle that people get CSS to work inside React components, Web components, and stuff like that, given that out of the box CSS doesn't have any mechanism to stop people from using the same classes, not to mention a rather complex mechanism of inheritance, etc.

    • > In the case of HTML it would be great if you could snip a piece of HTML out of a document together with CSS and associated assets and then incorporate these into another document and have it "just work"

      You mean like an <iframe>?

> Thus we get a lot of things like bootstrap and tailwind that erode the idea of CSS classes being somewhat semantic

Can you link to somewhere explaining why and how CSS is meant to be semantic? Search bots and screen readers don't read or use class names. They expect certain semantics from HTML tag names and HTML attribute names though.

I think this is mixing up something that is really only meant to be a convenience for developers here.

Tailwind would advocate you wrap up common styles within a web component so the web component filename would take the place of a class name so there's not much difference for developers. Lots of styling is purely decorative as well and doesn't have semantics so there isn't always a useful name to provide e.g. `gallery-container-wrapper` isn't telling you much.