44

Let's say I have this element for displaying the website logo:

<div id="web-title">
  <a href="http://website.com" title="Website" rel="home">
    <span>Website Name</span>
  </a>
</div>

The #web-title would be styled with background:url(http://website.com/logohere.png), but how to properly hide the text Website Name? As seen here: Hide text using css or here https://stackoverflow.com/a/2705328 , I've seen various methods to hide the text, such as:

#web-title span { text-indent: -9999px; }

or

#web-title span { font-size: -9999px; }

or

#web-title span { position: absolute; top: -9999px; left: -9999px; }

I've also seen some combine those three methods. But actually which one is the best practice to hide text effectively?

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
deathlock
  • 2,756
  • 5
  • 27
  • 48
  • 2
    how about display: none? – F. Müller Oct 08 '12 at 14:10
  • **Not constructive:** As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or specific expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. – Florent Oct 08 '12 at 14:11
  • Ain't no smart ass, but can't you just put an image tag instead? I'm just a practical person who doesn't like ugly ad-hoc solutions. maybe I'm wrong – Mark Segal Oct 08 '12 at 14:11
  • I would say that it depends on if you want the text (that isn't there) should take up the place it originally has. – Alfred Larsson Oct 08 '12 at 14:11
  • It's called image replacement, and the idea is to keep your html semantic (images that are decorations in the CSS). – coopersita Oct 08 '12 at 14:23
  • 1
    Here's a list of most image replacement techniques, their pros and cons: http://css-tricks.com/examples/ImageReplacement/ – coopersita Oct 08 '12 at 14:36
  • 1
    more up-to-date roundup of techniques: https://css-tricks.com/the-image-replacement-museum/ – ptim Feb 09 '17 at 00:05

12 Answers12

80

Actually, a new technique came out recently. This article will answer your questions: http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement

.hide-text {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

It is accessible, an has better performance than -99999px.

Update: As @deathlock mentions in the comment area, the author of the fix above (Scott Kellum), has suggested using a transparent font: http://scottkellum.com/2013/10/25/the-new-kellum-method.html.

coopersita
  • 5,011
  • 3
  • 27
  • 48
  • This is great. How'd you discover this? – Danger14 Apr 18 '13 at 19:17
  • @Danger14 Can't remember, but since it was posted on Zeldman's site, a bunch of people must have been commenting on it on blogs, and Twitter. – coopersita Apr 19 '13 at 21:39
  • I've been revisiting this question, and found other hack by Nicolas Gallagher, and a comparison between Zeldman's and Gallagher's here: http://www.css-101.org/articles/image-replacement/the_new_new_image-replacement_techniques.php What do you think? – deathlock Jul 26 '13 at 20:23
  • 1
    Another method using clip:rect(): http://developer.yahoo.com/blogs/ydn/clip-hidden-content-better-accessibility-53456.html – thdoan Aug 29 '13 at 03:05
  • 2
    Just updating: what about the New Kellum Method? http://scottkellum.com/2013/10/25/the-new-kellum-method.html – deathlock Nov 05 '13 at 06:40
  • You should post an answer with that, @deathlock. Thanks! – Lars Gyrup Brink Nielsen Feb 27 '14 at 09:46
  • The only downside of this answer is, that Google Chrome will find the hidden text and bring it into view http://puu.sh/9eran/4be205d507.png. So does Safari http://puu.sh/9erct/89373c8e00.png. However Firefox does not do it. – Patrik Affentranger Jun 04 '14 at 08:55
  • 1
    It will destroy your table cells if you do `text-indent: 100%`. – Daniel Kmak Mar 21 '15 at 11:04
  • This didn't work for me - did something change? It has been several years ... – ProsperousHeart Dec 23 '22 at 20:53
19

you can simply make it transparent

{
   width: 20px;
   height: 20px;
   overflow: hidden; 
   color:transparent;
}
Yukulélé
  • 15,644
  • 10
  • 70
  • 94
  • +1 this works great if you have a link that you need to still be active. I used this to get rid of numbers on an old image slider and the links work fine. – Dan Beaulieu Feb 09 '15 at 21:28
  • This is the solution that ended up working for my needs. I have a button which has a graphic via the css background-image property and on mobile devices I wanted to collapse the button down and hide the text. – Brad Johnson Mar 21 '15 at 02:56
6

Can't you use simply display: none; like this

HTML

<div id="web-title">
   <a href="http://website.com" title="Website" rel="home">
       <span class="webname">Website Name</span>
   </a>
</div>

CSS

.webname {
   display: none;
}

Or how about playing with visibility if you are concerned to reserve the space

.webname {
   visibility: hidden;
}
Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
  • 7
    Display:none has very bad implications for people using screen readers. It's a big accessibility no-no. – coopersita Oct 08 '12 at 14:19
  • When you hide material from visual display on a PC screen, you almost always hide it from screen readers too http://css-discuss.incutio.com/wiki/Screenreader_Visibility – Dipak Oct 08 '12 at 14:28
  • 1
    @Mr.Alien: I believe it's because screen readers that respect CSS will plain skip over the undisplayed elements. You don't want this to happen for headings. Basically, you want to hide the text from not-screen-readers only. – millimoose Oct 08 '12 at 14:28
  • Because you are removing the text, an replacing the text with an image that blind people can't see (and no alt for the screen reader to read). At least with -9999px the text is still there (off screen), so screen readers will read it. – coopersita Oct 08 '12 at 14:28
  • 3
    but what's the use of reading a text which actually you want to hide, and if you really want that it should be readed out than why to hide? and where this user has said that he wants a reader compatible solution? – Mr. Alien Oct 08 '12 at 14:30
  • 3
    He didn't say he wants screen readers, but he asked what's best practice. Providing good accessibility is the proper way of doing things. Imagine he devastating it would be for screen readers if you did this to your logo and menu items. – coopersita Oct 08 '12 at 14:46
  • @coopersita agreed if it's menu or the content, but it's a logo here :) – Mr. Alien Oct 08 '12 at 14:47
  • 1
    @Mr.Alien The logo would be replacing the text showing the name of your site. There is a reason that's usually placed first on a page... Most people want to know in what site they are... – coopersita Oct 08 '12 at 14:51
  • @coopersita For that you've something like `@media braille` ;) – Mr. Alien Oct 08 '12 at 15:00
3

the way most developers will do is:

<div id="web-title">
   <a href="http://website.com" title="Website" rel="home">
       <span class="webname">Website Name</span>
   </a>
</div>

.webname {
   display: none;
}

I used to do it too, until i realized that you are hiding content for devices. aka screen-readers and such.

So by passing:

#web-title span {text-indent: -9000em;}

you ensure that the text still is readable.

Mark
  • 6,762
  • 1
  • 33
  • 50
  • That is bloody brilliant. Was stuck on a problem where i wanted to hide some parts of the ajax file uploader, such as the dropzone and some text in StatusContainer. This little hack did the trick. – Mana Apr 13 '15 at 14:47
2

Add .hide-text class to your span that has the text

.hide-text{
display:none;
 }

or make the text transparent

.hide-text{
 color:rgba(0,0,0,0);
 }

use according to your use case.

Dhruv Batheja
  • 2,140
  • 1
  • 18
  • 16
  • As others have said, `display: none` has a very bad implication for screen reader. http://stackoverflow.com/a/12783474/651170 – deathlock Jul 03 '16 at 14:09
0

If you're willing to accomodate this in your markup (as you are in your question with the holding the text), I'd go with whatever jQuery UI went with in their CSS helpers:

.ui-helper-hidden-accessible { 
    position: absolute !important; 
    clip: rect(1px 1px 1px 1px); 
    clip: rect(1px,1px,1px,1px); 
}

The image replacement techniques are good if you absolutely refuse to add extra markup for the text to be hidden in the container for the image.

millimoose
  • 39,073
  • 9
  • 82
  • 134
0

What Google(search bot) needs is same content should be served to bot as it is served to user. Indenting text away (any text) gets bot to think it is a spam or you are serving different content to user and bot.

The best method is to directly use logo as an image inside your anchor tag. Give an 'alt' to your image. This will be perfect for bot to read & also will help in image searching.

This is straight from the horse's mouth: http://www.youtube.com/watch?v=fBLvn_WkDJ4

Neeraj
  • 132
  • 7
0

As of September of 2015, the most common practice is to use the following CSS:

.sr-only{
    clip: rect(1px, 1px, 1px, 1px);
    height: 1px;
    overflow: hidden;
    position: absolute !important;
    width: 1px;
}
Joel Kinzel
  • 969
  • 2
  • 7
  • 19
  • 2
    According to MDN the clip property is now deprecated. https://developer.mozilla.org/en/docs/Web/CSS/clip – chap Jan 08 '16 at 00:09
0

I do it like this:

.hidden-text {
  left: 100%;
  display: inline-block;
  position: fixed;
}
isapir
  • 21,295
  • 13
  • 115
  • 116
0

Another way

position: absolute;
top: 0px;
left: -5000px;
atazmin
  • 4,757
  • 1
  • 32
  • 23
0

It might work.

.hide-text {
    opacity:0;
    pointer-events:none;
    overflow:hidden;
}
en0ndev
  • 673
  • 1
  • 7
  • 19
-2

I realize this is an old question, but the Bootstrap framework has a built in class (sr-only) to handle hiding text on everything but screen readers:

<a href="/" class="navbar-brand"><span class="sr-only">Home</span></a>
Jim T.
  • 69
  • 4