CSS Scoping

August 27, 2012
The biggest problem with CSS is absence of scoping. For simple HTML pages scoping has little sense, however modern web applications are far from simple pages. Modern web applications widely use ajax techniques refreshing portions of the page and often the entire page never fully reloads. Imaging you are developing a web application where you insert a block of HTML code into the page, then you apply some CSS rules to the inserted section. However, the browser will apply all applicable CSS files from all included CSS files and all <style> blocks present on the page to the newly inserted HTML section. And there is no way to prevent browser from doing so.

This is why all CSS files are so difficult to read and extend. It takes no small amount of time to track how the web of CSS rules is applied and where to tackle to fix it. If you do not agree that this is a problem, open jQuery UI CSS file and try to customize it beyond just changing colors. Even changing font family or font size will cause you lots of grief trying to make you design pixel perfect.

I believe that most of the problems can be avoided if you apply sound CSS scoping techniques early in the development of your application. I would recommend following 3 simple rules that will make your CSS files more readable and logical.

Rule #1: Use global CSS definitions sparingly

By global CSS definitions I mean CSS rules that apply to a large number of elements. In this sense all of the following css definitions are global: No doubt, you need global declarations, but try not to abuse them. Another mistake is to have global definitions in multiple files. As you know CSS is Cascading Style Sheets, which means it will combine multiple CSS rules to the same element if it applies in the order they are present in the document.

Rule #2: Scope all logical CSS sections

The best way to demonstrate CSS scoping is by a good example. Lets consider the following CSS
and HTML
which will produce the following table:
1.1 1.2 1.3
2.1 2.2 2.3
3.1 3.2 3.3
4.1 4.2 4.3
Note that:
  1. Applying one class I applied CSS rules to the entire structure
  2. If you have a table inside the table, CSS rules will not apply to the nested table
  3. If you had global declaration for the table, it would have messed up our structure (see Rule #1)
  4. The code is clean and easy to modify
For those of you who do not know what is > in CSS, I recommend to get a crush course of CSS selectors. It you are to use CSS scoping effectively, you need to be able to write effective selectors. You can start by reviewing this article.

Rule #3: Use CSS dynamically

It is common to use .innerHTML or $.html() to refresh sections of HTML of the page. However, I have read little about inserting CSS dynamically, and in my opinion it is a great practice. There are two way to do so:
  1. Insert <link> tag that point to a css file
  2. Insert <style> tag into the document
If you add <style> or <link> it will get applied to the page, if you remove it, its rules will be removed from the page as well. Here is an example:
File: file1.html
JavaScript
Here are the advantages of this approach:
  1. Your page will render faster because you have less nodes in the document tree
  2. Your pages will be easier to troubleshoot because you will know which CSS broke your pixel perfect page

Conclusion

By no means this is a perfect solution, but before the global community comes with a better way we are stuck with it. I have seen some articles (for example http://www.webmonkey.com/2012/04/html5-offers-scoped-css-for-precision-styling/) that talk about new attribute for CSS scoping, but current implementation lack flexibility and usefulness.

User Comments

Other Articles