A lot of people have been pointing this out in the responses. The author has been defending himself for people misreading his tweet when he should have simply left out that last sentence
It requires discipline beyond the capabilities of many organizations to structure CSS so that it's maintainable. The ubiquity of `!important` is not so much "a sign you may not understand the cascade properly" as a sign that the cascade is a flawed design that falls apart in practice.
Step 1: Write component-based UIs
Step 2: Give each component a unique name
Step 3: Repeat this principle even for building routes
Step 4: your CSS will struggle to clash, no matter how hard you try
The cascading is pretty nice actually. Think about using CSS vars... you can dynamically theme apps because of the cascade, by changing just 1 class. there's other nice attributes, and it's true it requires discipline. Just not nearly as much as you imply
When hunting down a function you want to deprecate/remove in your private imperative language codebase, you can probably find all call sites just by grepping — and even if you miss some, in most cases you'll get a hard error of some kind (either compile time or runtime) after removal.
But with the cascade, call sites are implicit — and removal, for better and worse, doesn't cause a hard error.
All it takes is a single rogue engineer or product manager to mess things up. And then cleaning things up later is difficult because of all the places that have to be inspected.
Step 2 demands there be a way for one developer to control the global namespace.
That's completely impractical[0] given inclusion of 3rd-party code and no enforceable standard for imposing step 2 on other developers.
(Web components now exist to facilitate this, but of course, web components are relatively recent; most of CSS's history did not support this 4-step process).
[0] To be fair, maybe completely is too strong an assertion. I've seen something like it done... A compiler rewrites the CSS selectors and the CSS classes to create a sort of top-level namespace by prepending some garbage per module so that no component can accidentally reference another component. It's not great for debuggability (about as much fun as having to deal with the actual entrypoint names in the binary for constructors and overloads when debugging C++), but it gets the job done.
> Step 2 demands there be a way for one developer to control the global namespace
I mean, I just prepend all my component class names with my library name or a shorthand acronym, so 100% of my styles are like `.NawgzInput {}` or `.NawgzGraphNode {}`
I have never seen the limitation to this approach (i.e. the ends of its ability to scale), so long as you don't pick a super generic prefix. So to hear you assert this approach is "completely impractical" to someone who has used it to build their own component library that every application they build is entirely comprised of.. rings hollow
You're basically hand-rolling the prefix-garbage solution the compiler tool I've seen does.
That's the best I think we have now. It's not good (i.e. decreases readability), and it's not universal (there are definitely component frameworks out there where the classes are just named "table" and "button").
> You're basically hand-rolling the prefix-garbage solution the compiler tool I've seen does.
Except it's incredibly easy to debug and avoids most of your complaints about the solution.
Anyways, fair enough, I can confess that there is probably another ideal world that has better viewport styling. But CSS is giving us incredible flexibility, and just like JS, its warts can be worked around very easily and deliver you a powerful, useful, simple set of capabilities.
If component-based UIs are such a good idea, maybe the w3c shouldn't have designed literally every piece of the HTML/CSS/JS infrastructure around global namespaces, particularly ones where every declaration is global by default in the case of CSS and HTML IDs.
"Global all the things" seems to clash with "component".
Very few clients care about how "proper" the CSS is behind the scenes. I'd also venture that they would not want to pay for proper CSS (and the expense of expertise that comes with it) when a single attribute would deliver the same end result. !important actually seems like a practical and valuable attribute in this regard.
I hate that the general conversation around !important is simply:
"Important is bad. You should never use it".
Its more of a belief rather than knowledge at this point.
I'd be interested to hearing a good answer as to why one wouldn't use !important on a modifier class such as ".padding-20" or even something like ".full-width".
Surely the problem lies with your html composition if either of these classes are being used on an element that does not need them?
Over time, accrued wisdom has turned into a rule of thumb such that Grumpy Old Developers sit around the fire with Young Energetic Developers and say “ya know, child, never use !important, it’s bad design.”
The web development industry is getting mature enough to even have this kind of wisdom, which is wonderful, even if (like “wive’s tales”) the principle is overstated.
Engineering is doing what you can with what you've actually got. If what you've actually got is an inherited tremendous ball of spaghetti css, a need to change just one thing on the page, and scant prospects for future changes in the area, then it may be good engineering to use "!important" to make your change over a more complex solution. This is in fact the situation I find myself in at work somewhat often, although luckily I can't recall the last time I had to use "!important". But I wouldn't issue a blanket disendorsement of it.
Being more specific often ends up more tightly coupling your selector to the structure of the DOM. .className { property: value !important; } is more resilient to DOM changes than adding extra selectors to increase specificity.
having an id on the top <html> tag and mentioning it in css rules seemed very effective to me- especially when the tag was the name of the page, which is what i wanted to override by anyway
I’ve noticed many CSS authors don’t seem to know that you can just repeat a selector to increase its specificity. For your example, `.className.className` increases the specificity without adding more reliance on DOM structure.
Wow, I've been doing CSS for a very long time, and had no idea about repeating the selector to increase specificity. That'll come in very handy, thank you!
But that only works if you only need to increase "class-level" specificity. If you're trying to overwrite a style set with IDs, you're gonna need to either use IDs yourself or use !important. Sometimes you may not want to use IDs.
Right—you can do the same thing with ID selectors, they just always have a higher specificity because they are in bucket A[0], whereas virtually all the other selectors are in bucket B.
If you really have to select that element by ID for some reason, you can use an attribute selector instead—`[id=foo]`—and then it’s also in bucket B and can be controlled in the normal way.
Basically, you should consider ID selectors (and element selectors) an antipattern and never use them.
On the other hand, using ever-increasing specificity to emulate !important is about as elegant and semantic as using the hypothetical properties !importanter, !importanterer and !importantererer
Ever-increasing specificity is how CSS works, to call that "emulating !important" is misleading. I'm suggesting using CSS as intended, the cascading part of cascading style sheets, instead of relying on a troublesome override.
Edit: Take this example:
div {font-size: 60% !important;}
If I can't control the order the CSS is loaded, and I can't change that line directly, how do I modify it? Like this:
html div {font-size: 70% !important;}
The use of !important isn't some simple way of bypassing ever-increasing specificity. In many cases it just makes things more complex.
While I agree with your statement overall, most of the time, using !important just kicks the problematic spaghetti-code can down the road. The CSS eventually becomes un-workable/maintainable.
At one place I worked (a subsidiary of NTT), the effort to clean up the CSS and remove all the !important overrides was so time consuming management wanted to make sure it never happened again, so using !important at all would affect our performance reviews. We were expected to fix any bad CSS right away without overriding the default cascading rules.
"The CSS eventually becomes un-workable/maintainable..."
True that, but sometimes one has already reached that point, and yet must make this change anyway somehow. But I don't recall using "important" in years, so I guess it's not that often.
One caveat: every time I use !important, there's at least a clear reason why ("X" library is doing stupid stuff) and you could be surfacing this like any other tech debt. Often, 'spaghetti css' is an easy excuse to not even look into what's going on.
Yup. If you've used important it should be accompanied by documentation. So much of frontend development work is using, adapting, updating, or integrating code you have no control over that it's inevitable to need to use some blunt force on occasion...
Technical debt in CSS seems to be both more inevitable and less problematic than application code. By the time it becomes a problem, either marketing decides on a redesign or the latest frontend lead wants to use a new framework.
So “screw it, this works” seems to be an entirely justifiable methodology.
OO leads to technical debt in most cases. You can limit it to a narrow scope (interfaces), or you can have objects that wont move or inherit much (bascially if the parents can be replaced by traits), but someday someone will try to be clever and your team will soon enter OO hell. Bonus hell points if you allow third-party plugin in your software (shoutout to Jenkins!).
This is why, as someone who loves writing CSS and thinks they're reasonably good at it, I've come to the conclusion that writing CSS is an anti pattern, and if you want teams to quickly build interfaces with a maintainable "frontend styling layer", it should prevent the ability to write css.
Unless something major has happened to it since I used it, Ant uses a giant ball of SCSS with complex selectors that make it ridiculously hard to customize without hacking the source.
Hacking is exactly what we are trying to avoid. Just change the variables to suit your branding and compile the SCSS yourself, just like Bootstrap (which was using LESS but otherwise the same idea).
It must be CSS in the end, but you should create/use a component library, that has the right set of primitives (and less-primitives) that lets end feature developers create the UIs without having to resort to manually write CSS.
THis is made significantly easier when you have designers working with this "design library" mindset also.
I've come to the conclusion that writing CSS is an anti pattern
I don't think this is true. The biggest problem is people who write CSS do it as if they want CSS to be something else and are trying to force it to be that.
Writing CSS using ITCSS (Inverted Triangle CSS) [1]
solves so many of the issues devs complain about it. It's simple: create layers in specificity order. Don't fight the cascade; make it work for you.
Writing good CSS isn't about getting the syntax right; it's about getting the architecture right [2].
Harry Robert's video does a great job of describing all the pain points ITCSS solves [3].
The big problem is knowing all the places which could be displaying incorrectly when you make a change. This is a fundamental design issue with the cascade: unbounded silent failure because rule activation is implicit.
In addition, there is the difficulty of inspecting those sites which you can identify to verify that display is correct, which is hard to achieve programmatically.
It's not inevitable. I love Svelte partly because it solves the problem by compartmentalizing CSS to the UI component I'm working on. It feels natural that if I write CSS in a file for a component it shouldn't be seen by other components in general.
Even without Svelte, most of the problems people have with CSS go away if you do the following:
- Avoid cascading (i.e. no nested selectors except when there's "no other way")
- Implement separate selectors for styling and page/component layout (separation of concerns)
- Using a good naming convention and stick with it
The first point can also be achieved with using style attributes if that floats your boat, although Svelte kind of gives you the best of both worlds just by compartmentalizing the CSS, not necessarily by preventing cascading.
I can't remember the last time I ever had to use !important except when I had to work with some ridiculous CSS "framework" my predecessors chose to use. At least !important was understandable back in the days when it was really hard to achieve some things with CSS, but these days I believe there's little to no excuse.
Thanks, it looks great. I'm happy that they didn't rush it. They don't talk much about compatibility with current web frameworks, I think they should. I really hope that it will be featureful enough to support being a target for compiling Svelte components (or even maybe React / Vue components) to HTML modules to be imported at some point, but still stay simple enough to be useful.
Mind telling a bit more on this second part "Implement separate selectors for styling and page/component layout (separation of concerns)"? Are you referring to classes (for styles) and probably id's for Javascript?
> I can't remember the last time I ever had to use !important except when I had to work with some ridiculous CSS "framework" my predecessors chose to use. At least !important was understandable back in the days when it was really hard to achieve some things with CSS, but these days I believe there's little to no excuse.
Yep. I find of the usage of !important I see daily is failure of the programmer to understand precedence rules, which, as you pointed towards, is mostly due to cascading.
On the other hand, I find Svelte's handling of this half-baked, as there's no way to pass scoped classes to a component, only to a HTML element. [1] In fact, I find this so frustrating that I have actually given up on Svelte's CSS scoping entirely and I use Tailwind instead, which also solves the same problem by almost [2] completely disregarding the cascade altogether.
[1] Why would you want to do this? Well, what about layout? And what if you have a component that wraps or otherwise behaves like an HTML element?
[2] Of course Tailwind supports modifiers, which do cascade, but everything is still local to a single element.
One of the questions for passing scoped classes to a component is why you want to do it. If you have complex selectors, it would effect the implementation of the component, so I think that would be an anti-pattern. Just modifying the root would be great, but in Svelte I believe one component can translate to multiple root nodes, so all of them would need to get the styles, which again would increase the coupling between the component usage and implementation. I think there's just no clean way to do what you want.
> Why would you want to do this? Well, what about layout? And what if you have a component that wraps or otherwise behaves like an HTML element?
Yes, it's nothing something you'd want to do willy-nilly or all the time, but there are perfectly valid use cases. This issue has been one of the single most-commented in the Svelte repos with tons of back and forth and a lot of demand so this isn't just an obscure complaint either.
As for how to resolve it, there are plenty of clean ways to do it. Svelte's style scoping is done via a unique class per component. It suffices to simply provide some way to pass this class from a parent to a child, for example, and let the child component decide what to do with it. There are many possible variations on this theme. The obstacle to resolving this problem isn't technical infeasibility, it's that to date the maintainers just haven't cared.
> It suffices to simply provide some way to pass this class from a parent to a child, for example, and let the child component decide what to do with it.
Again, the child component can't decide what to do with a class, as it can't know specifics about the parent. It would break the modularity.
I checked the most commented issue, it's about the reactivity system doing only one round of checking in topological ordering, which could be fixed, but could cause infinite loop, and again the problem is not implementation, but deciding on the best design:
In my career, I've gone from Waterfall, to XP, to Agile/Scrum methodologies.I've also spent some time doing V-Model. Personally, I'm looking forward to the switch to the "Screw It, This Works"™ methodology. Looking forward to the Addison-Wesley book series!
Edit: I've just founded the "Screw It, This Works"™ Alliance. Sign up today to become a certified SITW Master.
I work in a rather small company, but we are 100% WFH and we span quite a few timezones (From South America to South East Asia). Just yesterday I was summoned at 22:00 to un-fix a small previous fix that had been introduced earlier in the day and was affecting the production site... And the fix was meant "only" for test domains.
The way you earn the certificate is by making it yourself in MS Paint, from one of your other certs and a screenshot of the logo you take from the website.
> So “screw it, this works” seems to be an entirely justifiable methodology.
I've become more aware over the years that some developers, especially very senior ones, are under the fatally mistaken assumption that the problems start when the complaining starts, when it's closer to the truth to say that the real problems start when the complaining ends.
There can be bad developers on any team of course, but there are many developers who know or suspect what they are considering doing is wrong, and discover that asking someone about it is far more trouble than its worth. They either get yelled at or saddled with a bunch of homework because they've drawn attention to a can of worms and are being deputized to fix four things instead of the one they knew about.
Every project has problems. Even the ones that are making millionaires out of relatively new team members. If you aren't hearing about those problems, that's entirely, 100% your fault.
The point of the post isn't that all problems should be given equal credence, but that all problems should be at least acknowledged. Im the end would you rather a Jr. dev who's been working on the project for 6 months be the one who decided whether the problem is important enough to be solved or the Sr/project lead?
You know you can acknowledge a problem and that doesn't mean you have to solve it this very instant, right? It's not a matter of either dropping everything or gaslighting people^W^W dismissing the issue as trivial. There are other choices. Many other choices.
If you don't think the problems people are bringing you have merit, then they won't bring you any problems at all, even when they have merit. Suck it up and realize that you're going to have to allocate a little bit of time on "good problems to have" (if this is our biggest problem right now, things are going very well) or you'll either introduce latency into your early warning system or shut it down entirely.
> if the problem boils down to "this architecture isn't pure enough"
Then the problem is that your coworkers think that purity is a magic shield that will protect them from all ills, which is a bigger problem. You still need to hear it, even if you don't like it.
Honestly though a lot of times when I find myself at odds with someone they try to dismiss my concerns as matters of purity when what I'm really complaining about is the smoke that's coming out of the machine (or the team's ears) because they're riding it too hard. Sharpening the saw isn't aesthetics. Preventing wear and tear isn't some white tower bullshit. It's about keeping something in the tank for the next problem we don't know we have yet. People who don't believe in burnout are doomed to create it, usually in others.
Targets of opportunity are problems that have a distinct value in being solved which is less than the naive cost of fixing it.
Not the actual cost of fixing it, the 'drop everything and work on it now' cost, adjusted for Murphy's law. These are often the sort of 'nice to haves' that come out to 3 months of work, which nobody is going to approve unless a customer is actively yelling in their face about it. And sometimes not even then.
Refactoring is Make the Change Easy, Then Make the Easy Change. If you don't know what your targets of opportunity are, because you have some misguided notion that you can't [have an adult conversation about the state of things](https://www.jimcollins.com/concepts/confront-the-brutal-fact...) without tender egos being hurt, then instead of moving toward any of the horizons you'll just sail in a big circle while people keep trying to get you to venture farther afield.
The problem I often see is in the evaluation of the naive cost of fixing it versus the actual probability your target of opportunity will become a legitimate design consideration. The naive cost almost always is large but the probability your target of opportunity will be necessary is often small or miniscule. It's easy to try to cover all your bases and write something in an unnecessarily flexible way when a concrete implementation would have solved the immediate requirements succinctly and very likely may not to be touched again for years (if ever again).
I really like this quote, and I'm gonna reuse it in a slightly rewritten fashion. In SE teams, indeed, the amount of complacency is directly related to the amount of increasing technical debt.
> when it's closer to the truth to say that the real problems start when the complaining ends
Oh, no, when the complaining ends, the problems didn't just start, they reached the magnitude where they are unsolvable long enough ago that no one even harbors any glimmer of hope of fixing or even meaningfully mitigating them.
... yeah... that's a whole row of ice cream flavors of its own. There's depressed despair, betrayed despair (chocolate and vanilla), cold disdain (mint) and red-hots (if I think about this I will get so angry that I will do something career limiting, so I cannot think about it anymore).
I'm still trying to work out how I communicate to someone that the things I have stopped mentioning might still be bothering me, and so fixing the two things I'm actually harping on won't magically make me happy. Maybe that's just something people are supposed to work out for themselves. Mostly I seem to have figured out how to do this when three or more people are involved (basically hand all of my fodder to someone who is still engaged, and let them run with it), but not when it's one on one. Conversations with people who can't 'look at things' can be exhausting, and that seems to hold no matter which party you are.
> They either get yelled at or saddled with a bunch of homework because they've drawn attention to a can of worms and are being deputized to fix four things instead of the one they knew about.
There is a gradient I've seen with IT workers in general, that is doing IT as a passion and doing IT for a job. Disciplining someone for not knowing enough though is a bit much.
> real problems start when the complaining ends
By this point no one cares anymore and the technical debt is beyond fixing.
I dunno. I know of a project that lingered in this spot for a couple of years before enough people who cared had left to make it a truly lost cause. But there was no leadership to speak of to motivate any of those people, and most of them left. There were points right up until the end where these people were sprinkled across enough of the organization to be a beach head for doing something, but then they lost people on two teams in as many months and from then on it is destined to be status quo. Or at least until they decide to binge on a tech stack update, hire too many people but not for long enough and end up back where they are now. From what I understand they've done that a couple times already.
I think utility-first frameworks like Tailwind are becoming popular because they allow frontend teams to say "screw it" without descending into total anarchy.
Over a lengthy career writing code, I feel like I've gotten pretty good at writing clean, maintainable, legible, changeable code. Especially in the languages I have the most experience in.
I don't feel like I have any idea how to write maintainable legible changeable CSS. Like, it's not just that I can't afford the time -- I just don't know how to do it, despite all my efforts the CSS becomes monstrous, always.
I used to work with 3 versions of a whole css system co-existed. To unfuck css debt is like to do surgery, make it done quick or you have vein spaghetti bleeding .. while is also running service.
This can be a slippery slope. I’ve seen projects with an initial nice hierarchy become spaghetti when engineers looking to save time start throwing important everywhere.
Not that it should never be used. It’s like gotos in C code. They definitely have a purpose but if you find you’ve implemented more than half of your program control via gotos you’ve probably made your codebase into a horrific mess.
That's a quick fix and I fail to see anything engineering specific about it. The same approach can be applied to any other problem in any other profession. Personally, I'm not a fan of this approach.
I also think it's the wrong quick fix. What you want is a rule of increased specificity. Better use a unique id, maybe in conjunction with an element selector.
!important rules should be avoided like the plague
Right, the flaw in this argument:
> Anything else is probably misuse, and a sign you may not understand the cascade properly.
is that it assumes the cost of changing the "whole cascade" is minimal. And that it would be easy to design an initial cascade which works perfectly for your needs without any changes needed as the design evolves. In other words it assumes the classical waterfall method where the spec and design are complete and never-changing once the "implementation" phase begins.
The suggestion is that there is nothing wrong with CSS, only in developers who can not come up with a perfect CSS-design before they start coding.
A big problem with CSS in my view is precisely its cascading nature. When you change anything anywhere it can break things in many other places, and there is no good tool as far as I know that would tell you what all can change because of any given change in a single CSS-rule. It is assumed that developers should have such a tool in their brain, and if you don't you are not a worthy developer. :-)
Having a good justification for misuse doesn't make it not misuse. And bad tooling and hard-to-understand CSS design might be reasonable excuses to not understand cascades, but the point is valid -- even more valid.
> Having a good justification for misuse doesn't make it not misuse.
If there is a good justification for misuse, that would logically mean the original intent isn't applicable to real world scenarios -- which doesn't make the intent incorrect, but it does betray short-sightedness. To claim misuse strictly because it's outside of that extremely narrow original vision, is completely disregarding the actual logistics of front-end development.
It's a bold claim to say that "anything else is misuse". To prove a claim like that you would have to show how every possible use of !important is "misuse", except when it is for font-size problems. Now maybe it is possible to show that every conceivable other use is misuse, but until we see such a proof we shouldn't just take for granted just because somebody makes such a claim.
A better claim would be "I don't see any good reason to use it". Just because one person doesn't see any good reason to use it doesn't mean there isn't one, or two, or three, or more.
It is always very hard to prove a negative ("There isn't any such that ...")
Pemberton is one of the OG designers of the spec. He explained the motivation for the feature when it was designed in committee. It's a much bolder claim to say that because you find it useful in some other way, it's not misuse.
If you have a specific case where you think it shouldn't be considered misuse, I'm sure he'd be happy to explain to you how it should be avoided. He's a friendly guy. But you did not design CSS. He did, so you fundamentally misunderstand that the burden is on you to prove there are cases where !important cannot reasonably be avoided, not the other way around.
When anybody says "Everything else is misuse" that is a very large claim because "everything else" includes very many things. Thus the burden is on them, or you, to give evidence to such a broad claim, if you want us to believe that the validity of such a claim.
I don't have a burden to prove anything since I'm making no claims except saying that whoever makes a broad claim should offer some evidence for it. The broader the claim, more evidence is needed, to convince your readers.
The evidence is that he was one of the designers. You seem to be missing the very simple fact that CSS is has not always existed, and it was not suddenly discovered by programmer explorers, whose prerogative it is to define its usage by their usage. It was designed by a standards body. Of designers. The designers designed the usage, and it's the designers' prerogative to define mis-use.
That's not what it means at all. It just means you find it easier to work outside of the spec's design. He's very clearly saying that if you are doing that, it's always possible to avoid it and work within the intent of the spec instead. If you're happier working outside of that, good for you. The "logistics" of you needing to get your work done has no bearing on what the designers of the tools you're using intended.
> He's very clearly saying that if you are doing that, it's always possible to avoid it and work within the intent of the spec instead.
No, he very plainly (almost literally) said that if the tool isn't used exclusively in the way that he imagined, then you don't understand what you're doing. It was a blatant attempt at belittling a community which has been forced to tirelessly work around CSS's terrible spec for decades.
> The "logistics" of you needing to get your work done has no bearing on what the designers of the tools you're using intended.
You have this completely backward, and you may think you're defending Pemberton, but you're actually making him look more elitist and foolish by highlighting why the real world is different from the spec.
Implementations of CSS have been an absolute disaster since day one, and that is largely because of early design mistakes that did not account for countless scenarios and necessary functionality, making interfaces extremely difficult to both build and test, and forcing browser developers to create their own solutions over decades. A lot of those have been "fixed" by adding completely new methods (flex, etc) to replace the broken concepts, but that doesn't automagically make the original bad spec any better, which to this day still makes everything in CSS more difficult than it needs to be.
If a designer is not factoring in those real-world elements, then they have completely failed at their task, because the real world is the part that actually matters -- everything else is an ideological theory.
I second that. Well said. Trying to get something look like you want with CSS takes too much time. If you know what you want it should be easy but it takes a lot of trial and error. Because of that we now have Flexbox and Grid. The problem with all the new add-ons is the amount of stuff you must learn and remember about how they work and how they work together, or don't, to get the results you want.
Then to hear from someone that the problem is "You don't understand the cascade" is annoying. The question is why don't I understand the cascade? The answer is because it is complicated, and it's not only about understanding it in principle but about then understanding its effects on your (current state of) application, and how you should or could change the cascading elements and or where they are defined to make your app look like you want.
And then the answer is perhaps: "Clearly you don't understand it but it is really easy" -- implying it is difficult for you because you are dumb or lazy and not a very good developer in general. Give me a break :-)
I wonder if it would help if the !important -feature should in fact be extended so you could have !important2, !important3, etc. with increasing levels of importance. That might make things easier, in practice. Or even better make it work like "z-index" does. If z-index can take on any numeric value including negative ones, why not have the same with "importance"?
That would mean that instead of having to calculate the "specificity" in your head, correctly, to understand what is happening with your app, you could just choose the specificity you want and make it part of any rule whose impact you want to differ from the default.
> The question is why don't I understand the cascade? The answer is because it is complicated ...
This is exactly his point! You think it should be correct usage because "CSS is too complicated." Great, good point, most of us would agree that CSS is too complicated. But that does not make it correct usage! It only means CSS is so complicated most people don't use it correctly. A majority of people misusing something doesn't make it correct.
I would have assumed with the level of pedantry that is standard on HN, more people would understand this. But I think in this case the power of fragile egos has overwhelmed pedantic instincts.
One place where I end up using !important very frequently is writing user-styles/extensions for websites. Obviously not a common use case, but it makes me glad that CSS has `!important`.
If you're explicitly trying to overwrite another rule that you do not control, `!important` is more idiomatic than the alternative. (If you've lucky enough to have never had to do this, the alternative is adding otherwise pointless qualifiers to your selector, since CSS gives higher priority to "more specific" selectors. e.g `html > body > div {...}` takes precedence over `div {}`)
You can make the qualifiers less silly looking by matching the qualifier you're trying to override exactly. This makes it more obvious what exactly it is that you are overriding, and has the added benefit of only applying in that one place.
If you explicitly want to change one element in every place, though, !important comes in handy.
Speaking of working with what you've actually got, CSS source code so looks dull and boring, all in the same font and style and format.
I want to be able to mark up my CSS sources with HTML tags, and style it with CSS, so it's beautiful self documenting literate code!
Imagine how easy and pleasurable to read and understand CSS would be you could simply use CSS in your CSS to format "font-weight: bold" in bold, and "font-style: italic" in italic!
I agree that you often need to be pragmatic. Not that the keyword is the definition of grace in any way. If you have to overwrite something later you can append it as the last !important gets precedence.
I am no web developer and I honestly don't like html/css, even if I use it nearly exclusively for visualization by now. There is so much baggage that you basically have to know to be able to create efficient solutions. Wanted to visualize some data where you basically color small cells in a larger table. I used a HTML table tag and styled it with CSS. Big mistake! It was incredibly slow for something very simple, I had perhaps 50,000 cells. Little did I know about the background calculation of html table cells and I also did not know why no browser version of Excel derivative uses that tag to implement their grid.
Of course you can say that everyone knows this. Doesn't change the fact of the severe baggage.
> Engineering is doing what you can with what you've actually got.
Well said.
There's also no mention about !important having that specific purpose in the CSS spec, nor the tweet discusses why other already existing solutions would've not fit that use case.
What's the source for this, I do see they're the CSS co-designer, was this requirement originally written somewhere? I'm looking at the description of important, and I don't see this intention carried through.
If the intention is indeed as described, then the CSS designers failed to communicate it properly, and not "a sign you may not understand the cascade properly."
For the same reason we call it "accessible entrance" and not "government-mandated alternative door with ramp." Making the phrase more general is just good design.
But nobody is saying that accessible entrances should only be used for disabled persons and nothing else.
Here, the author is asserting that there is only one valid use case of !important, and that it shouldn’t be used in the general case. If it shouldn’t be used generally, having a general name is bad design.
> or a pompous person trying to make other devs feel inferior
This is how I felt reading it as well. IMO Steven should exercise a little humility.
It was bad design on his team's part. How is anyone supposed to know that there was only one super secret reason for "!important" to exist? Why not call it something like "!break-cascade-override"? They put an emphasize on making the language look "clean" over real world usability and this is the outcome.
When you say "If the intention is indeed as described," are you referring to the tweet in the submission? Because it looks like the intention is indeed so described in the links you give:
> This CSS feature improves accessibility of documents by giving users with special requirements (large fonts, color combinations, etc.) control over presentation.
Yeah, I seem to recall it was added in Firefox to solve some browser chrome styling issues, or something like that. Anyone any idea where I got that idea from?
I don't doubt the explanation but agree it doesn't totally make sense: an !important-set font-size is not really any more "guaranteed" than another one, as it can just be overridden with another more-specific or later-appearing !important style. So you still have to look at all the styles to be sure you're complying, and if you're going to do that then you might as well just not use !important at all.
Though I'll admit that once you have your "mandatory" size style as !important you'd only have to look at the other !important ones to be sure, so there's something to it.
Of course there's lots of perfectly reasonable uses of !important now: dealing with other peoples' uses of !important.
I wasn't there, but putting myself in the headspace of someone who was and may have had to comply with that law: There are things outside of the individual control of the designer that can override everything except !important. The most obvious example is non-!important rules in user stylesheets.
Today it's obvious that overriding a font-size with a user stylesheet is a bit of an extraordinary measure. You're unlikely to have any legal issues based on somebody shrinking your text using one. This may not have been obvious in the meetings in which CSS was being designed: it's plausible that I might think user stylesheets would be all over the place and have unpredictable effects, including shrinking disclaimers or whatever. On the other hand, putting !important in a user stylesheet could've seemed like an extraordinary measure even then.
But again, I wasn't there. I'm just making semi-educated guesses.
> You're unlikely to have any legal issues based on somebody shrinking your text using one. This may not have been obvious in the meetings in which CSS was being designed: it's plausible that I might think user stylesheets would be all over the place and have unpredictable effects.
Someone predicting "stylesheets all over the place" would have been exactly right, though - practically every single news page on the Internet has questionably-sourced ads, Facebook like buttons, Twitter embeds, and chat/discussion/engagement widgets, all of which have custom stylesheets. The only saving graces come from frequent use of iframes for isolated embeds (which will become less common now with cookie restrictions!), stylesheets well-engineered by well-funded corporations to have every rule prefixed by a custom and dedicated class name for compatibility, and preprocessors and CSS-in-JS that would make that latter approach viable.
Now imagine a world where you're a site operator, !important doesn't exist, and you cannot trust that a site component provider will not install a global CSS rule that will break your legal or branding requirements, with no real way for you to work around it if they do, without unmaintainable specificity boosters for your own components. You simply won't use that site component provider unless it's well-vetted. Which means that there's significantly less innovation on the Internet, because "nobody ever got fired for embedding IBM CSS" becomes an actual thing to think about. !important becomes the escape hatch that the web needs.
There is no law for the designer of CSS system. Only the developers who build UI have any liability to comply with the law. As long as CSS allowed them to render the required font-sizes there was no reason for them build breaks to the cascading to "comply with law", perhaps it makes it easier for developers with this feature to comply to the law, but there was no requirement to make it easy .
>The most obvious example is non-!important rules in user stylesheets.
You are fundamentally unable to force the user to render the text you send them in a particular font size, !important or not. What if they use a text browser and small font size in the terminal?
It's hard for me to imagine a website actually managing to comply with such a requirement. Even if you set a font to "12 points" or whatever in CSS, and the browser respects it, will it actually turn up on every screen at exactly 4.2336 millimetres? I don't know if the law actually requires a particular point size, or uses some other definition.
The most common use for !important is to override something else marked !important. It’s an interesting situation when getting rid of a feature simultaneously removes most of the need for it.
That gives you a specificity that should override everything else. Would only be a problem if some other rule has 3 or more IDs, in which case you can add more here.
I think in this scenario it is supposed to match all div.legal elements. The styles are then applied with the highest priority, thus overriding other rules.
To be fair, I find many of those replies (by other people, that is) painful to read. Completely missing his point. I'd probably also get a bit annoyed after the fifth person pointed out something because they completely misunderstood what I said.
What is his point? It just reads as blame-shifting. Introduction of an unidiomatic feature into the standard for a particular use case is an acknowledgment of deficiency or incompleteness of the whole standard.
I read his point being that !important used for anything but the original intent is "code smell", and I'm fully behind that. He doesn't imply that you mustn't use it for anything but its designed purpose, I'm sure he is enough of an engineer to know that sometimes you cannot stick to your ideals. He's probably well aware that some people have to rely on frameworks which already use !important, so they have to work around that by using !important as well. None of that contradicts what he says, but it's still a misuse of the feature.
> I read his point being that !important used for anything but the original intent is "code smell", and I'm fully behind that.
It doesn't explain why using !important for the original intent isn't equally a "code smell".
Unless that is smelly too, in which case there are even more questions to answer about why this is the workaround and why you're supposed to use it for the original intent despite that.
We're only hearing about the "original intent" now, via a smug tweet in 2022. It doesn't say much about someone who insinuates people "don't understand the cascade" if they don't follow an undisclosed design spec.
And if they wanted it to be for font size only, they should have made it work only for fonts rather than any property.
the point is it should never been in css in first place. and css works better without it. I think he is frustrated because nobody takes the time to understand the cascade
I would be annoyed as well, however if I tweet this instead of say write a well thought out article/blog with some references then I should expect low quality responses.
Unless I'm missing some context it seems like this guy tweeted something intentionally cryptic, inflammatory, and baiting for no apparent reason then got mad when people took the bait?
The same thing can be said for a lot of things with CSS…
The @media rule was added for one reason only: provide different styles for different media types. It wasn’t intended to be used to make responsive websites. Is using it to make responsive websites an incorrect usage?
It's different from the implementer's perspective because the implementer can go back to the CEO (maybe indirectly) saying "I can make that work 80% of the time, but it just can't be done for the 20% of users who have expressed a preference to the contrary". In your example the CEO gets the option to say "OK, make it work most of the time". In a compliance situation, the CEO is legally obligated to can the whole project, find someone willing to put the text in a JPEG with the attendant accessibility issues, or some other draconian maneuver.
If you send me a government mandated form, and I scrible on it, you aren't liable for anything. The only potential concern is if the content is deployed through a framework like Wordpress that might add CSS.
Anyone have an idea of which part of US Code would require this? I have a hard time imagining it's that prescriptive about font sizes (especially given that different fonts have different glyph sizes, DPI on monitors results in different physical rendering sizes etc.) Only thing that comes to mind is that Apple court case many years back where the judge told them they had to have a disclaimer on their page in a certain size and color as part of the judgement.
css "co" designer. that explains a lot. horse by committee.
i find many uses. sometimes you need to override a style coming from an external or to apply a rule globally, you can just use !important and know that it will work regardless of individual specificity in all instances of that selector.
yes, you could override it with specificity but why bother, a hack is a hack
Yes, it's by far the most common use of "!" in programming (though newer languages are increasingly using it for various flavours of null/nothing checking too). Javascript just seems particularly relevant here.
Can anyone give an ELI5 to us curious non-webdevs about why !important seems to be A Thing? (As a sysadmin I'll probably never have a practical need for this, but it's always fun learning about the various niches in 'tech'.)
Not a webdev by profession, but hand-coded a few hobby sites - !important is used as a duct-tape "just do the dang thing" hack if you need to overrule a bunch of the current styling rules and don't want to think too hard about it.
CSS stands for Cascading Style Sheets. The cascading part refers to the fact that when you have a HTML element which is targeted by multiple style rules (e.g. browser defaults, style sheets, inline `style=""` attributes, inherited from a parent element's rules, etc.), there's a well defined priority order which decides which style "wins" and is in effect.
For example, you might define that all body text is black, but then also have a rule that says that if it's a link (an `<a>` element), it's blue. Suppose you want other links to be blue, but the links in your navigation bar should also be black. Can do, just specify `nav a { color: black }` - now rest of the links are blue, except inside your navbar.
This is neat, because with relatively concise notation, you can specify styles for the majority of your site, but can also easily specialize styles when you need to. Compare that to manually setting `style=""` attributes on every single HTML element!
So what's the problem with !important then? !important is #1 in the priority order I mentioned previously, so when you add !important to a CSS declaration, you throw out the first C from CSS. You're saying "I don't care what any other stylesheet or style rule says - ignore them and use this rule". To beat !important, you need to also add !important, and additionally make your CSS rule more "specific" than the other, e.g. `nav a { color: black }` beats `a { color: black }` because it's more specific - "target <a> inside a <nav>".
This becomes very problematic if e.g. a third party component uses !important in its rules. Let's say that third party component's stylesheet overrides all <a> elements to be red. Great! Every single link is now red - including the ones in your navbar. You'll now need to go back to your own rules and add !important there - meaning now you need to use !important in every single declaration to get the C back into CSS.
CSS !Important is a nice fail safe or safety valve for emergencies. It is good design to have safety valves in a system. Sure, you should not be encouraged to use it under normal circumstances. As with other fail safe features, it is meant for extreme scenarios you can sometimes predict, but more importantly for reasons you CANNOT predict. So this tweet arguing that it is meant for one reason is invalidating why it is good design.
After blocking popups on some sites, the scrollbar is dtill hidden, making it impossible to scroll (like on twitter, for example). With the help of !important, the scroll bar can be forcibly turned on by adding uBlock cosmetic filters. Works on per-site basis, but can be added globally, though some sites break a bit, like the top header on Wikipedia starts behaving strangely.
Zapper is a special feature, entirely unrelated to cosmetic filtering. When you zap an element, the element is removed from the DOM, and the zapper code will also look at the DOM to find out if any of the parent elements are scroll-locked, and if so will defuse it with an inline style using `!important`.[1]
As for cosmetic filtering, it's is the hiding of elements using `display: none !important`, so `!important` is also key to ensure page styles are overridden.[2]
344 comments
[ 2.8 ms ] story [ 417 ms ] threadThe cascading is pretty nice actually. Think about using CSS vars... you can dynamically theme apps because of the cascade, by changing just 1 class. there's other nice attributes, and it's true it requires discipline. Just not nearly as much as you imply
But with the cascade, call sites are implicit — and removal, for better and worse, doesn't cause a hard error.
All it takes is a single rogue engineer or product manager to mess things up. And then cleaning things up later is difficult because of all the places that have to be inspected.
That's completely impractical[0] given inclusion of 3rd-party code and no enforceable standard for imposing step 2 on other developers.
(Web components now exist to facilitate this, but of course, web components are relatively recent; most of CSS's history did not support this 4-step process).
[0] To be fair, maybe completely is too strong an assertion. I've seen something like it done... A compiler rewrites the CSS selectors and the CSS classes to create a sort of top-level namespace by prepending some garbage per module so that no component can accidentally reference another component. It's not great for debuggability (about as much fun as having to deal with the actual entrypoint names in the binary for constructors and overloads when debugging C++), but it gets the job done.
I mean, I just prepend all my component class names with my library name or a shorthand acronym, so 100% of my styles are like `.NawgzInput {}` or `.NawgzGraphNode {}`
I have never seen the limitation to this approach (i.e. the ends of its ability to scale), so long as you don't pick a super generic prefix. So to hear you assert this approach is "completely impractical" to someone who has used it to build their own component library that every application they build is entirely comprised of.. rings hollow
That's the best I think we have now. It's not good (i.e. decreases readability), and it's not universal (there are definitely component frameworks out there where the classes are just named "table" and "button").
Except it's incredibly easy to debug and avoids most of your complaints about the solution.
Anyways, fair enough, I can confess that there is probably another ideal world that has better viewport styling. But CSS is giving us incredible flexibility, and just like JS, its warts can be worked around very easily and deliver you a powerful, useful, simple set of capabilities.
"Global all the things" seems to clash with "component".
Its more of a belief rather than knowledge at this point.
I'd be interested to hearing a good answer as to why one wouldn't use !important on a modifier class such as ".padding-20" or even something like ".full-width".
Surely the problem lies with your html composition if either of these classes are being used on an element that does not need them?
Over time, accrued wisdom has turned into a rule of thumb such that Grumpy Old Developers sit around the fire with Young Energetic Developers and say “ya know, child, never use !important, it’s bad design.”
The web development industry is getting mature enough to even have this kind of wisdom, which is wonderful, even if (like “wive’s tales”) the principle is overstated.
> Note: Repeated occurrences of the same simple selector are allowed and do increase specificity.
[0] https://www.w3.org/TR/selectors-3/#specificity
*:is(#a#b, .someclass) {...}
overrides any selector with a single id; you add more ids to override more specific selectors (except inline stiles and !important)
If you really have to select that element by ID for some reason, you can use an attribute selector instead—`[id=foo]`—and then it’s also in bucket B and can be controlled in the normal way.
Basically, you should consider ID selectors (and element selectors) an antipattern and never use them.
[0] https://www.w3.org/TR/selectors-4/#specificity-rules
Edit: Take this example:
If I can't control the order the CSS is loaded, and I can't change that line directly, how do I modify it? Like this: The use of !important isn't some simple way of bypassing ever-increasing specificity. In many cases it just makes things more complex.At one place I worked (a subsidiary of NTT), the effort to clean up the CSS and remove all the !important overrides was so time consuming management wanted to make sure it never happened again, so using !important at all would affect our performance reviews. We were expected to fix any bad CSS right away without overriding the default cascading rules.
True that, but sometimes one has already reached that point, and yet must make this change anyway somehow. But I don't recall using "important" in years, so I guess it's not that often.
So “screw it, this works” seems to be an entirely justifiable methodology.
How about something like Ant Design?
This, to me, is a feature. Don’t customise it.
THis is made significantly easier when you have designers working with this "design library" mindset also.
I don't think this is true. The biggest problem is people who write CSS do it as if they want CSS to be something else and are trying to force it to be that.
Writing CSS using ITCSS (Inverted Triangle CSS) [1] solves so many of the issues devs complain about it. It's simple: create layers in specificity order. Don't fight the cascade; make it work for you.
Writing good CSS isn't about getting the syntax right; it's about getting the architecture right [2].
Harry Robert's video does a great job of describing all the pain points ITCSS solves [3].
[1]: https://dev.to/carlillo/understanding-itcss-real-case-using-...
[2]: https://www.xfive.co/blog/itcss-scalable-maintainable-css-ar...
[3]: https://www.youtube.com/watch?v=1OKZOV-iLj4
I think it’s hard to hire lots (…hundreds) of developers who’s going to know CSS well enough to not screw it up.
Nicely put. I've stressed over finding unused rules, restructuring, etc. but in the end it never matters as long as it displays correctly.
In addition, there is the difficulty of inspecting those sites which you can identify to verify that display is correct, which is hard to achieve programmatically.
- Avoid cascading (i.e. no nested selectors except when there's "no other way")
- Implement separate selectors for styling and page/component layout (separation of concerns)
- Using a good naming convention and stick with it
The first point can also be achieved with using style attributes if that floats your boat, although Svelte kind of gives you the best of both worlds just by compartmentalizing the CSS, not necessarily by preventing cascading.
I can't remember the last time I ever had to use !important except when I had to work with some ridiculous CSS "framework" my predecessors chose to use. At least !important was understandable back in the days when it was really hard to achieve some things with CSS, but these days I believe there's little to no excuse.
Importing HTML files as modules with localized CSS+JS as web components would be one such option for example.
Styling is setting colors/fonts/padding etc on a specific component.
eg. .sign-up-form .delete-button .accept-button
Yep. I find of the usage of !important I see daily is failure of the programmer to understand precedence rules, which, as you pointed towards, is mostly due to cascading.
[1] Why would you want to do this? Well, what about layout? And what if you have a component that wraps or otherwise behaves like an HTML element?
[2] Of course Tailwind supports modifiers, which do cascade, but everything is still local to a single element.
> Why would you want to do this? Well, what about layout? And what if you have a component that wraps or otherwise behaves like an HTML element?
Yes, it's nothing something you'd want to do willy-nilly or all the time, but there are perfectly valid use cases. This issue has been one of the single most-commented in the Svelte repos with tons of back and forth and a lot of demand so this isn't just an obscure complaint either.
As for how to resolve it, there are plenty of clean ways to do it. Svelte's style scoping is done via a unique class per component. It suffices to simply provide some way to pass this class from a parent to a child, for example, and let the child component decide what to do with it. There are many possible variations on this theme. The obstacle to resolving this problem isn't technical infeasibility, it's that to date the maintainers just haven't cared.
Again, the child component can't decide what to do with a class, as it can't know specifics about the parent. It would break the modularity.
I checked the most commented issue, it's about the reactivity system doing only one round of checking in topological ordering, which could be fixed, but could cause infinite loop, and again the problem is not implementation, but deciding on the best design:
https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3A...
Edit: I've just founded the "Screw It, This Works"™ Alliance. Sign up today to become a certified SITW Master.
This is a sub-domain of Fuck Users, Ship Excrement, or FUSE-Dev.
Where is the conference and the website to download a frameable printable "Certified SITW Master" certificate?
Then you can have the SITH Alliance and give out SITH master certifications.
I've become more aware over the years that some developers, especially very senior ones, are under the fatally mistaken assumption that the problems start when the complaining starts, when it's closer to the truth to say that the real problems start when the complaining ends.
There can be bad developers on any team of course, but there are many developers who know or suspect what they are considering doing is wrong, and discover that asking someone about it is far more trouble than its worth. They either get yelled at or saddled with a bunch of homework because they've drawn attention to a can of worms and are being deputized to fix four things instead of the one they knew about.
Every project has problems. Even the ones that are making millionaires out of relatively new team members. If you aren't hearing about those problems, that's entirely, 100% your fault.
Its often a pointless effort, especially if the problem boils down to "this architecture isn't pure enough"
If you don't think the problems people are bringing you have merit, then they won't bring you any problems at all, even when they have merit. Suck it up and realize that you're going to have to allocate a little bit of time on "good problems to have" (if this is our biggest problem right now, things are going very well) or you'll either introduce latency into your early warning system or shut it down entirely.
> if the problem boils down to "this architecture isn't pure enough"
Then the problem is that your coworkers think that purity is a magic shield that will protect them from all ills, which is a bigger problem. You still need to hear it, even if you don't like it.
Honestly though a lot of times when I find myself at odds with someone they try to dismiss my concerns as matters of purity when what I'm really complaining about is the smoke that's coming out of the machine (or the team's ears) because they're riding it too hard. Sharpening the saw isn't aesthetics. Preventing wear and tear isn't some white tower bullshit. It's about keeping something in the tank for the next problem we don't know we have yet. People who don't believe in burnout are doomed to create it, usually in others.
YAGNI applies to a lot more than most people think it does.
Not the actual cost of fixing it, the 'drop everything and work on it now' cost, adjusted for Murphy's law. These are often the sort of 'nice to haves' that come out to 3 months of work, which nobody is going to approve unless a customer is actively yelling in their face about it. And sometimes not even then.
Refactoring is Make the Change Easy, Then Make the Easy Change. If you don't know what your targets of opportunity are, because you have some misguided notion that you can't [have an adult conversation about the state of things](https://www.jimcollins.com/concepts/confront-the-brutal-fact...) without tender egos being hurt, then instead of moving toward any of the horizons you'll just sail in a big circle while people keep trying to get you to venture farther afield.
I really like this quote, and I'm gonna reuse it in a slightly rewritten fashion. In SE teams, indeed, the amount of complacency is directly related to the amount of increasing technical debt.
Oh, no, when the complaining ends, the problems didn't just start, they reached the magnitude where they are unsolvable long enough ago that no one even harbors any glimmer of hope of fixing or even meaningfully mitigating them.
I'm still trying to work out how I communicate to someone that the things I have stopped mentioning might still be bothering me, and so fixing the two things I'm actually harping on won't magically make me happy. Maybe that's just something people are supposed to work out for themselves. Mostly I seem to have figured out how to do this when three or more people are involved (basically hand all of my fodder to someone who is still engaged, and let them run with it), but not when it's one on one. Conversations with people who can't 'look at things' can be exhausting, and that seems to hold no matter which party you are.
There is a gradient I've seen with IT workers in general, that is doing IT as a passion and doing IT for a job. Disciplining someone for not knowing enough though is a bit much.
> real problems start when the complaining ends
By this point no one cares anymore and the technical debt is beyond fixing.
I don't feel like I have any idea how to write maintainable legible changeable CSS. Like, it's not just that I can't afford the time -- I just don't know how to do it, despite all my efforts the CSS becomes monstrous, always.
Not that it should never be used. It’s like gotos in C code. They definitely have a purpose but if you find you’ve implemented more than half of your program control via gotos you’ve probably made your codebase into a horrific mess.
I also think it's the wrong quick fix. What you want is a rule of increased specificity. Better use a unique id, maybe in conjunction with an element selector.
!important rules should be avoided like the plague
is that it assumes the cost of changing the "whole cascade" is minimal. And that it would be easy to design an initial cascade which works perfectly for your needs without any changes needed as the design evolves. In other words it assumes the classical waterfall method where the spec and design are complete and never-changing once the "implementation" phase begins.
The suggestion is that there is nothing wrong with CSS, only in developers who can not come up with a perfect CSS-design before they start coding.
A big problem with CSS in my view is precisely its cascading nature. When you change anything anywhere it can break things in many other places, and there is no good tool as far as I know that would tell you what all can change because of any given change in a single CSS-rule. It is assumed that developers should have such a tool in their brain, and if you don't you are not a worthy developer. :-)
If there is a good justification for misuse, that would logically mean the original intent isn't applicable to real world scenarios -- which doesn't make the intent incorrect, but it does betray short-sightedness. To claim misuse strictly because it's outside of that extremely narrow original vision, is completely disregarding the actual logistics of front-end development.
A better claim would be "I don't see any good reason to use it". Just because one person doesn't see any good reason to use it doesn't mean there isn't one, or two, or three, or more.
It is always very hard to prove a negative ("There isn't any such that ...")
If you have a specific case where you think it shouldn't be considered misuse, I'm sure he'd be happy to explain to you how it should be avoided. He's a friendly guy. But you did not design CSS. He did, so you fundamentally misunderstand that the burden is on you to prove there are cases where !important cannot reasonably be avoided, not the other way around.
I don't have a burden to prove anything since I'm making no claims except saying that whoever makes a broad claim should offer some evidence for it. The broader the claim, more evidence is needed, to convince your readers.
No, he very plainly (almost literally) said that if the tool isn't used exclusively in the way that he imagined, then you don't understand what you're doing. It was a blatant attempt at belittling a community which has been forced to tirelessly work around CSS's terrible spec for decades.
> The "logistics" of you needing to get your work done has no bearing on what the designers of the tools you're using intended.
You have this completely backward, and you may think you're defending Pemberton, but you're actually making him look more elitist and foolish by highlighting why the real world is different from the spec.
Implementations of CSS have been an absolute disaster since day one, and that is largely because of early design mistakes that did not account for countless scenarios and necessary functionality, making interfaces extremely difficult to both build and test, and forcing browser developers to create their own solutions over decades. A lot of those have been "fixed" by adding completely new methods (flex, etc) to replace the broken concepts, but that doesn't automagically make the original bad spec any better, which to this day still makes everything in CSS more difficult than it needs to be.
If a designer is not factoring in those real-world elements, then they have completely failed at their task, because the real world is the part that actually matters -- everything else is an ideological theory.
Then to hear from someone that the problem is "You don't understand the cascade" is annoying. The question is why don't I understand the cascade? The answer is because it is complicated, and it's not only about understanding it in principle but about then understanding its effects on your (current state of) application, and how you should or could change the cascading elements and or where they are defined to make your app look like you want.
And then the answer is perhaps: "Clearly you don't understand it but it is really easy" -- implying it is difficult for you because you are dumb or lazy and not a very good developer in general. Give me a break :-)
I wonder if it would help if the !important -feature should in fact be extended so you could have !important2, !important3, etc. with increasing levels of importance. That might make things easier, in practice. Or even better make it work like "z-index" does. If z-index can take on any numeric value including negative ones, why not have the same with "importance"?
That would mean that instead of having to calculate the "specificity" in your head, correctly, to understand what is happening with your app, you could just choose the specificity you want and make it part of any rule whose impact you want to differ from the default.
"Custom Specificity for CSS"
This is exactly his point! You think it should be correct usage because "CSS is too complicated." Great, good point, most of us would agree that CSS is too complicated. But that does not make it correct usage! It only means CSS is so complicated most people don't use it correctly. A majority of people misusing something doesn't make it correct.
I would have assumed with the level of pedantry that is standard on HN, more people would understand this. But I think in this case the power of fragile egos has overwhelmed pedantic instincts.
If you're explicitly trying to overwrite another rule that you do not control, `!important` is more idiomatic than the alternative. (If you've lucky enough to have never had to do this, the alternative is adding otherwise pointless qualifiers to your selector, since CSS gives higher priority to "more specific" selectors. e.g `html > body > div {...}` takes precedence over `div {}`)
If you explicitly want to change one element in every place, though, !important comes in handy.
I want to be able to mark up my CSS sources with HTML tags, and style it with CSS, so it's beautiful self documenting literate code!
Imagine how easy and pleasurable to read and understand CSS would be you could simply use CSS in your CSS to format "font-weight: bold" in bold, and "font-style: italic" in italic!
!important-10 > !important-9 > ...
we need more important stuff!
I am no web developer and I honestly don't like html/css, even if I use it nearly exclusively for visualization by now. There is so much baggage that you basically have to know to be able to create efficient solutions. Wanted to visualize some data where you basically color small cells in a larger table. I used a HTML table tag and styled it with CSS. Big mistake! It was incredibly slow for something very simple, I had perhaps 50,000 cells. Little did I know about the background calculation of html table cells and I also did not know why no browser version of Excel derivative uses that tag to implement their grid.
Of course you can say that everyone knows this. Doesn't change the fact of the severe baggage.
Well said.
There's also no mention about !important having that specific purpose in the CSS spec, nor the tweet discusses why other already existing solutions would've not fit that use case.
https://www.w3.org/TR/css-cascade-5/#important
https://www.w3.org/TR/css-cascade-5/#importance
If the intention is indeed as described, then the CSS designers failed to communicate it properly, and not "a sign you may not understand the cascade properly."
Here, the author is asserting that there is only one valid use case of !important, and that it shouldn’t be used in the general case. If it shouldn’t be used generally, having a general name is bad design.
or the React way, "!enforce--only-use-this-for-legal-font-size-or-you-will-be-fired"
The example or use case they describe doesn't even make sense to me. Nor does it even seem to line up with how CSS specificity or cascade works.
"Here's a paper to write on, oh wait why are you drawing, this is a writing paper, you're doing it wrong!"
This is how I felt reading it as well. IMO Steven should exercise a little humility.
It was bad design on his team's part. How is anyone supposed to know that there was only one super secret reason for "!important" to exist? Why not call it something like "!break-cascade-override"? They put an emphasize on making the language look "clean" over real world usability and this is the outcome.
> Alas not. I wish there had been an agreement that after some number of years the records would be made public.
https://twitter.com/stevenpemberton/status/15059585359763456...
> This CSS feature improves accessibility of documents by giving users with special requirements (large fonts, color combinations, etc.) control over presentation.
> If you need to set font-sizes with !important you also don't understand the cascade
If law requires you to make certain text a certain size, just do so.
Without any more background information, this explanation for !important doesn't make any sense.
Though I'll admit that once you have your "mandatory" size style as !important you'd only have to look at the other !important ones to be sure, so there's something to it.
Of course there's lots of perfectly reasonable uses of !important now: dealing with other peoples' uses of !important.
Today it's obvious that overriding a font-size with a user stylesheet is a bit of an extraordinary measure. You're unlikely to have any legal issues based on somebody shrinking your text using one. This may not have been obvious in the meetings in which CSS was being designed: it's plausible that I might think user stylesheets would be all over the place and have unpredictable effects, including shrinking disclaimers or whatever. On the other hand, putting !important in a user stylesheet could've seemed like an extraordinary measure even then.
But again, I wasn't there. I'm just making semi-educated guesses.
Someone predicting "stylesheets all over the place" would have been exactly right, though - practically every single news page on the Internet has questionably-sourced ads, Facebook like buttons, Twitter embeds, and chat/discussion/engagement widgets, all of which have custom stylesheets. The only saving graces come from frequent use of iframes for isolated embeds (which will become less common now with cookie restrictions!), stylesheets well-engineered by well-funded corporations to have every rule prefixed by a custom and dedicated class name for compatibility, and preprocessors and CSS-in-JS that would make that latter approach viable.
Now imagine a world where you're a site operator, !important doesn't exist, and you cannot trust that a site component provider will not install a global CSS rule that will break your legal or branding requirements, with no real way for you to work around it if they do, without unmaintainable specificity boosters for your own components. You simply won't use that site component provider unless it's well-vetted. Which means that there's significantly less innovation on the Internet, because "nobody ever got fired for embedding IBM CSS" becomes an actual thing to think about. !important becomes the escape hatch that the web needs.
You are fundamentally unable to force the user to render the text you send them in a particular font size, !important or not. What if they use a text browser and small font size in the terminal?
The legal requirement explanation makes 0 sense.
NFC.
I'm thankful that I only ever do it in contexts where I control all the CSS and don't have to do silly stuff like that
It doesn't explain why using !important for the original intent isn't equally a "code smell".
Unless that is smelly too, in which case there are even more questions to answer about why this is the workaround and why you're supposed to use it for the original intent despite that.
We're only hearing about the "original intent" now, via a smug tweet in 2022. It doesn't say much about someone who insinuates people "don't understand the cascade" if they don't follow an undisclosed design spec.
And if they wanted it to be for font size only, they should have made it work only for fonts rather than any property.
[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
The @media rule was added for one reason only: provide different styles for different media types. It wasn’t intended to be used to make responsive websites. Is using it to make responsive websites an incorrect usage?
The law itself does not prescribe specific font sizes, but ensuring minimum font sizes is necessary to comply with the law.
Sounds made up
i find many uses. sometimes you need to override a style coming from an external or to apply a rule globally, you can just use !important and know that it will work regardless of individual specificity in all instances of that selector.
yes, you could override it with specificity but why bother, a hack is a hack
For example, you might define that all body text is black, but then also have a rule that says that if it's a link (an `<a>` element), it's blue. Suppose you want other links to be blue, but the links in your navigation bar should also be black. Can do, just specify `nav a { color: black }` - now rest of the links are blue, except inside your navbar.
This is neat, because with relatively concise notation, you can specify styles for the majority of your site, but can also easily specialize styles when you need to. Compare that to manually setting `style=""` attributes on every single HTML element!
So what's the problem with !important then? !important is #1 in the priority order I mentioned previously, so when you add !important to a CSS declaration, you throw out the first C from CSS. You're saying "I don't care what any other stylesheet or style rule says - ignore them and use this rule". To beat !important, you need to also add !important, and additionally make your CSS rule more "specific" than the other, e.g. `nav a { color: black }` beats `a { color: black }` because it's more specific - "target <a> inside a <nav>".
This becomes very problematic if e.g. a third party component uses !important in its rules. Let's say that third party component's stylesheet overrides all <a> elements to be red. Great! Every single link is now red - including the ones in your navbar. You'll now need to go back to your own rules and add !important there - meaning now you need to use !important in every single declaration to get the C back into CSS.
So the exclamation mark basically takes on its 'linguistic meaning' that this particular definition should be given extra emphasis.
I was interpreting the "!" in this conversation as it is often used in tech, as a "not-" prefix. :)
Thanks.
>> PATH=/special myscript.sh
https://www.reddit.com/r/uBlockOrigin/comments/ce4mok/how_to...
https://nitter.net/about offers a better experience IMHO, because it's fast.
Is this what the death of the open web feels like?
As for cosmetic filtering, it's is the hiding of elements using `display: none !important`, so `!important` is also key to ensure page styles are overridden.[2]
---
[1] https://github.com/gorhill/uBlock/blob/12ab8664a30538570d395...
[2] https://github.com/gorhill/uBlock/blob/12ab8664a30538570d395...
For reference, Tk, which was conceptually a decent GUI toolkit ( https://en.wikipedia.org/wiki/Tk_(software) ), was launched in 1991.
CSS was launched in 1996...