CSS is !important
Cascading Style Sheets are designed to, well, cascade. !important declarations overrides the cascading nature of CSS and are often considered to be a hack. You should avoid using them for the most part. But like most things proposed to the CSS spec, !important has several practical applications. But what are they?
First we need to travel back in time. Long before media queries and responsive design. The !important keyword was first introduced in CSS1 as a way to increase the specificity of CSS declarations. But it did something rather strange.
When !important was first introduced in CSS1, an author rule with an !important declaration held more weight than a user rule with an !important declaration; to improve accessibility, this was reversed in CSS2
— The Important CSS Declaration How and When to use it
Author stylesheets are included by web developers in a web page to style the page. User styles are defined by the user often in their browser preferences. It makes sense that a user style should always override author styles, but that wasn’t always the case.
However, for balance, an “!important” declaration (the delimiter token “!” and keyword “important” follow the declaration) takes precedence over a normal declaration. Both author and user style sheets may contain “!important” declarations, and user “!important” rules override author “!important” rules. This CSS feature improves accessibility of documents by giving users with special requirements (large fonts, color combinations, etc.) control over presentation.
— W3C Recommendations — !important rules
So there you have it. Straight from the CSS2 Specification, the !important feature improves accessibility of documents. It isn’t just a hack.
Accessibility
The CSS authors made an important decision to make !important declarations in user style sheets the most specific of them all. A user should have the final say in the styles they are presented with. This isn’t the only advantage to the changes made in the CSS2 spec however. Inadvertently, this ruling also allows web developers to use !important declarations freely without concern of overriding !important user styles.
We shouldn’t expect all users in need of stylistic considerations to be savvy enough to author their own user styles. Using JavaScript localStorage and a simple form we can create preference widgets that allow users to specify their preferences. Our author stylesheets then respond to user preferences accordingly. Using JavaScript to promote accessibility along with responsive design, sounds like a plan. Let’s look at a few examples.
Visually Hidden
Sometimes you want to hide an element visually but not semantically. For example, maybe a label doesn’t need to be visually but does need to be accessible to screen readers. The A11Y Project has a well tested technique for this using a .visually-hidden class. Notice the use of !important.
Font Size
Whether visually impaired or just sitting far away from your screen, we can all appreciate larger font size from time to time. We’ll create a medium font size that is 20% larger than normal and a large font size that is another 20% larger than medium.
Note: Depending on your cascade and styles you may not need to use important declarations for setting font-size on the body element. Only use !important in your declarations if necessary or if stylesheets outside of your control may be included in the page.
Using classes on our body element is fine and well, but once we start using JavaScript to asynchronously reflect user preferences they can be a bit cumbersome. For example, we don’t want to have to remove the medium class each time we add the large class and vice–versa. So let’s use a data attribute instead.
Now with one simple setAttribute we can update our page to reflect the user’s preferences.
Very nice, but we’re not there yet. A splash of HTML and a sprinkle of JavaScript and we’ll have a user friendly component that allows them to choose their !important font-size.
And now for the JavaScript.
Here is our Font Size Preference Widget as a CodePen. Try it out.
Okay, I know what you are thinking. This is a CSS post about !important declarations. Now that we’ve architected a preference widget, let’s get back to it.
High Contrast Mode
Increasing font size is a great way to improve legibility but we need to consider contrast as well. Even large black text on a white background may be illegible to users with particular eye conditions. By supporting a high contrast mode that forces backgrounds to black and font color to white we can accommodate users with particular eye conditions and night owls alike. Everybody wins.
To enable our high contrast mode we’ll add a .high-contrast class to our HTML element that forces all elements on the page to black background white white border and font colors.
Sure we could use more specific selectors to override each area of our stylesheet that sets background, color, and border-color properties. But that would be difficult to maintain and increase our CSS weight. With just three !important declarations we can specify how all elements should be styled when in high contrast mode without overriding any !important declarations in user sheets.
Of course our JavaScript to toggle the high contrast mode is as follows.
You can use the patterns outlined above to create a similar widget that allows users to set their contrast preferences. Visit markup.tips for an example. In supported browsers you can even allow the user to choose automatic switching between high contrast and normal contrast based on the luminosity of their current environment. At the time of this writing, Firefox is the only browser to support the HTML5 Luminosity API needed for this feature.
If you are working with high contrast modes don’t forget to checkout the -ms-high-contrast feature and stay tuned as this feature hopefully works its way into CSS Media Queries Level 4.
Reducing Motion
CSS Transitions and Keyframe Animations are a great way to add character to an experience. While many users find animations and transitions entertaining they can be intrusive and even detrimental to others. Whether this is because they experience motion sickness or just aren’t in the mood, it is important we give users a way to opt out of animations and transitions.
Create a preference widget that allows users to opt out of unnecessary motion. When they choose to reduce motion, prevent CSS Transitions and Animations will the following styles.
Font Family
Typography is a critical design element. Graphic Designers put great effort into choosing the web fonts they deliver. But design isn’t just about how something looks. Perhaps more importantly design is about how something functions in society. Even the most aesthetic typefaces may not be legible to all users. Particular fonts have been designed to accommodate these users. For example,OpenDyslexic is a font created to increase readability for users with dyslexia. Unlike print, the web offers the ability to asynchronously change the fonts on a page. So let’s leverage the nature of our medium by allowing users to do so. Depending on the nature of your cascade, you may need to use !important declarations to ensure the font the user prefers is used for all the appropriate elements on the page.
Create a widget that allows users to set their font preferences and make OpenDyslexic an option. Visit markup.tips for an example of allowing users to choose their font. Not only does this technique allow for a more inclusive design but it also can be used to increase site performance by initially serving a web safe font and allowing users to opt into heavier web fonts.
Print Styles
In 2010 Louis Lazaris wrote an excellent article published by Smashing Magazine titled “!important CSS Declarations: How and When to Use Them”. In it he reminds us that while it may not always be necessary, !important declarations can be used within print media queries to override specific styles without having to repeat selector specificity.
To be considerate of the environment and your user’s paper supply we’ll use some !important declarations to force printed pages to black text on a white background. We’ll also remove advertisements and navigational elements such as the site nav and search components.
Most users would probably prefer to choose between color or grayscale printing in their print dialog box but you can force grayscale printing with a CSS filter.
Perhaps you use the grayscale filter together with a preference widget that allow users to set their print preferences so they are reflected on their next visit.
To Hack Inline Style
Using the style HTML attribute will override CSS declarations regardless of selector specificity. For this reason inline style should be avoided. If you find yourself working on a project where inline styling is present and cannot be feasibly removed you can hack them away with !important declarations. An !important declaration in a stylesheet will override inline style. It might not be the most ideal fix, but it works. For example, an absurd amount of !important declarations were needed to make the MODX 2.5 Manager Interface more mobile friendly.
Never
Louis put it best in his post.
!important declarations should not be used unless they are absolutely necessary after all other avenues have been exhausted. If you use !important out of laziness, to avoid proper debugging, or to rush a project to completion, then you’re abusing it, and you (or those that inherit your projects) will suffer the consequences.
— !important CSS Declarations: How and When to Use Them
So remember, only use !important declarations if they are absolutely necessary or are improving accessibility. It might feel hacky but if a few !important declarations allow you to feasibly support a high contrast mode, it’s worth it.
In this post we’ve covered some practical uses of !important declarations but what is most important is you architect your styles to meet the best needs of your users and your team. So what do you think? What is most important to you and yours?