Cleaning up the “CSS only sexy bookmark” demo code
Friday, January 8th, 2010Going through my Google Reader I stumbled upon an article today called Sexy bookmark like effect in pure CSS. Normally when I hear “pure CSS” I skip as 99% of these solutions don’t work with a keyboard and are thus a bad idea to use on the web. However, this one intrigued me as I had no clue what a “sexy bookmark like effect” might be.
Turns out it was not a porn bookmark but one of those “share this with the social media” link-bars you have below blog posts to help the copy and paste challenged people out there:
OK, that can’t be that problematic. The trick to do a list of links as a cool rollover using CSS only has been done in 2004 in the first CSS sprites article. Notice that the links are in a list.
Now, the new article’s HTML is the following:
There are a few things wrong with this in my book:
- There is no semantic structure of what is going on here. Line breaks do not mean anything to HTML so in essence this is a list of links without any separation. Imagine sending three links to a friend in an email or putting them on a page. Would you do it like this: GoogleI can has cheezburgerb3taSpotify ? looks confusing to me…
- There is no content in the links – when CSS is turned off you find nothing whatsoever.
- There is quite a repetion of classes there. When every element in another element has the same class in it then something fishy is going on. Unless this class is used as a handle for – let’s say a microformat, you can get rid of it and use the cascade in CSS. So in this case you can style all the links with
.sharing-cl a{}
and get rid of the repeated classes. - A navigation is a structured thing, so instead of a div with links in it, how about using a list? This way when CSS is off, this still makes sense.
So here’s my replacement:
Of course you should replace the empty href
attributes with the real links.
Normally I’d use IDs instead of classes, but as this bar might be used several times in the document, let’s leave it like it is.
The HTML now is 318 bytes instead of 294 which is a slight increase. But:
- It makes sense without CSS
- It is well-structured and makes sense even to screen readers
- The links make sense as they say where they are pointing to.
Let’s check on the CSS:
.sharing-cl{
}
.sharing-cl a{
display:block;
width:75px;
height:30px;
float:left;
}
.sharing-cl .share-sprite{
background:url(http://webdeveloperjuice.com/demos/images/share-sprite.png) no-repeat}
.sharing-cl .sh-su{
margin-right:5px;
background-position:-210px -40px;
}
.sharing-cl .sh-feed{
margin-right:5px;
background-position:-70px -40px;
}
.sharing-cl .sh-tweet{
margin-right:5px;
background-position:-140px -40px;
}
.sharing-cl .sh-mail{
margin-right:5px;
background-position:0 -40px;
}
.sharing-cl .sh-digg{
margin-right:5px;
background-position:-280px -40px;
}
.sharing-cl .sh-face{
background-position:-350px -40px;
}
.sharing-cl .sh-mail:hover{
margin-right:5px;
background-position:0 1px;
}
.sharing-cl .sh-feed:hover{
margin-right:5px;
background-position:-70px 1px;
}
.sharing-cl .sh-tweet:hover{
margin-right:5px;
background-position:-140px 1px;
}
.sharing-cl .sh-su:hover{
margin-right:5px;
background-position:-210px 1px;
}
.sharing-cl .sh-digg:hover{
margin-right:5px;
background-position:-280px 1px;
}
.sharing-cl .sh-face:hover{
background-position:-350px 1px;
}
So here we have a lot of repetition. You also see where the share-sprite class comes in: if you wanted to add an element to that section that is a link but has no image background you just leave out the class. This, however is exactly the wrong approach to CSS. We can assume that every link in this construct gets the background image, which is why it makes more sense to apply the image to the a
element with .sharing-cl a{}
. As every link has a class you can easily override this as the “odd one out” with for example .sharing-cl a.plain{}
.
The same applies to the margin-right:5px
. If that is applied to all the links but one, don’t define it for all the others and leave it out at the “odd one out”. Instead, only apply it to the odd one out and save a lot of code.
Final CSS:
.sharing-cl{
overflow:hidden;
margin:0;
padding:0;
list-style:none;
}
.sharing-cl a{
overflow:hidden;
width:75px;
height:30px;
float:left;
margin-right:5px;
text-indent:-300px;
}
.sharing-cl a{
background:url(http://webdeveloperjuice.com/demos/images/share-sprite.png) no-repeat;
}
a.sh-su{background-position:-210px -40px;}
a.sh-feed{background-position:-70px -40px;}
a.sh-tweet{background-position:-140px -40px;}
a.sh-mail{background-position:0 -40px;}
a.sh-digg{background-position:-280px -40px;}
a.sh-face{
margin-right:0;
background-position:-350px -40px;
}
a.sh-mail:hover{background-position:0 1px;}
a.sh-feed:hover{background-position:-70px 1px;}
a.sh-tweet:hover{background-position:-140px 1px;}
a.sh-su:hover{background-position:-210px 1px;}
.sh-digg:hover{background-position:-280px 1px;}
a.sh-face:hover{
margin-right:0;
background-position:-350px 1px;
}
From 1028 bytes down to 880. Just by understanding how CSS works and how the cascade can be used to your advantage. I would have loved to get rid of the a
selectors, too, but they are needed for specificity. Notice the overflow on the main selector – this fixes the issue of the floats not being cleared in the original CSS. By using negative text-indent we get rid of the text being displayed, too. Personally I think this is bad and you should try to show the text as you cannot expect end users to know all these icons.
For example:
#text{
margin-top:3em;
font-weight:bold;
font-family:helvetica,arial,sans-serif;
}
#text a{
text-indent:0;
height:auto;
text-align:center;
font-size:11px;
padding-top:35px;
color:#999;
text-decoration:none;
}
You can see the solution in action here:
To me, praising “CSS only solutions” is not enough – if you really love CSS and see it as a better solution than JavaScript then you should also show how people can use its features to create smart, short and flexible code.