Accessible sprites?

Are sprites in CSS accessible?

Ok, so I’m working on a site and want to put my social media icons (Facebook, Twitter what have you) at the bottom of the page.

When the user rolls over I want the images to change to inverted colours.

I’m just wondering what the best and most accessible way to do this would be. I’ve had a look at Trifecta images but these seem somewhat outdated, so it seems that sprites would be a better way to go. I have read though that they aren’t all that great for accessibility.

So what’s the answer?

Here’s a snippet of the testing code I’ve produced (obviously it is very bad to have empty tags, but isn’t hiding text via padding or a -99999px margin just as bad?):

<style>
#social{
	height:400px;
	width:300px;
	background-color:#999;
}
#social a {
	display:block;
	height:32px;
	width:32px;
	background:url(../images/facebook.png) no-repeat 0 -32px;
}

#social a:hover {
	background-position:0 0;
}

</style>

<body>

<div id="social">
<a href="#"></a>

</div>

Thanks!

Jonno

The most accessible means would be to place text in the anchor so that the link is accessible when images are off. An empty anchor is not a good idea, always use text than add images/icons using an image replacement method.

Yeah, oddz is right – empty anchor == /FAIL/… This is why things like gilder-levin image replacement came along in the first place – AND you have a perfectly good anchor to use as the wrap container.


<ul id="social">

	
	<li class="skype">
		<a href="#">
			Skype
			<b></b>
		</a>
	</li>
	
	<li class="twitter">
		<a href="#">
			Twitter
			<b></b>
		</a>
	</li>
	
	<li class="tumblr">
		<a href="#">
			Tumblr
			<b></b>
		</a>
	</li>
	
	<li class="faceBook">
		<a href="#">
			Face<span>book</span>
			<b></b>
		</a>
	</li>
	
</ul>

The span is in there to split ‘facebook’ into two lines, since at 32px wide fitting the text inside the box is going to be tough (I’d give serious thought of going to 48x48 for that reason). By using a span when CSS is disabled or a screen reader hits it – in theory – it should be treated as one word thanks to the lack of whitespace. The empty bold tags is a “sandbag” to be absolute positioned over the text.


#social a {
	position:relative;
	display:block;
	overflow:hidden;
	width:32px;
	height:32px;
	text-align:center;
	font:normal 10px/16px arial,helvetica,sans-serif;
}

#social a span {
	display:block;
}

#social a b {
	position:absolute;
	top:0;
	left:0;
	width:32px;
	height:64px;
	background:url(images/social.png) 0 0 no-repeat;
}

#social a:active,
#social a:focus,
#social a:hover {
	top:-32px;
}

#social .twitter b {
	background-position:-32px 0;
}

#social .tumblr b {
	background-position:-64px 0;
}

#social .facebook b {
	background-position:-96px 0;
}


This approach while a wee bit of code, is much more versitile than most as it gets real text in there, shows that real text when images are disabled (though it works better when the image is bigger) or when CSS is off… and lets you use CSS sprites on two dimensions while only having to state background-position once per unique icon. We use overflow to ‘chop off’ our double-tall inner bold tag, sliding it up to reveal the bottom half on hover – that way you just put your hover states underneath the unhovered, and your various buttons all in a single image going across.

… for example. One file, only having to state background position once instead of twice, single hover state instance for all four. WITH actual text in the links that’s shown images off.

The only drawback being it’s absurdly tiny text – but for social icons I don’t consider that the end of the world; it’s also one of the few cases where I MIGHT consider adding TITLE to those anchors identical to the text inside said anchor… maybe. Would probably still strike me as redundant with no accesskeys to justify the use of title – as unless it’s a accesskey item, if you have to resort to the TITLE attribute, there’s probably something wrong with the content of that tag.

That’s a pretty interesting technique.

A bit of a simpler technique (though it doesn’t handle when the image is missing) is to simply set the text-indent to a really large negative number.


<ul class="social">
  <li class="twitter>
    <a href="#">Twitter</a>
  </li>
</ul>


#social li a {
  background: url(spritesheet.png);
}

#twitter a {
 text-indent: -10000px;
 display: block;
 width: 32px;
 height: 32px;
 background-position: 0 0;
}

#twitter a:hover {
 background-position: -32px 0;
}

It’s not as versatile as the one DS posted (namely it won’t show the text if images are simply disabled), but it will still allow screen readers to read the anchor and the code is easier to understand (and no extra HTML elements).

Which is why I reject that technique altogether – as it defeats the entire POINT of doing image replacement.

Also to do four of them you’d have to say background-position EIGHT times… once for no hover, once width, once for no hover, once with… gets annoying after a bit :smiley:

ESPECIALLY if like a good little dooby you bother to say :active and :focus so keyboard navigators aren’t left out in the cold.

I agree your technique is superior (and I’ll probably start using it going forward myself) =p.

Just wanted to offer a bit of a simpler solution since it’s a bit complex (I had to sit there for a bit and look at it to figure out exactly how it was working).

Cheers as ever DS, gonna have a proper look into gilder-levin image replacement to get a full understanding of what’s going on.

Your code didn’t work however. I first wrote it out by hand and got nothing, then I tried copypaste and then it was causing flickering. Any ideas?

Thanks

@deathshadow60 Nice one man, thanks for showing me that, it’s an awesome technique!

Is it not bad to have an empty element, in this case <b></b> though?

Thanks again

Normally, yes. However, that’s the trade-off that makes everything else in the technique work properly.

I haven’t looked at it but flickering is normally due to the image not being loaded upon the page request.

You can normally avoid flickering by combining all the images into one file, aka a Sprite image and just switch between the images on hover (change the background position). It also saves HTTP requests :).

Or you could use JS, though that’s a bad option :).

My bad, typo. What I get for typing it in on the laptop – can’t type worth a damn on those useless low travel keyboards.

Off Topic:

Ok, I’ll admit it, I can’t type worth a damn on anything less than a IBM Model M – <Ordell>when you absolutely have to type every last {expletives omitted} character in ASCII 7, accept no substitutes!</Ordell> – NOT really a joke, it’s the Kalashnikov of keyboards.

This:


#social a:active,
#social a:focus,
#social a:hover {

Should have been this:


#social a:active b,
#social a:focus b,
#social a:hover b {

My bad. Couple other ‘bugs’ in that too.

Here’s a working copy:
http://www.cutcodedown.com/for_others/jonnoW/hovers/template.html

As always directory is wide open for easy access to the bits and pieces:
http://www.cutcodedown.com/for_others/jonnoW/hovers/

The only bad thing about it is that it’s extra markup… but it’s not a LOT of extra markup so I look the other way. You argue any other point of it, and it’s bull… NOT that some people who think they understand semantics won’t try to argue it… A, B, I and SPAN are all semantically neutral tags – which is to say they apply no semantic meaning to their contents, (yes, even anchor… and anchor does NOT change the meaning or structural importance of it’s content!)… so there’s no harm in using them as presentational hooks – which is to say WHERE you might want to latch on presentation, without saying WHAT that presentation actually is.

But more importantly, using them as sandbags (the term for an empty tag before or after a section of content) means they aren’t content, will never be treated as content, and so have zero impact from an SEO or accessibility standpoint.

So literally, the worst thing that can be said about them and the ONLY arguement against it that holds water is that a empty B or SPAN is seven to 11 extra characters – OH NOES, NOT THAT. Most people waste more than that on absolute URL’s for nothing or endless pointless classes and DIV around things that don’t need extra div, or classes.

In an IDEAL world instead of a empty ‘sandbag’ tag we could use generated content using :before or :after, but legacy IE doesn’t quite handle that right… there’s an expression to get around that… Well, lemme show you. Gimme a minute or two and I’ll toss together a demo of that.

Here we go:
http://www.cutcodedown.com/for_others/jonnoW/hovers/template2.html

with the CSS for that:
http://www.cutcodedown.com/for_others/jonnoW/hovers/screen2.css

Modern browsers I use :after and generated content to add the element – versions of IE that don’t know what :after is (IE7 and lower) get an expression that adds the bold tag to the markup and uses the old method. Doesn’t work scripting off, but that’s why the fallback text is important.

I actually would rather use the empty bold tags in the markup until IE7 is a long forgotten memory… it’s actually simpler. 7 extra bytes in the markup per item, or 80 bytes extra average per item in the CSS - even with CSS caching, I’d just go ahead and put them into the markup.