惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
GbyAI
GbyAI
博客园 - Franky
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
The Register - Security
The Register - Security
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
InfoQ
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Full Disclosure
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
博客园 - 【当耐特】
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Project Zero
Project Zero
量子位
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
美团技术团队
Attack and Defense Labs
Attack and Defense Labs
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Blog of Author Tim Ferriss
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Troy Hunt's Blog
Google Online Security Blog
Google Online Security Blog
罗磊的独立博客
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
S
SegmentFault 最新的问题
L
LINUX DO - 最新话题
Simon Willison's Weblog
Simon Willison's Weblog
爱范儿
爱范儿
博客园 - 聂微东
A
About on SuperTechFans
PCI Perspectives
PCI Perspectives
D
Docker

CSS Wizardry

Front-End’s Missing Metric: The TBT Window Meet Your Users Where They Are with Obs.js Better Browser Caching with No-Vary-Search font-family Doesn’t Fall Back the Way You Think What Is CSS Containment and How Can I Use It? When All You Can Do Is All or Nothing, Do Nothing Obs.js: Context-Aware Web Performance for Everyone Low- and Mid-Tier Mobile for the Real World (2025) The Fastest Site in the Tour de France Making Sense of the Performance Extensibility API Why Do We Have a Cache-Control Request Header? HTML Is Not a Programming Language… Build for the Web, Build on the Web, Build with the Web Licensing Code on CSS Wizardry A Layered Approach to Speculation Rules Designing (and Evolving) a New Web Performance Score Core Web Vitals Colours The Ultimate Contract Templates for Tech Consultants: Protect Your Business and Get Paid Optimising for High Latency Environments Cache Grab: How Much Are You Leaving on the Table? blocking=render: Why would you do that?! Correctly Configure (Pre) Connections The Three Cs: 🤝 Concatenate, 🗜️ Compress, 🗳️ Cache What Is the Maximum max-age? How to Clear Cache and Cookies on a Customer’s Device The Ultimate Low-Quality Image Placeholder Technique Core Web Vitals for Search Engine Optimisation: What Do We Need to Know? The HTTP/1-liness of HTTP/2 In Defence of DOM­Content­Loaded Site-Speed Topography Remapped Why Not document.write()? Speeding Up Async Snippets Critical CSS? Not So Fast! Measure What You Impact, Not What You Influence Optimising Largest Contentful Paint Measuring Web Performance in Mobile Safari Site-Speed Topography Speed Up Google Fonts Real-World Effectiveness of Brotli Performance Budgets, Pragmatically Lazy Pre-Browsing with Prefetch Making Cloud.typography Fast(er) Time to First Byte: What It Is and How to Improve It Self-Host Your Static Assets Tips for Technical Interviews Cache-Control for Civilians Bandwidth or Latency: When to Optimise for Which ITCSS × Skillshare What If? CSS and Network Performance The Three Types of Performance Testing Getting to Know a Legacy Codebase Image Inconsistencies: How and When Browsers Download Images Identifying, Auditing, and Discussing Third Parties My Digital Music Setup Measuring the Hard-to-Measure Finding Dead CSS The Fallacies of Distributed Computing (Applied to Front-End Performance) Ten Years Old Relative Requirements Airplanes and Ashtrays Performance and Resilience: Stress-Testing Third Parties Refactoring Tunnels Little Things I Like to Do with Git Writing Tidy Code Configuring Git and Vim Base64 Encoding & Performance, Part 2: Gathering Data Base64 Encoding & Performance, Part 1: What’s Up with Base64? Code Smells in CSS Revisited Typography for Developers Moving CSS Wizardry onto HTTPS and HTTP/2 Ack for CSS Developers A New Year, a New Focus Preparing Vim for Apple’s Touch Bar Choosing the Correct Average CSS Shorthand Syntax Considered an Anti-Pattern CSS Wizardry Newsletter Nesting Your BEM? Improving Perceived Performance with Multiple Background Images Continue Normalising Your CSS Pure CSS Content Filter Pragmatic, Practical, and Progressive Theming with Custom Properties Refactoring CSS: The Three I’s Speaker’s Checklist: Before and After Your Talk Improving Your CSS with Parker Mixins Better for Performance Managing Typography on Large Apps White October Events Workshop Partnership BEMIT: Taking the BEM Naming Convention a Step Further Travelling Like You Want to, When You Have To Contextual Styling: UI Components, Nesting, and Implementation Detail Subtleties with Self-Chained Classes Cyclomatic Complexity: Logic in CSS Immutable CSS Can CSS Be Too Modular? More Transparent UI Code with Namespaces When to use @extend; when to use a mixin The Specificity Graph CSS Wizardry Ltd.: Year 1 in review CSS Guidelines 2.0.0
The Importance of !important: Forcing Immutability in CSS
Harry Roberts · 2016-05-09 · via CSS Wizardry

Written by on CSS Wizardry.

Table of Contents

Independent writing is brought to you via my wonderful Supporters.

  1. Never Use !important in Anger
    1. Hacking Specificity
  2. Forcing Immutability with !important
  3. A Note on Utility Classes

There’s a piece of advice I give out to clients and workshop attendees that is often met with shock and horror:

I advise the use of !important.

For the most part, I’m glad that the initial reaction is disgust—!important usually is bad news—however, there’s a little more to it than that…

As with most things, there are exceptional circumstances in which following the rules would actually be a pretty bad idea, and it’s usually context and discretion that inform our decision to break them.

For example, in the UK, the speed limit is 70mph (unfortunately we do still use miles). You are not allowed to drive faster than 70mph. It’s illegal. You just can’t do it.

However… if your friend is dying in the back seat and you’re trying to get them to hospital before they bleed out everywhere, by all means, drive faster than 70mph!

In 90% of situations, the rule is a good one. By and large, we’re much better off following it than not following it. But there will definitely be situations that fall outside of that 90%.

Similarly, as we mature as developers, we need to recognise that the rules we live by will also have exceptions, given the correct circumstances.

With age (or time, I guess) comes wisdom, so with that it mind I would always tell junior developers not to use !important at all. But, once developers start to grow and learn that things aren’t always that black and white, we can get a little more detailed and nuanced, and throw in some caveats.

But before we look at the exceptions to the rule, let’s look at the rule itself.

Never Use !important in Anger

Using !important reactively is the most heavy-handed, nuclear, all-the-way-up-to-11 option we have at our disposal. Using !important to get yourself out of a problem with some existing CSS is most certainly inadvisable. It will have knock-on effects whose only solution will be to use another !important, then another, then another, ad infinitum.

Do not use !important reactively. Do not use !important to solve a specificity issue. Do not use !important in anger.

Hacking Specificity

If we do find ourselves in a situation where existing styles are overriding our current work, we have much safer methods of altering their specificity.

If we need to bump the specificity of a single class up, we can chain it with itself (e.g. .btn.btn {}). If we need to bring the specificity of an ID down, we can rewrite it as an attribute selector (e.g. [id="header"] {}). You can read about that in much more detail in my Hacks for Dealing with Specificity article.

Most of the time, there is no need to turn to an !important.

Right. When can we use it?

Forcing Immutability with !important

The idea of immutability is one that really fascinates and resonates with me. The idea that something can never be changed after it’s been created sounds amazing! How much more confidence would we have if we knew that something always looked and behaved the same no matter where we put it? I like that idea a lot!

This is typically quite hard to achieve in CSS because it’s designed around an inheritance-based model which makes heavy use of mutations. But, there is a specific type of rule that can actually make great use of immutability, and do so very safely: utility classes.

Utility classes are tiny little classes that carry out very specific, very explicit jobs. Classes like:

.u-text-center { text-align: center; }

.u-float-left { float: left; }

.u-text-large { font-size: 48px; }

They all begin with a u- in order to tell the next developer what their purpose is, and they all carry out just one simple piece of styling.

All of the declarations in the rulesets above are defined without an !important on them, but they really, really ought to be. Here’s why:

By using a class like u-text-center in our HTML, we are making a definite, clear, unambiguous decision that we want some text to be centrally aligned. There is absolutely no question about that. However, the selector .u-text-center {} has a relatively low specificity, so there’s a chance that another selector could accidentally override it. Take the following HTML and CSS:

.sub-content h2 {
  ...
  text-align: left;
}

.u-text-center {
  text-align: center;
}
<div class="sub-content">
  <h2 class="u-text-center">...</h2>
</div>

Unfortunately, we have a specificity mismatch here: .sub-content h2 {} has a higher specificity than .u-text-center {}, so the h2 ends up being aligned left despite us explicitly telling it to be text-align: center;. This is also a mutation: u-text-center no longer aligns something centrally.

This, in a nutshell, is why we should put !important on our utility styles. We want utilities to be immutable; there is no chance ever that we would apply a class of u-text-center and expect something not to end up with centred text.

Force utility classes to be immutable by applying !important to their declarations.

Of course, in a perfect world (whatever that is), we wouldn’t have a selector like .sub-content h2 {} even present in our CSS, but it’s inevitable that.

  • someone comes along and ends up writing a selector like that;
  • there was already a selector like that in some legacy part of the project.

Resilient and defensive systems are not designed for the perfect world, they’re designed for the real world, and in the real world, people write sloppy CSS. Using !important to force immutability will safeguard us from collisions and conflicts that others may introduce.

A Note on Utility Classes

I suppose it would be wise to have a brief aside about the general use of utility classes in here.

If we are not adhering to the Tachyons/Basscss/Atomic CSS style of functional CSS (which is a different topic entirely), we probably don’t want to be seeing too many utility classes in our HTML.

If, instead, we’re taking a more modular and componentised approach to our CSS (which we probably are), most of our classes will be very topical, e.g.:

.c-carousel {}

.o-media__body {}

.c-nav-primary {}

.c-btn--large {}

They will have a scope (a Block, in BEM), and will be well encapsulated. The beauty of classes like this is that we can easily spot relationships in our HTML (something that’s much harder (nigh on impossible) with functional CSS), e.g.:

<blockquote class="o-media  c-testimonial">
  <img class="o-media__img c-testimonial__photo" ... />
  <p class="o-media__body c-testimonial__text">...</p>
</blockquote>

Here we can clearly see a relationship between two distinct and separate strands of styling.

Let’s say, however, that one specific testimonial needs to have a much larger margin-bottom applied to it. It’s not a treatment that all testimonials need, and it only needs the larger margin-bottom when it’s in this exact part of the page. This is a very implementation-specific design change.

Here we’d reach for a utility class:

<blockquote class="o-media
                   c-testimonial
                   u-margin-bottom-large">

We use a utility here because the extra margin-bottom doesn’t have anything to do with the testimonial specifically; it’s a very context-sensitive and temporary treatment, so we didn’t ought to hard code that change into our testimonial’s CSS.

On the flip side. If we have a style of testimonial that has a larger font size, and any testimonial anywhere on the site could adopt this variation, we would not use a utility. This is a non-temporary treatment that belongs specifically to the testimonial, so we should codify and encapsulate it using a BEM Modifier:

<blockquote class="o-media
                   c-testimonial  c-testimonial--large">

So, as a general rule:

If it’s permanent styling, formalise it and code it right into your CSS. If it’s short-term or one-off styling, use a utility class.

Utility classes are probably my ‘least favourite’ type of class because they are really only one step away from inline styles. Use them sparingly, and to target very temporary or implementation-specific changes.