I’ve said before and I’ll say again that
This time, I want to combine what we’ve learned about CSS and
contenteditable with another HTML5 attribute called
scoped, and show you a fun little jQuery plugin that’s sure to make your day more interesting.
First let’s get the browser issues out of the way.
scoped may not work in all browsers. Definitely check to see if you can use
scoped on caniuse.com. Even if the answer is “yes”, you may still need to enable a flag. Go to Chrome://flags in Google Chrome to flip it on (warning, may require a browser restart).
You have three values for this attribute:
There’s two ways we make an element’s content editable for the end user, the difference is whether you want to use a value. Therefore, setting either
contenteditable="true" on an element will get you the same result. A browser, by default, sets the value to
true when the
contenteditable attribute is present (but I’ll explicitly set the value because valueless attributes creep me out).
Child elements get a value of
inherit unless you explicitly state otherwise.
Once an element is
contenteditable, the end user can now change any of that content that’s inside; all descendants of this element will inherit this property. Yes, that means those
<headers>, and even
Folks have been talking about
scoped for a while (in the web world, a while == a year). It’s another HTML5 property that’s in draft mode, and it hasn’t been advanced too much because it is extremely dangerous… to the design.
scoped attribute is meant for the
<style> element. What it does is tell the browser that these styles apply only to the parent container and its children. The styles that are scoped are isolated to only one small piece of the page; they won’t affect the entire design. So, consider the following HTML:
Bacon for the Win
If you have
scoped enabled in your browser, this HTML will make much more sense to you.
Bacon for the Win
And if you didn’t get the joke, here’s a picture of what you should see:
The default color was supposed to be green for those
h1 elements, but in the first one we set a new style, scoped it, and didn’t affect the others. As a result of the scoped style, Bacon is its proper and respectable color.
The dangers of
Ignoring the ever-present issue of browser support, there are other serious dangers with this attribute. The big one is that this is the override that overrides the override. Best practices dictate that we use an external stylesheet. Decent practices dictate that we use an internal stylesheet in the
<head>. Bad practices involve style blocks in the body, and worst practices are inline-styles.
There’s two reasons that we don’t like styles on the page itself: manageability and specificity.
The specificity is what really gets hairy in the case of
scoped styles. Recall that the order of specificity power is this:
inline style / style block > ID > class > element
Your inline style block is already the Obi Wan Kenobe of the specificity wars (I guess that an inline style must be a Yoda / Superman / Chuck Norris combo).
Once you start scoping the styles, it’s almost like there becomes 5 levels of specificity:
inline style / scoped style block > style block > ID > class > element.
You see, an inline style will still trump a scoped style block. But, a scoped style block can beat a non-scoped style block. I wouldn’t venture to say that there is a true fifth level of specificity, though — I imagine the battle for specificity supremacy is why so few browsers have implemented
So why used
scoped at all?
contenteditable=true, there’s no reason not to sandbox the styles, too. This means you can safely edit styles without disrupting the design of the entire page. Not only that, a scoped style may be very useful if you build inline WYSIWYGs for a page.
Scoped is good for building prototyping tools or developing content design APIS. It’s an absolutely HORRIBLE idea anywhere else.
A Good Protyping Plugin
So, I wrote a jQuery plugin called editable which you can fork on GitHub.
To make an element editable, it’s easy:
And if you want to be able to edit those styles, here’s how.:
Provided your browser supports the
scoped attribute, you can edit and style by simply double clicking the element (I’m not doing feature checking yet). Use the up arrow to get to that style block up at the top of the element (I haven’t worked out the events so that it stays there when you move the mouse).
I haven’t buffed out some of the finer points of the user interface, but follow the repo on GitHub and you’ll see it improve.
If you want a live demo, it’s over on JSfiddle.