Scoped style sheets

  ·   Scoped style sheets are a feature from HTML 5 (or the HTML Standard, if you prefer) that allows the effect of a style sheet to be limited to a subtree of the document. By placing a scoped attribute on a <style> element, the style sheet applies only to elements within the subtree rooted by the parent of the <style> element.

For example, consider this document:

<!DOCTYPE html>
<title>Scoped style example</title>
    p { font-style: italic; }
  <p>The first paragraph.</p>
    <style scoped>
      p { color: crimson; }
    The second paragraph.

It would be rendered as follows:

The first paragraph.

The second paragraph.

Rules in the style sheet only match an element if all of the elements matched by a selector are within the style scope. Thus, if the rule were instead body > p { color: crimson; }, it would not match that second paragraph.

The CSS Cascading and Inheritance Level 3 specification defines that when there are nested style scopes, rules on inner scopes override those from outer scopes, regardless of the specificity of the rules. Using !important reverses this, and allows outer scopes to win over inner scopes. Global style sheets, including <style> elements without a scoped="" attribute or those loaded using a <link> element, are treated as if they are scoped to the root element.

One use case for scoped style sheets is to isolate a set of style rules that apply to a single article or comment within a page to ensure that they cannot affect the style of other elements on the page. On a web site that aggregates articles from different authors, this could allow the designer of the overall site to know that the elements of the page outside the article itself will not be affected by the article’s styles.

Another is to be able to specify style for a given element’s pseudo-element, or only when it matches a pseudo-class, which is not possible just by using the style="" on the element or without giving the element an ID and defining the style in a global style sheet. For example if you have an element styled like this:

  <span style="text-decoration: underline;">looks like a link</span>

and you decide you want the underline to be applied only when the element is hovered, then it’s not possible to use the :hover pseudo-class within the style="" attribute. A scoped style sheet can be used:

    <style scoped>:hover { text-decoration: underline; }</style>
    looks like a link


Firefox 21, currently on the Nightly channel, supports scoped style sheets now that bug 508725 has landed. This feature is not prefixed or behind a pref. The scoped="" attribute can be placed on SVG <style> elements, too.

There are two aspects of the Firefox implementation that don’t match the specification yet:

  1. The @global at-rule, to allow all elements during selector matching except for the subject to be outside the style scope, is not implemented. The name “global” doesn’t quite convey the meaning it has, and given there are no other at-rules that can be used as a prefix to a list of selectors, some other syntax might be better. (Filed as bug 830058.)
  2. Other at-rules that have global effects, including @font-face and @keyframes, are not processed at all within scoped style sheets. The HTML specification states that these should have effects limited to the style scope. (Filed as bug 830056.)

[Edited 16 January 2013 – fixed the typo pointed out by Pablo]

Ten comments

You can subscribe to the comment feed to follow the responses to this entry.

  1. «Global style sheets, including elements without a style=”" attribute»
    I suppose you meant the *scoped* attribute.

  2. Indeed I did, thanks.

  3. Daniel Glazman
    16 January 2013, 8:38pm

    Hi Cameron, this is good news but raises an important question for an application like BlueGriffon or even the developer tools of Firefox: inIDOMUtils allows to “climb up” the cascade to find the CSS rules responsible for the current styles of a given element. Was that updated to return rules in such scoped stylesheets? I suppose non-scoped stylesheets inside an arbitrary elements are listable in |document.styleSheets| but is there anything planned for scoped ones?
    In summary: this is good but if our developer APIs and tools don’t share that love, it won’t be enough for embedders :-)

  4. Hi Daniel. I didn’t update anything in inIDOMUtils, but I am not sure if anything needs to be updated. Have you tested it? Scoped style sheets will appear in document.styleSheets just like non-scoped ones. If anything is missing please file a bug and CC me!

  5. Daniel Glazman
    16 January 2013, 9:10pm

    Oh cool. I’ll test that as soon as I arrive at the office. If the rules are
    visible from nsIDOMUtils then BlueGriffon will probably be able to edit scoped
    stylesheets out of the box! Thanks Cameron.

  6. That’s excellent! Another property that will be helpful to mix content from various sources is the all property [0]. I tried to search for a bug in Bugzilla but it’s not really the easiest keyword to search. :) Any plans to implement this?


  7. I haven’t seen a bug filed on implementing this so I don’t think there are concrete plans to do so yet. It is relatively new, though, and there have been some threads on the mailing list about whether the particular names or syntax are ideal, so it might be good to wait for those discussions to settle first.

  8. That’s fantastic. I’ve been waiting an eternity for this. The other part of this (IMO) is allowing similar scoping in the global style sheet. e.g. something like:

    article {
    header {
    h1 { font: …; }
    .byline { font: …; }

    Syntactic sugar, of course, but would make things so much easier to read.

  9. [...] [00:03:00] Scoped Stylesheets [...]

  10. [...] time-consuming tasks for web developers and designers – the parent selector in particular. Firefox has also started to support scoped stylesheets in it’s nightly builds. To the layperson, what that means is that sites will be able to give [...]

Leave a comment