0

I'd like to replace the text ("Word 1 Word2 Word3 Word4") in the following HTML with images, using CSS. I'd like the images to appear in-line horizontally too, as the text would.

<div id="aSentence">
    <p>
        <span id="word1">Word1&nbsp </span>
        <span id="word2">Word2&nbsp </span>
        <span id="word3">Word3&nbsp </span>
        <span id="word4">Word4&nbsp </span>
    </p>                    
</div>

I've read through and tried a couple of the techniques from mezzoblue and some other sites, but I'm coming to the conclusion that those techniques seem to require that the text's span is surrounded by a or another element type that will make the words not line up horizontally.

Any ideas on how I can achieve this goal? I'd like to (if possible) make the solution 'accessible' to screenreaders etc.

Thanks very much,
Prembo.

PS: I tried to implement some of the techniques - none of them worked properly: TextReplacement.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
        <title>Text Replacement by Image using CSS</title>
        <style type="text/css" title="currentStyle" media="screen">
            @import "TextReplacement.css";
        </style>
    </head>

    <body id="bodyId">
        <div id="centerContainer">
            <h1><span>Comparison of Various Techniques</span></h1>
            <p class="noteText">(NOTE: only text "Word1" is being replaced by image)</p>
            <div id="mainBodyContainer">
                <div class="techniqueContainer">
                    <h2>Technique 1: FIR</h2>
                    <ul id="t1List">
                        <li id="t1w1"><span>Word1.&nbsp;</span></li>
                        <li id="t1w2"><span>Word2.&nbsp; </span></li>
                        <li id="t1w3"><span>Word3.&nbsp; </span></li>
                        <li id="t1w4"><span>Word4.&nbsp; </span></li>
                    </ul>                    
                    <p class="techniqueComment">Word 1 and corresponding image disappear completely.</p>
                </div>

                <div class="techniqueContainer">
                    <h2>Technique 2: Radu</h2>
                    <ul id="t2List">
                        <li id="t2w1"><span>Word1.&nbsp;</span></li>
                        <li id="t2w2"><span>Word2.&nbsp; </span></li>
                        <li id="t2w3"><span>Word3.&nbsp; </span></li>
                        <li id="t2w4"><span>Word4.&nbsp; </span></li>
                    </ul>                    
                    <p class="techniqueComment">All disapppear completely.</p>
                </div>                

                <div class="techniqueContainer">
                    <h2>Technique 3: Rundle</h2>
                    <ul id="t3List">
                        <li id="t3w1"><span>Word1.&nbsp;</span></li>
                        <li id="t3w2"><span>Word2.&nbsp; </span></li>
                        <li id="t3w3"><span>Word3.&nbsp; </span></li>
                        <li id="t3w4"><span>Word4.&nbsp; </span></li>
                    </ul>                    
                    <p class="techniqueComment">No effect - image and text visible.</p>
                </div>    

                <div class="techniqueContainer">
                    <h2>Technique 4: Leahy/Langridge</h2>
                    <ul id="t4List">
                        <li id="t4w1"><span>Word1.&nbsp;</span></li>
                        <li id="t4w2"><span>Word2.&nbsp; </span></li>
                        <li id="t4w3"><span>Word3.&nbsp; </span></li>
                        <li id="t4w4"><span>Word4.&nbsp; </span></li>
                    </ul>                    
                    <p class="techniqueComment">Image appears above Word1.</p>
                </div>    

                <div class="techniqueContainer">
                    <h2>Technique 5: Dwyer</h2>
                    <ul id="t5List">
                        <li id="t5w1"><span>Word1.&nbsp;</span></li>
                        <li id="t5w2"><span>Word2.&nbsp; </span></li>
                        <li id="t5w3"><span>Word3.&nbsp; </span></li>
                        <li id="t5w4"><span>Word4.&nbsp; </span></li>
                    </ul>                    
                    <p class="techniqueComment">Word 1 and corresponding image disappear completely.  Same as Technique 1.</p>
                </div>                        
                <div class="techniqueContainer">
                    <h2>Technique 6: Jason</h2>
                    <div id="t6List" class="borderContainer">
                        <span id="t6w1">Word1.&nbsp; </span>
                        <span id="t6w2">Word2.&nbsp; </span>
                        <span id="t6w3">Word3.&nbsp; </span>
                        <span id="t6w4">Word4.&nbsp; </span>
                    </div>                    
                    <p class="techniqueComment">Same as Technique 3 - Rundle.</p>
                </div>     
            </div>
        </div>
    </body>
</html>

And the CSS File: TextReplacement.css

* {
    margin: 0;
    padding: 0;
}

body {
    margin: 0;
    padding: 0; 
    font-family: verdana, "trebuchet MS", helvetica, sans-serif; 
}

#centerContainer {
    margin-left: auto;     /* centres container */
    margin-right: auto; /* centres container */ 
    margin-top: 18px;
}

#mainBodyContainer {
    width: 900px;
    margin-left: auto; 
    margin-right: auto; 
    margin-bottom: 20px;
    font-size: 1.8em;
    font-weight: bold;    
}

#mainBodyContainer h2{
    font-size: 1.2em;
    font-weight: bold;    
    font-style: italic;    
    color: green;
}

div.techniqueContainer{
    text-align: center;
    margin-bottom: 30px;    
}

p.techniqueComment{
    font-size: 0.5em;
    font-weight: normal;    
    font-style: italic;    
    color: red;
}

p.noteText{
    font-size: 1em;
    font-weight: normal;    
    font-style: italic;    
    color: blue;
}

#mainBodyContainer ul{
    list-style: none;
    border: 1px solid #820000;
}

#mainBodyContainer ul li{
    display: inline;
}

/* TECHNIQUE 1: FIR */
li#t1w1 {
    width: 250px;
    height: 61px;
    background-image: url(http://stackoverflow.com/content/img/so/logo.png);
}

li#t1w1 span {
    display: none;
}

/* TECHNIQUE 2: Radu */
li#t2w1 {
    width: 2250px;
    height: 61px;
    background: url(http://stackoverflow.com/content/img/so/logo.png) top right;
    margin: 0 0 0 -2000px;
}

/* TECHNIQUE 3: Rundle */
li#t3w1 {
    width: 250px;
    height: 61px;
    background: url(http://stackoverflow.com/content/img/so/logo.png);
    text-indent: -9999px;
}

/*TECHNIQUE 4: Leahy/Langridge. */
li#t4w1 {
    width: 250px;
    padding: 61px 0 0 0;
    height: 0;
    background: url(http://stackoverflow.com/content/img/so/logo.png) no-repeat;
    overflow: hidden;
}

/*TECHNIQUE 5: Dwyer. */
#t5{

}

#t5List{
    list-style: none;
    border: 1px solid #820000;
}

#t5List li{
    display: inline;
}

li#t5w1 {
width: 250px;
    height: 61px;
    background-image: url(http://stackoverflow.com/content/img/so/logo.png);
}

li#t5w1 span{
    display: block;
    width: 0;
    height: 0;
    overflow: hidden;
}

/* TECHNIQUE 6: Jason */
li#t6w1 {

}

#t6w1{
    text-indent: -5000px; 
    background: url(http://stackoverflow.com/content/img/so/logo.png) no-repeat 0 0; 
    overflow: hidden;
}
Prembo
  • 2,256
  • 2
  • 30
  • 50
  • This is doable, no worries about that, but if you're doing this for a font's sake, why not check out something like Cufon? http://wiki.github.com/sorccu/cufon/about – dylanfm May 21 '09 at 07:08
  • I'd just like to add shadows/reflections to the text. But I wanted it to be able to use present the page differently for mobile screens (would use different images or simply the text). I started off placing the images in the HTML, but realised that is wasn't going to be a nice approach. – Prembo May 21 '09 at 07:19
  • why don't you use a separate stylesheet for mobile users? in your section: – Jason May 21 '09 at 10:02
  • That was exactly what I was hoping to do. And that is why I was keen to keep the presentation layer (ie the images) to the CSS files and keep the HTML content only. – Prembo May 22 '09 at 00:28

8 Answers8

4

It's easy:

span {text-indent: -5000px; background: url(../images/yourimage.jpg) no-repeat 0 0; overflow: hidden;}

Try it out. you'll see that it works.

Whatever you do, DO NOT USE JAVASCRIPT to achieve this effect. too easily done in CSS

You may also want to opt for an unordered list:

<ul>
  <li>word</li>
  ...
</ul>

ul {list-style-type: none; margin: 0; padding: 0;}
li {list-style-type: none; float: left;}
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Jason
  • 51,583
  • 38
  • 133
  • 185
  • This method has a serious drawback. Visitors with CSS enabled but images turned off won't see neither the text or the image. – viam0Zah May 21 '09 at 09:06
  • 2
    what percentage of your visitors has that combination? if it's a lot, don't do it. but if it's like 99.999% of the internet, it's a valid solution. more people have javascript turned off than have images turned off. – Jason May 21 '09 at 09:27
  • @Jason: an increasing number of visitors have images turned off. Think about mobile internet when user pays after the downloaded data. – viam0Zah May 21 '09 at 09:33
  • 2
    @Torok - you think they have CSS turned on too? Any user that knows how to turn their images off on their phone probably knows how to turn their CSS off too... a lot of CSS has to do with images, so turning your images off is going to make a CSS-based page look, well, bad. if the 1% of the people viewing my site don't want to look at my sub 10k images, so be it. why spend 80% of your time writing cases for 1% of the viewers? it's not very business-minded... – Jason May 21 '09 at 09:59
  • @Jason: Ok, I'm not trying no convince, it's a matter of view. Why should they disable CSS? If a CSS-based site without images collapses, well, that qualifies the site builder. Otherwise, it's interesting you're talking about business focus and throwing away one percent of your visitors so easily. Anyway, I just wanted to point out a pitfall, mind it or not. – viam0Zah May 21 '09 at 10:08
  • 4
    @torok unless you're building a site for yourself where time isn't an issue, you can't dawdle on features that affect a very small percentage of your viewers. time is money, and if 80% of your CSS time is spent writing and debugging specialized CSS code for a certain browser or platform that only 1% of the people use, you're wasting both. in a perfect world, yes, we want to be accessible to everyone, but sometimes you have to draw the line. – Jason May 21 '09 at 19:16
  • in addition to the above, if this guy is writing code that is going to be viewed PRIMARILY by screen readers, etc, then he should absolutely take the time to make it work :) – Jason May 21 '09 at 19:18
  • @Jason I tried the method described (see technique #6 in sample code) but unfortunately it didn't work. Am I missing something? Thanks guys... – Prembo May 22 '09 at 00:44
  • maybe try putting "display: block" in there and then float them left (float: left;). – Jason May 22 '09 at 21:16
4

Did you mean keep the HTML as is, but show an image instead of the text? If so, it can be done like this:

#word1 {
   display:block;
   width:100px; /* width of image */
   height:80px; /* height of image */
   background:url(image.jpg) top left no-repeat; /* sets image as background of span */
   text-indent:-999999px; /* this hides the text so the image is not obstructed */
}

Now the text stays and it SEO friendly but it can look impressive with fancy images.

Matthew James Taylor
  • 4,806
  • 5
  • 29
  • 33
  • @Matthew. Thanks for your response. This looks like the Rundle technique. Unfortunately, it doesn't work as I'd like as doing display:block; makes the text or images not appear inline. Have a look at technique #3 & 6 in the sample code. Only difference is display:block; – Prembo May 22 '09 at 00:57
  • @Prembo You can easily use float:left; to put all the blocks horizontally across the page. – Matthew James Taylor May 22 '09 at 04:52
2

Hi I prepared a test page cca a year ago on this problem but I link this just for interest because of the fact it causes a tag soup plus can face with the "images turned off" problem. Its pure CSS.

Update: It was designed for repeated images so this is not a one piece image replacement technique.

yaanno
  • 211
  • 1
  • 5
1

I personally prefer the Rundle text-indent technique because it's simple and elegant with no extra markup. If you change the display to inline-block it will work for you. For the browsers that don't support inline-block, use one of the techniques here: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/ (check the comments too, there are some simpler suggestions there). I agree with @Jason that crafting a complicated solution for this just to cover for people with css enabled and images disabled is probably overkill.

gterez
  • 106
  • 5
1

What is your original idea? What do you want to achieve? If you want to show images to your visitors, simply use the proper IMG tag for that and attach the words to the ALT attribute.

Otherwise, if these images are really not content images but part of the presentation layer, then I'm afraid you choose the wrong markup. SPANs have no semantic meanings. You'd rather choose an unordered list which you can design as you wish.

Edit

Okay, according to your response, you really want a solution in the presentation layer. You can choose the standard CSS2 property text-shadow for the shadow effect. It works in Safari, Opera, and Konqueror, and for the remaining browsers, you may use some JavaScript.

(SPAN is a simple container element that you can apply styles on.)

viam0Zah
  • 25,949
  • 8
  • 77
  • 100
  • That's interesting Török. You're right the images are part of the presentation layer. The plan was to use the images to replace the words so that I could have shadows/reflections of the text. I didn't want to use because I wanted the page to present differently (different images or maybe text only) on different media. I originally thought was appropriate because the words lent themselves more to a sentence rather than a list of words. What do you mean by "SPANs have no sematic meanings"? – Prembo May 21 '09 at 07:27
  • = unordered list, semantically.
    = division of the page, semantically.
  • = list item, semantically. = well, nothing, semantically.
– Jason May 21 '09 at 09:04