Prerequisite knowledge

Prior experience with CSS is required to make the most of this article.

User level


In Douglas Crockford's "JavaScript: The Good Parts", Crockford names global variables as the worst part of JavaScript. He writes, "Global variables can be a convenience in very small programs, but they quickly become unwieldy as programs get larger. Because a global variable can be changed by any part of the program at any time, they can significantly complicate the behavior of the program. Use of global variables degrades the reliability of the programs that use them."
Crockford continues, "Global variables make it harder to run independent subprograms in the same program. If the subprograms happen to have global variables that share the same names, then they will interfere with each other and likely fail, usually in difficult to diagnose ways."
Whether or not you agree with Crockford about globals, JavaScript, at the very least, has well documented and widely accepted ways to deal with them. Module patterns, object namespacing, and function closures are a few examples.
CSS, on the other hand, is not so lucky.
In CSS, everything is global. When the browser begins to style an element in the DOM, it will traverse every single rule in every single stylesheet to find matches. All CSS rules can potentially apply to all DOM elements, meaning it's up to you to avoid unintended matches.
This can be extremely difficult when multiple people are working on the same project; eventually two people will inadvertently pick the same class name or style the same tag in conflicting ways. Even a single developer can easily forget rules written just a few months prior.
Not only are CSS rules global, they also inherit from parent elements down to their children. This inheritance cannot be stopped or turned off. Once an element is added to the DOM, it will inherit values from every one of its ancestors. Your only defense is to explicitly unset the properties you don't want and hope you haven't missed any.
For framework and library authors the situation is even worse. You have absolutely no idea what kind of crazy rules the users of your library might have written, and there's no foolproof way to account for it. If a third-party site that uses your framework contains a rule like #content div { width: 25%!important; }, things are probably going to break.
So what can you do?
In this article I'll talk about some strategies for dealing with the global nature of CSS. I talk about finding the balance between paranoid over-protection and just asking for trouble. I'll also talk about some exciting things already making their way into the CSS spec that will provide real encapsulation in the future.
When writing CSS you're usually either defining styles for your own project or writing a library for use by other people. The strategies for these two situations are actually quite different. In the following section I'll address strategies for you own projects, and in the next section I'll discuss writing CSS libraries and frameworks.

Strategies for your own projects

With your own projects your primary concern should be future maintainability. You want your code to be scalable and react well to change. This is true even for small sites or applications on which you're the sole developer. You never know how a project will evolve, so you should code in a way that can withstand such unpredictability.
Use classes wherever possible
Every time you define a rule on an unqualified HTML tag (a type selector) you pollute the entire tree from that element down through all of its children. Consider the following rule:
#sidebar a { background: lightyellow; color: blue, text-decoration: underline; }
Rules like this may seem simple and harmless, but if you add a third-party calendar widget to your sidebar, the above rule will apply to the calendar’s links as well, and that is probably not what you want. Even if the author of the calendar widget explicitly set values for color, background, and text-decoration, your rule has a high specificity and will probably win out.
This situation could have been completely avoided had you used a class selector instead of a type selector. Sure it’s more work to put a class on each link in the sidebar, but with the extra work comes added peace of mind knowing that your styles are more predictable and stable when changes are made in the future.
There are a limited number of element types in HTML but there are an unlimited number of class names. The chances of someone else picking your exact class name are fairly small, but the chances of them using some of the same element types are practically guaranteed.
Prefer namespacing over descendent combinators
It’s common for developers to scope their subobject classes within a parent selector, secure in the knowledge that the scoped styles won’t leak out. For example:
.widget { } .widget .title { }
And they're correct. The styles defined on .widget .title will only apply when .title is used within .widget.  That, however, is only half of the concern. If the class selector .title is defined elsewhere in the stylesheet, those styles will apply to all elements with the class title including elements within .widget.
Encapsulation is a two part process. You have to worry about styles leaking out, but you also have to worry about outside styles leaking in.
Unwanted style leakage is especially problematic with names like "title". Developers frequently pick generic names like this, and the likelihood of two people unknowingly choosing the same one is fairly high.
This problem can be solved by namespacing your classes. Instead of relying on descendent combinators, simply class the subelements and use the component's base name as a prefix:
.widget { } .widget-title { }
Namespacing has many advantages in addition to providing better encapsulation. It lowers the specificity of each rule, it expresses more meaning in the markup, and it provides a common hook should you need to test your implementation or globally change the selector name in the future.

Strategies for writing library code

Unfortunately, many CSS frameworks today are hostile toward their host environment. They litter the global scope with rules defined on tags and extremely common class names, practically guaranteeing conflicts with your existing codebase.
They also make the usually incorrect assumption that users of their framework have the luxury of completely redoing their site's CSS, and then using that framework (and only that framework) until the next redesign. But this simply does not reflect the situation most developers are in. Most of the time you already have a site, and it's a struggle to incorporate a new framework into it.
Developers also frequently want just bits and pieces of multiple frameworks, but few frameworks are designed to "play nice" with others.
In an ideal world, framework code would be completely modular and encapsulated. You could easily pick and choose the parts of the framework you wanted without fear of it conflicting with your existing site or another framework. Unfortunately this goal just isn't possible given the current state of CSS, but that doesn't give framework developers permission to do the opposite.
Framework authors should strive to make their code as compatible as possible. That work shouldn't fall on the shoulders of the framework user. Fortunately there are a number of ways framework authors can make their libraries more global-friendly.
If you're creating a new CSS framework, contributing to an open source project, or writing any CSS that gets used on sites outside of your control, consider the suggestions and practices that follow.
Don't depend on your global resets
Arguably the main cause of CSS framework incompatibility is overreliance on aggressive global resets. The most prominent example of this is in ZURB's Foundation, which sets the box-sizing property of every element to border-box:
*, *:before, *:after { box-sizing: border-box; }
The box-sizing property enables you to alter the default box-model used by the browser. The traditional box model calculates the width and height of an element by the size of its content-box. In contrast, the border-box model includes the size of the padding and borders in those measurements. That means you can add a style of width: 50%; to a column <div> and safely add borders and padding without worrying about the column becoming wider than you want.
Many developers prefer the border-box model over the traditional box model and consider it a more intuitive approach. I personally use it in all my new projects. However, for a popular framework to require it globally on every element will practically guarantee its incompatibility with the vast majority of existing websites. Most sites still use the content-box model and have widths and heights defined in tens or hundreds of places throughout. Forcing a rule like this on an existing codebase is unreasonable.
Fortunately, there's an easy compromise.
With a CSS preprocessor you can have it both ways. You can default to a global box model reset while simultaneously providing a fallback for sites that can't make the switch. This enables you to promote some exciting new patterns without alienating millions of websites. Here's an example written in Sass.
/* The placeholder rule */ %border-box-model { @include box-sizing(border-box); } /* The reset conditional */ if $global-border-box-model == true { *, *:before, *:after { box-sizing: border-box; } } /* Individual component conditionals */ .tooltip { if $global-border-box-model == false { %extend %border-box-model; } }
The above technique enables sites to opt into a global border-box model reset, or gracefully fall back to defining it on individual components. Because this all happens in a preprocessor, it doesn't add any bloat to the compiled CSS.
In general, CSS preprocessors are great tools for letting end users customize a framework. Preprocessor variables are commonly used for customizing sizes and colors, but they can be great for customizing your site architecture as well.
Another example of an overdependence on global resets is the unsetting of user-agent styles. Many frameworks will unset list, link, or heading styles and then define components assuming those resets will still be in place, but this assumption is often false. For example, if your framework includes a tabbed navigation component that uses a <ul> element, it's probably a good idea to reset the list-style, padding , and margin properties, even if you've already reset them in a base stylesheet. Not resetting those properties assumes that your framework's users are always including the base styles, and not overriding any of them. Don't assume that.
The same is also true of link styles. If the tab elements in the previous example are coded with <a> tags, it's probably wise to explicitly set the color and text-decoration properties on both the normal and :hover states.
The line between paranoid overprotection and naive assumptions isn't easy to find, but it is important to be sensible. Aggressive attempts to reset every single property will lead to unnecessary code bloat, but relying too heavily on your base resets may lead to unexpected bugs. I leave it up to you to find your own balance.
Use a library namespace on all classes
Twitter Bootstrap, Zurb Foundation, and similar libraries define style rules on common class names, including .tabs, .alert, and .row. If you're working on an existing application, the chances are very high that you've already picked at least one of these names. But since the framework isn't going to change, you have to. This is a terrible inconvenience put on framework users.
jQuery UI takes a much better approach. It namespaces all class names with the prefix ui-, significantly reducing the possibility of conflict.
The namespaced approach may be more verbose, but it's much more considerate of library users' time.
Use a preprocessor for dynamic selector namespacing
Namespacing is a great start, but it is not guaranteed to prevent all naming conflicts, especially with shorter, less unique namespaces like ui-. However, if the library uses a preprocessor, it can take the namespacing technique one step further.
When all the styles of a particular component are prefixed with the component's name (like I recommended earlier), it's trivial to set that name with a variable. Imagine a CSS framework named "Flux" that defines a messagebox component. Here's how the selectors could be named dynamically:
$flux-messagebox-name: "messagebox" !default; .#{$flux-messagebox-name} { } .#{$flux-messagebox-name}-heading { } .#{$flux-messagebox-name}-body { }
Users of the Flux framework can now set their own namespace by simply overriding the variable:
$flux-messagebox-name: "some-other-name";
The beauty of this technique is that it empowers users to choose the names they want. If they like clean and simple names like those used in Bootstrap and Foundation, they can have them. If they prefer a consistent prefix like jQuery UI uses, they can have that. And if they need to completely change the name of a component to resolve conflicts, they can do that too. It’s entirely up to the users.
Dynamic namespacing supports short and simple names for the majority of use cases and only requires extra effort for those who actually need it. It doesn't impose a verbose prefix on anyone and keeps the barrier to entry low. Those who want to make changes can dive in and edit the Sass file, and those who just want to use it out of the box can simply grab the compiled CSS. Everybody wins.
For more detail on this technique, see Dynamic Selectors, an article that I recently wrote and posted on my personal website.

The future

Dealing with globals in CSS is a pain; luckily there are several exciting developments in the works to make real CSS encapsulation possible. Currently, the only way to achieve real encapsulation is to use an <iframe>, but for most scenarios iframe elements create more problems than they solve.
Three new HTML and CSS features that will make dealing with globals easier are scoped styles, the all property, and Web Components.
Scoped styles
HTML5 introduced the scoped attribute of the <style> tag, which allows the tag to be used within the body of an HTML document (previously <style> declarations could only be in <head>).
Scoped style declarations apply their contained CSS rules only to the document tree in which they're defined. In other words, if a <style> tag is inserted directly within <div id="sidebar">, then its styles will only apply to child elements of that sidebar. Scoped styles offer a good way to ensure that a set of rules do not leak out and conflict with the rest of the document. However, as with descendent combinators, they do not prevent outside styles from leaking in.
Scope styles will be particularly useful when injecting code into an existing document. They'll enable you to transmit some CSS along with your markup in a way that is valid (remember non-scoped style declarations are only allowed in <head>) and in a way that won't conflict with the existing page.
The downside of scoped styles is that browsers that don't support them treat them like regular style declarations. That means that not only will you not have two-way encapsulation, you won't even have one-way encapsulation. Because of this, my recommendation is to stay away from scoped style declarations until they're fully supported in all browsers. If you do use them, treat them as regular style declarations and anticipate rules leaking out.
For more information on scoped styles, see The Scoped Attribute on HTML5 Doctor.
The All property
CSS recently introduced the all property, which can be thought of as a shorthand way to set or reset everything.
The all property accepts CSS-wide keywords such as initial and inherit, making it easy to reset all previously defined styles for a given component without having to list each of them individually. Here's an example:
.widget { all: initial; background-color: gray; border: 1px solid black; font-family: sans-serif; text-align: center; }
Setting the all property helps prevent unwanted styles from being inherited. For example, imagine you created a widget that someone included on their page; unfortunately, that page contained all sorts of weird base styles like letter-spacing: 1em; and text-indent: -2em;. It would be impossible for you to anticipate this, and absurd for you to explicitly reset these properties (since they're so rarely used), but in this particular situation not resetting them breaks your widget.
With the all property you don't have to worry. You can easily reset everything and start fresh.
It's important to be aware that all is just like any other CSS property and its applicability depends on the cascade just like all other properties. Consider the following:
#sidebar p { text-decoration: line-through; } .widget { all: initial; }
If you use the above widget in your sidebar, its all declaration won't override the previous rule's text-decoration value because #sidebar p has a higher specificity than .widget.
If you're tempted to try declaring all: initial!important; to ensure your reset works, please reconsider. Doing so is extremely destructive. Keep in mind that the all property is just shorthand for listing every single CSS property individually. To illustrate the danger, the following example shows the CSS equivalent of declaring .widget { all: initial!important; }:
.widget { background-attachment: scroll!important; background-color: transparent!important; background-image: none!important; background-position: 0% 0%!important; background-repeat: repeat!important; border-collapse: separate!important; border-spacing: 0!important; border-style: none!important; border-width: medium!important; bottom: auto!important; caption-size: top!important; clear: none!important; clip: auto!important; /* and the list goes on... */ }
As you can see, the !important flag gets applied to each CSS property, which is almost certainly not what you want. Keep in mind that !important carries an even higher specificity than inline styles, making it nearly impossible to override. In fact, all: inherit!important; will even override subsequent declarations within the same rule unless they also use !important. CSS importance is a powerful tool that should only be used when absolutely necessary, and applying it to every single property is almost never necessary.
The all property is a great addition to CSS, and it can vastly reduce redundancy with style resets. However, since it is still subject to normal CSS cascading, it can't achieve true style encapsulation.
Web Components
You can think of Web Components as similar to native browser controls like <input type="date"> or the <audio> element. Both of these are just single elements in the HTML markup, but there's obviously more than that going on behind the scenes. For example, <input type="date"> elements display a calendar that is visually styled and responds to click events, and <audio> elements have controls for playback. How is this possible with just one HTML element?
Actually, within those single HTML elements lives a hidden DOM (known as a shadow DOM) that is self-contained and packages its own logic and styling. Web Components have a shadow DOM as well, and you can customize it.
The shadow DOM enables you to include HTML, CSS, and JavaScript on a page in a way that can be completely encapsulated from the master document. According to the W3C specification, "The component model for the Web (also known as Web Components) ... let[s] web application authors define widgets with a level of visual richness not possible with CSS alone, and ease of composition and reuse not possible with script libraries today."
To include a Web Component on your page, you simply reference a file where the component is defined:
<link rel="components" href="alert-component.html">
The contents of that component document will include a custom-named element and all the logic, styling, and markup that goes along with it; for example:
<html> <head> <style> .alert { background: yellow; border: 1px solid red; color: red; } h1 { font-size: 1.25em; margin: 0; } </style> </head> <body> <element name="alert"> <template> <div class="alert"> <h1>Watch Out!</h1> <content></content> </div> </template> </element> </body> </html>
The last step is to instantiate your new custom element in an existing element within the master document. You do this with the is attribute.
<div is=”alert”>This is the contents of the alert</div>
When you declare that the above <div> is an instance of your custom alert element, the browser automatically renders the markup of the custom alert element's <template> as the shadow DOM of the master document's <div>.
You might be wondering what happens to the text inside the <div> once the browser inserts the shadow DOM inside of it. This is where the <content> tag in the component document comes into play. The <content> tag is just a placeholder for whatever content the element in the master document provides to it. In this case, the text "This is the contents of the alert" would get rendered in the new component inside the content tag. Component documents can define more than one <content> tag and use the selected attribute to determine which of the master document's elements get rendered where, but that is beyond the scope of this article.
This introduction is just the tip of the iceberg of what is possible with Web Components. The main point to take away is that with Web Components you can completely separate the presentation and logic of a component from its content.
You might have noticed I broke two of my own rules when declaring the CSS of the alert component above. First, I used a generic class name (.alert), and second, I defined styles for an HTML tag (h1). However, with Web Components, this doesn't matter. I don't have to worry about whether someone already defined a conflicting .alert or h1 rule because the styles of the component exist in a completely separate scope from those of the master document. The styles of the master document do not touch the component document, and the styles of the component document do not touch the master document—real encapsulation at last.
The Web Component specification is still evolving and many of the details will likely change. Here are a few excellent resources if you want to learn more and be on the cutting edge:

Where to go from here

Currently the state of globals in CSS is not great. The temptation for Web developers to write their CSS selectors as minimalistically as possible is very high, but it comes at a much higher cost as your sites increase in size and complexity.
With a little discipline and the future in mind, writing CSS to avoid conflicts isn’t so hard. In fact, writing CSS in this way usually leads to a more manageable architecture.
As CSS grows and matures as a language, many of these concerns will no longer apply, but they probably won’t disappear entirely. A firm understanding of how and why conflicts arise is essential to knowing when to code defensively and when it doesn’t matter.
When in doubt, code defensively.