Grow your CSS skills. Land your dream job.

Saving the Day with Scoped CSS

Published by Guest Author

Today's post is by Arley McBlain (@ArleyM), a front end developer in Burlington Ontario at Thrillworks.

Over the last couple years HTML5 and CSS3 have rocked our worlds and the way we approach common website issues. Every few days it seems there is some new fangled snippet or approach that is a game changer. Today might just be another one of those days (kind of).

One little known feature of HTML5 is Scoped CSS. It's an attribute for style blocks that may change the way we tackle certain styling challenges in the future.

The implementation for scoping is simple. Let's look at some code on an otherwise unstyled page where all text is the default black:

<div>
  <style scoped>
    h1 { color: FireBrick;   }
    p  { color: SaddleBrown; }
  </style>
  <h1>This is an H1 in a scoped div. Regardless of global styles the text should be "FireBrick".</h1>
  <p>This is a paragraph in a scoped div. The text should be "SaddleBrown".</p>
</div>

<p>This is another paragraph, that will unaffected by the scoped style and remain black.</p>

The style block with the scoped attribute will overwrite the global styles generally found in the head (whether in a style block or linked stylesheet), but only on the sibling/descendent elements inside the same parent. In this example, everything inside the wrapping div is going to get some new heading and paragraph coloring. As w3.org puts it "If the scoped attribute is present, then the user agent must apply the specified style information only to the style element's parent element (if any), and that element's child nodes."

This is amazing! While all other text on the page may be black, within this div we can style freely without worrying about changing the styles of similar elements anywhere else on our site. This can be a very powerful tool.

Why is this cool?

"But Arley," you say, using a conjunction to begin a sentence, "Why not just use a class or ID on that div and style like #foo h1 and #foo p? Isn't this just organized inline styles?" There are a number of occasions I can think of when scoped CSS is a decent option under certain circumstances:

  • It may be desirable to keep the CSS of a particular interactive element together with the HTML. If the element in question is unique on the site (like a complex slider for example), there is no advantage to caching it with global styles.
  • Keeping the CSS with the HTML for organization may have value however.
  • When working with a team it can be a great way to allow for simultaneous development of various areas of the site without worrying about the state of the global CSS - I can see this as a short term solution.
  • If your article is getting aggregated by another site it's possible to customize styles on another website that would otherwise be beyond the reach of your global stylesheet.
  • If you enable tags in the comment section of your site you can give your readers the ability to style their... nevermind this is probably a terrible idea.
  • For use in widgets on third-party sites where the CSS is unknown and the in-widget styles shouldn't affect anywhere else. Although being able to reset the styles within the widget is the other half of that battle.
  • Finally (and most exciting to me), Scoped CSS is ideal for working within Content Management Systems where you have much less flexibility for adding unique markup to common templated areas, or no access to the existing stylesheets.

I would like to talk about the CMS advantages in more detail.

Working with a CMS

When we build a site in a CMS we are building constraints to ensure reusability of elements and templates, as well as maintaining consistency across the site. CMS are the perfect tool to let someone way less nerdy than you create and manage content without fear of breaking any site components. One limitation of a CMS can be the inability to do one-off tweaks for unique areas.

I had this problem working in an enterprise level CMS. Based on original comps and scope of the site we built the CMS to have a consistent uniform look and feel. A need for more flexibility rose a few months after launch: the addition of a second more verbose language, and special campaigns were introducing new challenges for styling.

My first challenge was to make a larger block of text (fun fact: the rule of thumb for designers when designing for bilingual in Canada is to allow for an extra 50% space when the design will need to be in French!). I looked at my pages, and I looked at my stylesheets: even any tiny change I made would mean hours of testing and QA across the entire site to ensure that no other areas were broken as a result. The ramifications were astronomical! Having no time for this I invented the poor-man's Scoped CSS, or "code block" as it became known. Code Block was technically just wrapping divs with IDs around content, and then having an adjacent style block to make the necessary changes (while this sounds simple, it was a bit outside-the-box for this CMS work). Since this CSS would only apply to this page it made no sense to have these styles bloating up the global styles. It was perfect. The style block would not affect any other area of the site. Bilingual and campaign content became easy to develop and test.

Thankfully Scoped CSS will be even cleaner and easier to implement than my McGyvered solution. There will be no need for special IDs, and in fact the ability to have really simple selectors like "p" will keep your CSS looking very clean.

Getting Practical

Have you ever wanted to make one specific post in your stream stand out in some way? Even if your CMS doesn't allow for coding in the editor, you may still have options thanks to Scoped CSS.

WordPress is an example of a CMS that will limit what code you can enter into the content area. Out of the box WordPress strips a lot of markup out of the wysiwyg editor, and this is actually a very very good thing, as it will clean up any stray code a n00b user may accidentally introduce. Giving users access to enter code into a CMS is to give them access to destroy the site! One too many closing div tags will mean a completely borked layout!

With a little work up front you can create a "Code Block" custom field that will allow you to inject scoped CSS directly into that post. If you really want to get fancy you could employ functionality from a plugin like Custom Field Template to make it easy for even the least savvy user to take advantage of this by making style choices with a simple form!

In the WordPress demo below I have created a Twenty Eleven Child Theme (meaning I'm completely relying on the default WordPress template, except for the three pages I've made small adjustments too). The changes I've made are few and simple (I should probably also mention that at the time of writing there is one other tiny problem to consider, but I'll save that until later). To get Scoped CSS working I simply add a little bit of logic to content.php and content-single.php to look for the custom field "scopedcss" and then to pop that into a style block. I simply put this code within the <article> block of the relevant content loops:

<?php 
  $scopedcss = get_post_meta($post->ID, 'scopedcss', false); 

  foreach($scopedcss as $css) {
    echo '<style scoped>'.$css.'</style>';
  } 
?>

Then in my WordPress post I simply added the custom field "scopedcss" and wrote whatever styles I wanted for this post.


Easy cheezy. If you don't see Custom Fields on your post editor screen, click the Screen Options tab at the top of the screen and make sure the checkbox for them is checked.

Note: if you are interested in this art direction on a per-post basis idea, but aren't ready for scoped styles check out this plugin which gives you the meta box for declaring styles, but they won't be scoped you'll need to be as specific as regular CSS.

A word of warning

My own experience with my poor-man's version of this wasn't all sunshine and daisies; there is one major weakness to this approach and to scoped CSS: organization gets very hard - you end up with styles everywhere! Scoped CSS has the ability to save the day, but if it's at all possible you should use ID selectors and linked stylesheets.

This is one of the major reasons we should avoid inline styles, they're messy, they add to page weight something that maybe should be cached, they're a pain to overwrite, they can complicate troubleshooting, and most importantly they're hard to maintain. Like inline styles, Scoped styles do have their place and can be a powerful tool. Use them wisely.

An even bigger warning

Using scoped styles without a proper polyfill is dangerous. In a browser that doesn't support them, the styles you declare will affect the entire page. Imagine you use a scoped style to use an image replacement technique on the h1 title inside an article on your site. Your logo is also an h1, and thus the logo is also replaced in unsupporting browsers. The result is a reverse-cascading style disaster.

Just be warned. Scoped styles are a very useful idea but the days of use using them without a polyfill are very far off.

A jQuery solution

Due to the lack of native browser support, this would be one disappointing demo today if it were not for this great jQuery Polyfill made by Simon Madine. To get my demo working in WordPress I also:

  1. Enqueued jQuery into my WordPress theme.
  2. Added the following code to the footer of the theme (footer.php in the theme folder).
<script src="<?php bloginfo( 'stylesheet_directory' ); ?>/jquery.scoped.js"></script>
<script>
  $.scoped();
</script>

It works!

Wanna play?

Chrome 20 is the only browser at the time of this writing that is supporting scoped styles. Chrome 20 is currently in Canary, which is a pre-beta release that you can run side-by-side with stable Chrome with no problems. To use it, you'll need to enable a flag, which you do by:

  1. Go to the URL chrome://flags/
  2. Search page for "scoped"
  3. Click "Enable"

There's a bunch of other fun stuff in here too.

Chrome moves quickly, so in around 12 weeks from the time of this writing (Mid-July 2012) Chrome 20 should be stable. Whether the feature will be shipped enabled is another matter (we just don't know yet).

Demos

One day soon Scoped CSS will do all of the amazing things you're seeing in these demos natively in the browser without extra JavaScript. Until then you can dream, read about it on the w3.org here, and check these demos:

Scoped styles, while delivering the functionality above, also will prove very powerful in Web Components, a proposal at the W3C for defining reusable widgets in next generation web apps. Exciting stuff.

Comments

  1. This feature looks really useful and I could see myself using this on a regular basis—escpecially integrated into WordPress custom fields.

    You mentioned Chrome 20 is the only browser currently supporting this. Any ideas of the effects/output on other browsers?

    I’m hoping this gets implimented in other browsers soon!

    • Hugo
      Permalink to comment#

      If no mistake, on a browser which does not support “scoped”, the style block is like any other style block : it affects the whole document.

      Just tested on Firefox 11 : http://dabblet.com/gist/2419401. The second is also SaddleBrown, even if it isn’t in the containing the scoped style block.

  2. Permalink to comment#

    No idea! At this point enough people are using older browsers that I’d use the jQuery fix in the mean time anyways. The slow adoption of newer browsers means we probably can’t rely on this natively (without the fallback) for a couple years :(

  3. I just hate wordpress. Bloated & way too complicated.

    • Explain? I know it has a few drawbacks here and there, but overall most people I know (myself included) don’t mind it at all and definitely don’t hate it.

    • As far as CMS’s go, WordPress is extremely easy to use and is quite light weight. Whenever a small client requests a CMS I always opt for WordPress. I’d really like to hear your explanation as well.

    • PyroCMS is an excellent counter-example of WordPress’ clunkiness. It is lightweight, and offers customisation with far less hoop jumping.

      WordPress is excellent, but we’re looking to use PyroCMS for new clients due to its modularity, superior flexibility and speed, and code cleanliness.

  4. Permalink to comment#

    I don’t really like the idea of polyfills here: they’re unnecessary. The simplest, most effective fallback is what you described as your “poor man’s Scope”:

    <div class="scoped">
        <style scoped>
            .scope h1{ color: blue; }
            .scope p{ color: orange; }
        </style>
        <h1>My Scoped Heading</h1>
        <p>Since scoped styles apply to the parent element, 
            we need the wrapper div anyway.
            Why <em>not</em> give it a class name?  
            The enhancement and the fallback are one and the same.</p>
        <p>Eventually, as browser support matures, 
            we'll be able to drop the parent element's class name.  
            But I can imagine situations where we might want to keep it, too.</p>
    &lt/div>

    no javascript? no problem.

    • nbevacqua
      Permalink to comment#

      that hardly beats not using scoped

    • Permalink to comment#

      beats using scoped alone and having it wreck your whole page (or someone else’s: after all, a main purpose of scoped is aggregation; and you can’t rely on polyfills when you don’t know where your feed will end up).

      This solution:
      1. Works now,
      2. in all major browsers, with
      3. no unintended side effects,
      4. no dependencies (polyfills/feature detection), and
      5. regardless of whether or not javascript is enabled.

      In addition to being more robust, it’s also lighter-weight than using a polyfill, and it provides a natural hook for other purposes (scripts, for example).

      personally, I also think it’s A Good Thing because it reminds you (the developer) of structure and browser limitations. Like it or not, you can’t “just use it” right now. In the long run, this practice isn’t much extra effort, and will help a lot with migration as support develops.

    • Permalink to comment#

      I like it! Great thought!

  5. Matt
    Permalink to comment#

    Interesting feature, but I have to say I would never, ever use it, for the reasons outlined above. It makes maintenance harder, you have style mixed with structure, page bloat, the list goes on. It just feels like using !important in regular CSS… It has it’s place in edge cases, but most of the time when I find myself writing !important it’s time to go back and figure out why, and change the other CSS so that it’s not necessary anymore. I’d feel the same about using this.

    • I agree. And I’m beginning to think that this is inline styling all over again? Wasn’t that something we tried to get rid of?

  6. While not a particular fan of the concept (feels like new-fangled inline styles, and I know I’m certainly missing the point, that’s just how it feels :) ), I am a huge fan of using the right function in the right place –

    Instead of this –

    <?php bloginfo( 'stylesheet_directory' ); ?>

    to reference the stylesheet directory, this could alternatively be used –

    <?php echo get_stylesheet_directory_uri(); ?>

    The benefit of using this is that it will work properly for SSL.

    That all said – a good argument could and perhaps should be made for enqueuing this script as well, perhaps in a functionality plugin for the theme or the functions.php file of that theme.

  7. Paul Garcia
    Permalink to comment#

    Cool use of CSS SCOPED in WordPress’ posts, and also for people no “php friendly” you just can write the CSS code inside the post in “HTML VIEW”:

    
    <style scoped>
        h1 { ...... bla bla  bla ..... .... }
       p {..... bla bla bla .... }
      &lt/style>
    

    also this way is faster as WordPress don’t have to deal with Custom Fields specially if you have many if them and you dont have to mess Wp themes and php files.
    I love Php and love the “poor man’s scope” Custom Field solution but I know some people hate it.
    Thx Arley for sharing…

  8. Ville
    Permalink to comment#

    Eh, inline-styles are bad mmmkay?

    The “A word of warning” paragraph sums it pretty well and hopefully I don’t have to use any inline-styles ever :)

    • Permalink to comment#

      Totally. I don’t like inline-styles, too.

      Other than that, I don’t see a “real” use-case for scoped styles other anyways. That’s just for hacks, ain’t it?

  9. Alastair
    Permalink to comment#

    Yeah, won’t be using this and won’t allow my clients to use it either. Good luck for those who choose to.

    ps. it’s not remotely cool, it simply goes against everything we’ve been fighting against for years (content vs. presentation).

  10. Richard Rosenthal
    Permalink to comment#

    I feel like the advantages are not that specific to the scoped styles vs inline styles. While I do see this as having its uses, I feel like they are such fringe cases that its not worth adding

    That being said, I would LOVE the ability to declare something as scoped from within a stylesheet, so that it would ignore all outside styling and act as its own “namespace,” if you will. It could potentially cut down on css file size, while still maintaining the different abstraction layers.

  11. Sebastian
    Permalink to comment#

    Also available on Chrome dev: (20.0.1105.0 dev-m)

    “Enable . Mac, Windows, Linux, Chrome OS
    Honor the ‘scoped’ attribute in elements.”

  12. Maybe it’s just me that’s too tired to understand how epic this scoped styling is, but how would this differ from adding a unique class (through PHP ofc) to the body / post of a say a WordPress and give that particular post some unique styles?

    I believe that Chris Coyier and Jeff Starr’s BLANK WordPress theme has that functionality, allowing one to do:

    
       .unique-post-class h1 { color: smurfBlue; } /* I'm kidding, you can't use that color, kids. */
     

    I’ve used that quite some times on a previous version of my site for giving each post a unique touch and I didn’t need to spend astronomically large amounts of time doing it. :)

    Doing this allows me to keep working in a one-stylesheet environment, but I definitely see the potential of scoped styles too. Meh, guess I’m low on caffeine and sleep. :P

    Great article Arley, and a good read too. :)

    • I think the point is, if you would like to be able to customise styles on a per post basis (something people like to do particularly on art-directed blogs), then whilst you can do it the one-stylesheet way, you’re gonna end up with a huge style sheet, with a large portion of the styles only being relevant to one page. So for example, on the home page, you’ll be loading dozens of custom styles that it doesn’t need.

      The scope method allows you to keep those styles specific to the page they’re needed on, without bloating your main stylesheet and having to load them for all the other pages too.

      I don’t think scoped styles are a bad idea as such, but they could be used in a bad way. Just depends on the situation I guess.

  13. Permalink to comment#

    Good overview, Arley.

    A lot of comments are saying that this is too close to ‘inline styles’ and that they don’t see much benefit to it. You do allude to what I think is the most important benefit in your ‘why is this cool’ section, which I think is summarized well by Jeremy Keith here:

    http://www.html5forwebdesigners.com/semantics/index.html#scoped_styles

    He says:

    Trying to port a piece of content from one document into another introduces some problems. The CSS rules being applied to the parent document will also apply to the inserted content. That’s currently one of the challenges in distributing widgets on the web.

    HTML5 offers a solution to this problem in the shape of the scoped attribute…

    So the main benefit is portability. That is, being able to take a single block of content and put it anywhere on any site, and it will still have the same styling. So (when this feature becomes more common) if a developer starts using it in the same way they would use inline styles, then that should be a warning that maybe a different approach is needed.

  14. Dave
    Permalink to comment#

    Just a gentle reminder that the Web is a multi-continental system and that French is spoken outside of Canada …

    There is more to the world than North America ;)

    • Permalink to comment#

      Point well taken! All the bilingual work I’ve ever done is Canadian. Funny enough, I have French-Canadien friends who recently went to Paris, and said no one could understand them!

    • Dave
      Permalink to comment#

      I’m about to build 28 sites for various parts of the world for a multinational company (who like my employer are based in the UK).

      Some countries like Canada have 2 major languages such as Belgium (Flemish/Walloon), some have as many as 4 such as Switzerland (German, French, Italian, Romansch), the UK has more than you may think (English, Welsh, Scots Gaelic, Ulster,Cornish) each with their own quirks, although normally English and Welsh are the only ones that get catered for nationally. French is nothing compared to Norwegian for the difference in space needed!

      Now add to that the different character sets that are used by these languages and it all begins to add up. It’s a minefield, tbh but I don’t think i would be using scoped styling to deal with any of this, to me its all about flexible verticals :)

      So as you can see when you step outside of North America, the world is a LOT more complicated

  15. Informative article on advanced CSS. Infact these are the hardcore tips and tricks which hardly anyone is aware.

    You gave Bonus by linking to JQuery alternative. Sweet !

  16. Permalink to comment#

    Thanx!!!

  17. Awesome post. I might use this technique if I need my day to be saved eventually. Your wordpress example was really good and to the point.

    BTW: here in Quebec, we don’t need to allow 50% more place for bilingual content containers since we’re already designing in french! ;-)

  18. Jessi Hance
    Permalink to comment#

    Regardless of whether I ever end up using this, it’s cool to have another trick at hand.

    You know what’s really super cool, though? Acknowledging the special challenges of working with CMS systems. I really appreciate that, Chris. Those who’ve never had to grapple with (often poorly-written) third-party HTML that you can’t modify, and (often poorly-written) stylesheets that you can’t modify or prevent from loading, have noooo idea.

    Rather than being a sculptor, lovingly shaping every aspect of my website, I’m a puny wrestler, grappling with one big dumb brute after another, getting exhausted in the process. Terrible metaphors, but I think you get the gist.

    I’d been meaning to send in a question of some sort about this to the ShopTalk podcast – could you all talk about special challenges and approaches when working with CMSs. Maybe I still will. Anyhow, thanks for this!

    • Brandon Flynn
      Permalink to comment#

      I hear ya, Jessi. CMS wrestling has given me many a bruise.
      I’d love to hear about some CSS organization/common-pitfall-avoiding strategies regarding working with a CMS on an upcoming ShopTalk.
      Cheers!

    • Jessi Hance
      Permalink to comment#

      Thanks for the solidarity, Brandon! Maybe I’ll get around to submitting something to ShopTalk this weekend. Feel free to beat me to it, though!

  19. Jessi Hance
    Permalink to comment#

    My apologies for addressing my comments to Chris, instead of to Arley McBlain. Props to you, Arley!

  20. Great alternative to inline CSS…..it’s pretty much inline CSS.

    • Paul Garcia
      Permalink to comment#

      Yeap I agree with you Julian, but also is an alternative to A :HOVER inline problem

  21. Permalink to comment#

    Reading the “word of warning” and the first comment makes me worry about this. I can see it becoming a crutch, and a crutch that makes future management of a site a nightmare.

    We’ve all picked up sites riddled with inline styles, they’re no fun to work with. Furthermore, we’re in the age of the CMS, which means sticking those scoped styles in your database, or using a bunch of template files, or building in a bunch of logic into your template files.

  22. 9
    Permalink to comment#

    9

  23. Catalin
    Permalink to comment#

    Oh, I remember that you had a tutorial like this a few years ago. Was about a page from your blog. In that same week you used only safari. Good memory, huh? And the page was white (not as your current theme back then) and was two big pictures, and yea… they where taken from google images, and one was with mozilla, the other one with safari.. hmm !
    The cool thing is that you have actually nice JS scripts so they work in all browsers.
    Good luck.

  24. Permalink to comment#

    Perhaps I just don’t “get it” but this seems remarkably similar to the inline styles we all threw out years ago.

  25. It seems like they could make this 20% cooler by also allowing an external version like this:

    style.css:

    
    /* Here be code */
    
    @scope(#news-widget) {
    
      .style1 {
    ..
      }
    
      .style2 {
    ..
      }
    
    }
    
    /* Do not stray here, for thar be selectors */
    

    index.html:

    
    
    /* ^^ Headerville: styles protected by guards */
    
    <section id="news-widget">
    
    Content in here is scoped.
    
    </section>
    
    /*  Content ahead, beware of overwrites */
    
  26. Permalink to comment#

    When you define a scoped element, do the global styles still cascade into it or does it give you a “blank slate”? I can see this being really useful if it’s the latter, as it would allow you to create truly unique elements in the page devoid of *any* global styles. An example would be if you wanted to showcase a snippet of someone else’s CSS in your page or article without having to resort to an iframe or javascript snippet in order to clear out your own site’s style declarations, know what I mean?

  27. “WordPress is an example of a CMS that will limit what code you can enter into the content area.”

    I use MODX for just that very reason: I don’t want restrictions, limitations and I sure as heck don’t want to spend any amount of time going all over the place in the back-end.

    I just want to code and style without using my brain to figure out how I can re-use and keep this manageable.

    The solution is Template Variables (TV), or what WordPress calls widgets. But widgets are sooooo . . . . what? 2001? 1997?

    With a TV I can put it anywhere in my Template. The TV can be literally anything I want it to be, and it can be as `dumb` or as smart as I need it/want it.

    I do exactly what you described here on a regular basis, in various ways (and thank you for this post) I just don’t have to think, worry, or stress about managing it. With an over-the-top ACL I also don’t have to worry about any other content creators and editors overwriting my TVs.

  28. Thanks for your post on this, I can think of a couple of cases right off the top of my head where it would have made my life a lot easier had I known that something like this. The incorporation into WordPress was also a pretty interesting idea.

  29. Rhys Lloyd
    Permalink to comment#

    Unfortunately, it’s likely that this is going to be removed from Blink (Chrome): https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/R1x18ZLS5qQ

  30. Zaheer
    Permalink to comment#

    Dear Iwant to use multi jquery Ui Theme in a single page how is it possible easy,
    i have tried to download scope file from jquery theme but when i open its demo file its not work, and also i could not impliment on my web page
    so please write something abot it.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".