Abusing text-shadow for fun and profit

A while back, when Opera 9.5 was in development, we gained support for [getters and setters](http://ejohn.org/blog/javascript-getters-and-setters/), and I needed some smoketest to check whether they worked as advertised.
Around the same time, we also added support for text-shadow, as outlined in the documentation for [Presto 2.1 standards support](http://dev.opera.com/articles/view/presto-2-1-web-standards-supported-by/#css3) (Presto is the core engine of Opera, currently in version 2.1)
So, I ended up testing both at once. [See the example](http://virtuelvis.com/gallery/text-shadow/). The demo fades some text in and out of the screen, simultaneously deblurring the text as it becomes visible. The fading itself is fairly trivial, with the animation library used taking care of the work.
### The script
I’ll keep this explanation brief, and gloss over some of the details, but: The majority magic happens in the getters and setters defined. Somewhere in the inlined code on the page, you’ll find this:
var e = CSSStyleDeclaration.prototype;
// … other getters and setters
e.__defineGetter__(“blur”,function(){ return this._blur_||0; });
e.__defineSetter__(“blur”,function(val)
{
this._blur_ = val;
this.textShadow = this.shadowX+” “+this.shadowY+” “+val+” “+this.shadowCol;
})
In the actual code, `this.shadowX`, `this.shadowY` and `this.shadowCol` are also attained through getters and setters on a CSSStyleDeclaration, but for the purpose of explaining, you can assume them being hardcoded to 1000px, 0 and #fff, respectively.
So, when the animation library is initialized and animations are set up, we tell it to animate the `blur` property of the affected element’s style
var st = document.getElementById(‘foo’).style;
var anim = new Animator(st,1000,15,
function(){ setTimeout(moveOut,1750) },
forceRepaint);
anim.addProperty(“blur”,12,1,”px”);
So, when the animation is run, the library iterates through all the properties of the animation, and when reaching the `blur` property, it sets it, but what is actually set is the blur value of the text-shadow, e.g. 1000px 0 3px #fff
### The CSS
For the purposes of the CSS, I conjured up a somewhat more minimal example, in the form of a navigation list.
[Try out the example here](http://virtuelvis.com/gallery/text-shadow/navigation-list)
What is happening in this example is pretty much analogous to what is going on in the animated demo. When you hover an element in the list, that element gets some focus, while the rest of the elements are blurred to bring attention to what you currently are hovering.
The first CSS rule to mind here is:

li {
font-weight: bold;
padding: 0.5em 0.5em;
display: block;
overflow: hidden;
color: #333;
background: hsl(40,15%,90%);
border: 2px outset #aaa;
}

Specifically, the `overflow: hidden` rule, which ensures that we clip the element’s box if content overflow it. Next, we’re applying a rule to all list elements when the list itself is hovered:
ul:hover li {
text-indent: -8em;
text-shadow: 8em 0 0.33em #333;
background: hsl(40,15%,40%);
}
The point of the rule is to move the text out of the element’s box, by setting text-indent to -8em and instead setting a text-shadow offset as 8em. Next up here is setting some mild blur (If you can call 0.33em, which I used for dramatic effect), and the same color as the text.
Finally, for this example, the following rule resets the text-shadow to something more sensible:
ul li:hover {
text-indent: 0;
color: #eee;
text-shadow: 1px 1px 2px #333;
background: hsl(40,15%,60%);
}
### Closing words
While you can probably do some real cool stuff, and create low-cost effects, I would advise against using it for production use: In both examples, text will become invisible if text-shadow is not supported. From what I have been able to gather, only a limited set of browsers [support text-shadow](http://www.css3.info/preview/text-shadow/)
Either way, it might be fun in 2014 when browsers have caught up to the next level of CSS.

Next Post

4 Comments

  1. That is indeed very wicked! I love it. Looking forward to seeing this implemented in the different JavaScript libraries, like jQuery. Excellent work. 🙂

  2. Brilliant! The first demo reminded me of LOST. All we need now is a way to make the text come in with a 3D effect.

  3. Chris: Good idea. Just hope CSS transformations can make it into a standard soon.

  4. Very nice, Arve. I’m definitely going to play around with this.