views:

1320

answers:

7

Hi,

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"&gt;
<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;
}
+1  A: 

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.)

Török Gábor
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 <IMG> because I wanted the page to present differently (different images or maybe text only) on different media. I originally thought <SPAN> 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
<ul> = unordered list, semantically. <div> = division of the page, semantically. <li> = list item, semantically. <span> = well, nothing, semantically.
Jason
+1  A: 

Have no semantic meanings: Spans add no meaning to the content (just like divs), so they are probably the right element to use for what you want to do.

Make the span display as a block and float it:

span { display: block; float: left; }

Thomas Maas
+1  A: 

Use jQuery to replace relevant element's text with the images. Images are inline, so they will go with the flow.

Antony Carthy
+2  A: 

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
This method has a serious drawback. Visitors with CSS enabled but images turned off won't see neither the text or the image.
Török Gábor
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
@Jason: an increasing number of visitors have images turned off. Think about mobile internet when user pays after the downloaded data.
Török Gábor
@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
@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.
Török Gábor
@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
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
@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
maybe try putting "display: block" in there and then float them left (float: left;).
Jason
+1  A: 

One technique I've used with great effect is to essentially push the text out of the displayable area. Not sure if it has a name, and it always requires tailoring but essentially it's:

height: {someHeight};
line-height: {someHeight x 3};
overflow: hidden;
letter-spacing: -1.1em; /* roughly */

The first line leaves a height for the element, the second pushes the text beyond that height (font-size depending, x3 is just a good starting point), the third hides it from display and the last nukes the width of the text.

annakata
+2  A: 

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
@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
Prembo
@Prembo You can easily use float:left; to put all the blocks horizontally across the page.
Matthew James Taylor
+2  A: 

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