@document is a candidate for CSS level 4 inclusion and currently implemented in Firefox. It will allow for nested CSS to be applied on a per-page or per-domain basis.

For instance, the following will apply CSS to the header area of a website’s index page.

@-moz-document url("http://somewebsite.com/index.html") {
  .header {
    /* ... */
  }
}

If we instead use url-prefix(), then styling can be added to all the pages within a subdirectory of a website.

@-moz-document url-prefix("http://somewebsite.com/blog/") {
  /*
    Style the header for all pages contained within /blog/
  */

  .header {
    /* ... */
  }
}

While the following would apply rules to an entire website.

@-moz-document domain("website.com") {
  p {
    /* ... */
  }
}

Do we want to use @document?

At first glance, it seems like this could be solved with just a few helper classes? For instance:

.generic-class {
  /* ... */
}

/* change generic class on about.html */
.generic-class--about {
  /* ... */
}

About page HTML:

<div class="generic-class generic-class--about">
  ...
<div>

If we didn’t want to bloat our CSS with a bunch of single page, single use helper classes, we could go down the route of inlining CSS into the <style>tag in the head of individual pages.

<head>
  <!--
    link to our main style sheet which contains
    the base styling for <b>.generic-class</b>
  -->
  <link href="/assets/css/stylesheet.css" rel="stylesheet" />

  <!--
    Insert page specific styling for
    .generic-class within the <style>
  -->
  <style>
    .generic-class {
      /* ... */
    }
  </style>
</head>

OK, maybe we don’t “need” @document for stuff like that. So where might @document definitely be useful?

Example 1: Partnering with OOCSS

For this example, let’s say we are working on a blog and we want to change the header image on each page / blog post.

Depending on the kind of blog you are running, and how easy it is to customize the mark-up on a per page basis, you could potentially be out of luck.

However, by using @document, we can use the url of the current page as our helper class.

/*
  We have our base header styling set up in a generic class
*/
.header-base {
  background-position: center center;
  background-repeat: no-repeat;
  /* additional base styling */
}

/*
  Then we add the extended styling, in this case our images,
  on a per page basis, reusing the .header-base class.
 */
@-moz-document url("http://yourwebsite.com/page-1.html") {
  .header-base {
    background-image: url(image-1.jpg);
  }
}

@-moz-document url("http://yourwebsite.com/page-2.html") {
  .header-base {
    background-image: url(image-2.jpg);
  }
}

Example 2: Working with Third-Party Content

If you’ve ever had to work with a third-pary customer service portal, where adding your own classes to the mark-up may not even be a possibility, then there is a lot of potential for @document to help with more customization in re-skinning.

Combining @document with other selectors, like targeting element attributes and attribute values, along with classes, opens up a lot of doors in styling opportunities.

For instance, let’s focus in on an important component of customer service pages. Search.

A search widget is likely written once, and is either baked into the mark-up of the CS portal, or it’s a widget that can be added to content areas. However, it’s highly unlikely that you can edit the code of the search widget, and it’s even more unlikely that the widget exports unique classes on a per-page / per-instance basis.

Using @document we could target the URL of the landing page of our CS portal, and style the search widget to be prominent. We could then style the search widget in a more modest way for the remainder of the pages within the CS portal, as once a customer has found what they are looking for, the content should be more prominent than searching.

/*
  First style the common look-and-feel for the search widget
*/
.search-widget {
  /* ... */
}

/*
  Then use @document to restyle the search widget
  for our landing page
*/
@-moz-document url("http://cs-website.com/index.php") {
  .search-widget {
    /* ... */
  }
}

Wrapping up

The thing I worry about with @document is the potential for verbose CSS when a simple helper class added to the <body> element would suffice.

Being a candidate for CSS4, we’re still a ways away from @document even being close to its final form. The usage of it may change, or it could be dropped all together.

However, based on my couple of examples, as well as stuff I’m sure I’m not even thinking about yet, this could be a very handy CSS rule when used in the correct context.