Generated Content by David Storey

HTML5 scoped attribute

The HTML5 spec adds the scoped attribute to style elements. What does this do, and how can it be useful?

The scoped attribute is used to limit the scope of the CSS rules inside the style element to that element’s parent and all the children of the parent. All other elements outside of the scope do not get styled, even if the selectors match. It is a boolean attribute, so you can use scoped for HTML and scoped="scoped" for XML/XHMTL. The use of scoped style sheets is best illustrated with an example:


<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Scoped example</title>
        <style>
            p { color: black; }
        </style>
    </head>
    <body>
        <p>The text in this paragraph will be black</p>
        <div>
            <style scoped>
                p { color: green; }
            </style>
            <p>The text in this paragraph will be green</p>
            <p>And in this paragraph too</p>
        </div>
        <p>This paragraph is out of scope so will be black</p>
    </body>
</html>

In compliant browsers, the two paragraphs inside the div element will receive a text colour of green, while all other paragraphs will be black. Any styles in the scoped style element only apply to the parent element (the div) and its children (the two p elements).

There is a bit more to it though. Any @page rules in scoped style sheets are dropped. Also if a font is linked via @font-face then that font will not be used for elements out of scope, even if they have a font-family applied to them which matches the name given in the @font-face rule in the scoped style sheet.

Why use scoped style sheets?

The first thought might be why should I use this? When you put a style element within your HTML then it isn’t too different to using inline styles (minus the specificity concerns). I strongly believe that we should strive for separation of concerns, and John Allsopp makes some good augments about this on his blog.

However, there are some valid use cases for it. One use case that comes to mind is when using demos in your page. Instead of giving everything ids or classes, you can use a scoped style sheet that you can guarantee will only apply to the demo. That is a bit esoteric compared to the average needs of web developers, but it hints at why it is really useful. Web components.

The Web was primarily used for documents and our languages reflected this. We are increasingly seeing the Web also be used for applications as well. Web apps have their own requirements. We often need rich components and controls, such as custom sliders, buttons, carrousels, accordions, etc. A lot of frameworks have sprung up to fill this need, and the component model along with the shadow DOM will hopefully be the standardised solution to this.

Components built with web technology usually have their own defined style and behaviour. We want the styling of these controls to be self contained and not leak out to the rest of the document. Scoped style sheets are one solution to this. It avoids having to hack in name spaces, such as trying to use a unique id and using this with each style rule (which can also lead to specificity hell), or inline style (which is even worse). With scoped style sheets we can be sure that the styles will only apply to the HTML of the component, and can style be easily overridden by other rules if we need to customise the component.

Where can I use them?

If you think Great! which browsers can I use this in? you’ll be frustrated right now, as no browser or user agent supports the scope attribute right now. There is work in progress in WebKit however, so it may land soon.

Edit: This is now supported in nightly builds of WebKit.

Wouldn’t it be nice…

The main criticism I’ve seen about scoped style sheets is the mixing of concerns issues, and I more or less agree. What I think could be a solution to this (but someone smarter than me probably knows why it can’t be done) is to allow link and maybe style elements in the head to have an option for attribute, just as labels do. Then you could do something like <link rel="stylesheet" href="style.css" scoped for="scoped-element" /> which is scoped to the element (and its children) with the id specified. This would allow you to keep the scoped style sheet in the head of the document where it belongs.

  1. jalbertbowdenii reblogged this from dstorey
  2. dstorey posted this