Reading List
The most recent articles from a list of feeds I subscribe to.
Exploring CSS3 text-shadow
I consider CSS3’s text-shadow one of the most exciting CSS3* properties, which offers us a lot more effects than it’s name suggests. Of course, it can be used for creating drop shadows for text, and it carries out that task very well, but it’s inherent flexibility allows it to be also used for glow effects, outlines, bevels, extruded text, inset text, fuzzy text and many others (until browser bugs and backwards compatibility come into play… :(). This post is about various findings of mine (and others’, where a source is provided) regarding this property, including browser bugs and inconsistencies, effects that can be achieved with it, compatibility woes etc.
Browser support
- Opera 9.5+
- Firefox 3.5+
- Safari 1.0+
- Google Chrome
text-shadow syntax
The syntax is fairly simple:
text-shadow: <offset-x> <offset-y> <blur-radius> <color>;
There are some variations (the color could be first instead of last, the blur radius can be omitted if it’s equal to zero and the color may be omitted if it’s the same as the text color) and you may include multiple comma delimited shadows.
You may read more about the syntax in the official specification.
How it works
It helps if you imagine the algorithm for drawing the text shadow as follows:
- Create a (most of the times differently colored) clone of the text and place it behind the text.
- Move it according to the X and Y offsets (positive values move it to the right and bottom respectively)
- If a blur radius is specified and it’s > 0, blur it accordingly (the specification doesn’t mention the blurring algorithm to be used, so each browser vendor may choose any blurring algorithm they prefer, and judging by my experiments, it seems they took advantage of this freedom). In all cases however, the bounding box of the blurred text can extend no further than the bounding box of the original text plus (+) the specified blur radius on each side.
- Repeat for the rest of the shadows, if more than 1 are specified. The order in which shadows are drawn seems to be a subject of debate, judging by the wording of the specification and the various existing implementations.
The experiments
You will find the experiments I performed here. I tried to come up with (or find) interesting uses of the property. I also tried to make some of them “pretty”, so they could be useful to others, but given the fact that these were primarily created for testing purposes, this wasn’t achievable for all of them. Next to each experiment is the CSS used to produce the effect (directly fetched from the <style> tag via JavaScript). You’d better not view it with IE until you read below or you might have some freaky nightmares tonight :P
Screenshots from various browsers: (mouse over the thumbnails to see which browser was used for each one)
[gallery link=“file”]
Browser bugs and inconsistencies
Apparently, some browser bugs were exposed in these experiments:
- Opera 10 and Safari don’t display the shadow when the text color is
transparent(demonstrated in Experiment #5). Opera 9.6 doesn’t seem to supporttransparentas a text color, so it ignores it. - When the text color is RGBA, Safari applies transparency to the shadow, equal to the Alpha component (demonstrated in Experiment #8).
- Opera paints the shadows in the order they were specified, whereas all others use the reverse. According to the current version of the specification, Opera is the only correct one, but I doubt that web designers will give her credit for it :p (Experiment #8)
- Google Chrome uses a crappy blurring algorithm (Experiments #5 and #7)
- Safari and Chrome don’t default to the text color when no color is specified in text-shadow, but to
transparent. (Experiment #2) - Opera is seriously messed up when it comes to transparent shadows, as demonstrated by Experiment #9. I can’t even describe the bug (try messing with the text-shadow value a bit and you’ll see why…). Luckily, I can’t think of a single case where a transparent text-shadow would be useful :P
- You can see a bit of the shadow in Google Chrome even if the offsets and blur radius are all 0 (Experiment #9). I’m not sure if this is a bug, but it’s inconsistent with the other implementations.
- Even if you ignore the bugs above, there are slight rendering variations when multiple blurred shadows are involved (or they are more apparent in those cases), as demonstrated by experiments #2, #6 and #7.
Firefox’s implementation seems to be the clear winner here…
A note about the above observations: When no version number is mentioned, 3.5 is implied for Firefox, 10 for Opera and 4 for Safari and Chrome.
Alternatives to text-shadow
IE Filters
As you might have noticed, I have managed to completely avoid mentioning Internet Explorer up to this point. It’s no surprise that our dearest browser doesn’t support the text-shadow property. However, it does support some filters (DropShadow and Shadow) that could be used to provide a very small subset of the different kinds of text shadows, although they severely mess up the font anti-aliasing (just like all IE filters). Also, if the parent or siblings of the text node in question have backgrounds or borders an extra element is needed to enclose the text node (you’ll see in the experiments why…). For these reasons, I highly doubt whether they are worth it and I don’t use them personally. However, if you are interested you can see a brief demonstration of these two filters in Experiments #3 (DropShadow) and #6 (Shadow, actually 4 of them).
The :before pseudo-element
This could be used instead of the text-shadow, when the blur radius is 0, since browser support for the :before pseudo-element is better than browser support for text-shadow (even IE8 supports that, yay). Here is a thorough (although slightly outdated) tutorial on this technique. However,this workaround severely hurts separation of presentation and content/structure, since the content has to be duplicated in the CSS. Repeating something greatly increases the chance that the two copies become inconsistent, since people tend to be forgetful. Also, you have to know in advance the exact height of the text (in lines), another maintenance headache. For these reasons, I don’t use this workaround either.
In my humble opinion, the text shadow is usually just icing on the cake and not something crucial to the design, so it doesn’t hurt if it won’t show in some old and/or crappy browsers. It degrades gracefully in most cases (ok, you’ll have to wait a few years before using it in ways that don’t) so it doesn’t hurt usability/accessibility either. It’s just one of the little treats I like to offer to visitors that were smart enough to use a decent browser. :-)
Epilogue
text-shadow is a very flexible property, with probably the best browser and editor – even Dreamweaver acknowledges it’s existence! – support among all notable CSS3* properties. It also degrades gracefully most of the times (the experiments above shouldn’t be considered “most of the times”! :P ) and this is why it’s probably also the most widely used CSS3* property.
I think it could be improved even more by allowing for the inset keyword (just like inset box-shadows – sadly only Firefox 3.5 supports those at the time) and a fourth parameter could be used to enlarge or shrink the shadow (currently the only way to enlarge it is by blurring it, which isn’t always desirable) although it would complicate the shorthand (the blur radius would probably become required – so that the browser can tell them apart). However, a separate property could be used to solve that (text-shadow-size?). I guess we could combine the :before technique, with transparent text color (in the :before pseudo-element) and a text-shadow for that to imitate such an effect (I can elaborate if this seems obscure) although I haven’t actually tried it (however, even if it works, it’s too much of a hassle).
Anyway, I guess it’s too late for such suggestions, so let’s focus on what we actually will get (?) which is more than sufficient :-)
______________________________________________________________
*Actually, it was originally proposed for CSS 2.1, but it was dropped due to lack of implementations (basically only Webkit supported it)
(byte)size matters
Yesterday, I was editing a CSS file and I was wondering how many bytes/KB would a particular addition add to it, in order to decide if it was worth it. Since, I had found myself wondering about the exact same thing multiple times in the past, I decided to make a simple standalone HTML page that would compute the size of any entered text in bytes, KB, MB, etc (whatever was most appropriate). It should be simple and quick and it should account for line terminator differences across operating systems.
About half an hour later, I was done. And then it dawned on me: Someone else might need it too! Since .com domains are, so cheap, hey, let’s get a domain for it as well! There are several sites with a domain that are way simpler than that anyway. A friend that was sitting next to me suggested “sizematters.com” as a joke, but as it turned out, bytesizematters.com was free, so we registered it. And there it is, less than a day after, it’s aliiive. :P
Any feedback or suggestions are greatly welcome!
For instance, should I implement a very simple minification algorithm and display bytesize for that as well, or is it too much and ruins the simplicity of it without being worth it? [edit: I did it anyway]
Should I implement a way to compare two pieces of text and find out the difference in byte size (could be useful for JavaScript refactoring)? [edit: I did it anyway**]**
(byte)size matters
Yesterday, I was editing a CSS file and I was wondering how many bytes/KB would a particular addition add to it, in order to decide if it was worth it. Since, I had found myself wondering about the exact same thing multiple times in the past, I decided to make a simple standalone HTML page that would compute the size of any entered text in bytes, KB, MB, etc (whatever was most appropriate). It should be simple and quick and it should account for line terminator differences across operating systems.
About half an hour later, I was done. And then it dawned on me: Someone else might need it too! Since .com domains are, so cheap, hey, let’s get a domain for it as well! There are several sites with a domain that are way simpler than that anyway. A friend that was sitting next to me suggested “sizematters.com” as a joke, but as it turned out, bytesizematters.com was free, so we registered it. And there it is, less than a day after, it’s aliiive. :P
Any feedback or suggestions are greatly welcome!
For instance, should I implement a very simple minification algorithm and display bytesize for that as well, or is it too much and ruins the simplicity of it without being worth it? [edit: I did it anyway]
Should I implement a way to compare two pieces of text and find out the difference in byte size (could be useful for JavaScript refactoring)? [edit: I did it anyway**]**
Bevels in CSS3
Yeah, yeah I know, bevels are soooo 1996. And I agree. However, it’s always good to know the capabilities of your tools. Talented designers will know when it’s suitable to use a certain effect and incapable ones will abuse whatever is given to them, so after a lot of thought, I decided to blog about my discovery.
Even though not directly mentioned in the spec, CSS3 is capable of easily creating a bevel effect on any element. Moreover, if the element has rounded corners, the bevel follows that as well. Before explaining the technique, let’s think about how a bevel actually gets drawn. It’s essentially two inner shadows, that when combined, create the illusion of a 3d appearance: a light one from the top left corner and a dark one from the bottom right corner. CSS3 includes the ability to create inner shadows, if you specify the keyword “inset” in the box-shadow declaration (currently only supported by Firefox 3.5). Moreover, the CSS3 spec allows for multiple box shadows on the same elements.
Now, let’s examine an example (only works in Firefox 3.5):
button { background:#f16; color:white; padding:6px 12px 8px 12px; border:none; font-size:18px; -moz-border-radius:10px; -moz-box-shadow: -2px -2px 10px rgba(0,0,0,.25) inset, 2px 2px 10px white inset; }
which produces this result:

If we want, we can also create a “pressed” button state, in a similar fashion:
button:active { -moz-box-shadow: 2px 2px 10px rgba(0,0,0,.25) inset, -2px -2px 10px white inset; padding:7px 11px 7px 13px; }
button::-moz-focus-inner
which produces this pressed state:

See it in action here (only for Firefox 3.5): http://lea.verou.me/demos/css3bevel.html
Of course, if implemented in a real world website, you should also add the -webkit- and -o- CSS3 properties to provide a closer effect for the other browsers and be ready for the time when the ones that aren’t implemented yet in them will finally make it (for instance, when Webkit implements inset box shadows, it will work in it as well).
Enjoy responsibly. :-)
Idea: The simplest registration form ever
If a web application has some sort of registration system (and most do), the registration page should be one of the most attractive, inviting, usable pages of it. It should make you to want to register, not repulse you. We don’t want the user to give up in the middle of filling it because they are fed up with it’s length or bad usability, or -even worse- not even attempt to do so, do we?
The most popular websites usually take this rule to heart and employ the simplest registration forms: Only the basic fields required, and most of the times, even without password/email confirmation.
I was wondering lately - what would be the simplest possible registration form? It should have the minimum number of fields required: Username and password and a field for some kind of human verification.
At this point, some readers might argue “Hey, why not an email field as well?”. In my opinion, the email is not always a required field. Let’s see why it’s being asked for in most cases: Unique identification (to prevent double accounts) and for sending out notifications for important events. However, it’s useless for the first purpose due to all these disposable email websites. As for the second purpose, since notifications can be switched off (and if not, then they are essentially considered spam), it could be regarded optional and we don’t include optional fields in registration forms, do we? ;-)
Of course, in websites that use the email instead of a username to let their users log in, you may just substitute the username field above with an email field (since in that case, the username is what could be considered optional) and we also have two fields. Smart readers might have noticed another pattern here: The only fields that are truly required for a registration form are the same ones that are required for a login form plus a human verification field.
And then it dawned on me: We can make the registration process almost as quick as logging in! We could use the same form for both actions. The submit button label could indicate the dual nature of the form, for instance “Log in or register”. If the username (or email) doesn’t exist, we could then ask the user whether they want to create a new account and present them the human verification field at that point. There is no need for a password verification field, since we could just have a checkbox for displaying what the user typed, if they feel insecure about it.
I find 3 inherent issues with this approach:
- Security. If a login attempt fails, the user will know whether he got the username or the password wrong. However, in most websites, you can easily check whether a username exists anyway, so I don’t consider this a real concern. I just included it because I’m certain that if I didn’t, somebody would point it out to me in the comments.
- Despite being a more usable approach by nature, it’s not by any means a convention yet. Until it becomes one, I’m afraid that some users will be confused by its extreme …simplicity! Funny, isn’t it?
- We won’t be able to employ Ajax verification for the registration form, since it will essentially be a login form as well, and until the user submits, we won’t know what they plan to do (login or register). Having an Ajax verification script there by default will confuse existing users as hell (as in “What do they mean by ‘Username is taken’? WTF??”). So, we have to sacrifice some usability to gain some usability. The question is: Is the usability we gain more than the usability we sacrifice? What do you think?
As you can see by the problems mentioned above, it’s still a rough-on-the-edges idea (I just thought about it and I haven’t refined it yet), but I think it’s interesting. What are your thoughts?