• 200808 Feb

    While thinking about suggestions for new features wanted in CSS3, my mind strayed onto image replacement methods. At the moment we have a cornucopia of methods, none of which resolves the style on/images off problem without extra markup (I’m referring to CSS-only techniques).

    CSS3 should be able to solve this problem for us, shouldn’t it? Isn’t that what it’s for? My initial idea was to suggest a pseudo-class that detected whether or not images were disabled and changed the content accordingly; something like:

    h1 {
    background-image:  url('image.png');
    text-indent: -9999px;
    }
    
    h1::no-images { text-indent: 0; }

    After doing a quick search, I found out that a solution has already been proposed, and it is much more elegant than mine! It uses the content declaration to replace the content, with a fallback option given after a comma:

    h1 { content: url('image.png'), contents }

    On the unofficial CSSWG wiki, the idea has been taken even further and the require-font function added; using this will allow you to instruct the browser to use a required font if available, download it if not, display an image if that’s not possible, or display in the fallback font style if none of the previous apply:

    h1 { 
    content: require-font('FF Meta Serif'), url('image.png'), contents;
    }

    A very neat solution! The drawback? Although accepted, this is not in the Generated and Replaced Content draft yet; and the module has been assigned a low priority.

    You can skip to the end and leave a response.


  • Comments

    • 01.

      I do not think much about replacing content with images. (Would there even be any need if fonts could be embedded in the stylesheet?) But this method would be far better than the existing hacks.

    • 02.

      Opera has supported CSS3 content on all elements for years. It is very nice actually.

      It works in Safari 3 now too, at least for image replacement.

    • 03.

      That IS very very nice Peter!

      @Daniel: well yes I would think there would be a need, for instance to replace a company’s logo with plain text in the source of the HTML.

    • 04.

      @ Lars: Opera does support ‘content’, but doesn’t seem to support the ‘url’ function; whereas Safari does support the ‘url’ function, but not text string or ‘contents’ fallback – according to the very simple tests I’ve just run, anyway.

      Sorry, both support the ‘url’ function, but neither seems to support the ‘contents’ fallback.

    • 05.

      I like the content idea a lot, it allows for greater accessibility whilst maintaining old the H1 branding which has become so important for SEO.
      I am a little concerned about downloading fonts though; surely this could become an abused feature of the language, opening up browsers to potential security issues i.e. virus-infected fonts?

    • 06.

      @ Steve Workman: I can’t find the article I read now, but the risk of infected font files is apparently very low; add to that the fact that you’ll be able to disable font downloading, and a good antivirus should be able to check if you do enable it, and it’s no more risky than downloading any other file from the web. In theory, viruses can be hidden in JPG and SWF files, but nobody worries about those!

    • 07.

      All image replacement is bad all the time.

      Discuss.

    • 08.

      I don’t agree John. Image replacement is a fine way of creating an accessible site whilst providing good looks too.

    • 09.

      Joost,

      How does one zoom image based text for legibility (other than on Opera and the mobile Safari)?
      When one does, what happens to the relative sizes of heading versus other text?

      From a practical development and maintenance point of view, what happens when we want to change the appearance of IR’d text? Add new IR’d text (you did save all of those image editing application setting right? Edit misspelled IR’d text?

      How does SIFR work on the iPhone?

      Once upon a time (2004), it was *arguable* that IR techniques were required to meet the needs of designers with clients who didn’t understand the point of the web (it’s NOT going to look the same everywhere, the fact that users and user agents can adapt your content is a feature not a bug). Now, it is a complete anachronism. And the idea that the development of CSS3 should in any way pay any attention whatsoever to enabling IR is AFAIK, utterly wrong headed.

      If developers want to use the technique, that’s their decision If standards developers want to entrench it, then IMO that’s simply wrong.

      j

    • 10.

      @ John Allsopp: IE7, Opera, FF3 all now support full page/scalable zoom (not sure about Safari), so that’s not so much of a problem (and with SVG images it will be a non-issue).

      As for updating IR’d text, that’s up to the developer to make the decision of whether it’s a good idea or not (probably not if you’re handing the site off to a client).

      You could argue that quite a lot of the features of CSS shouldn’t be used because they could be used badly, but that’s obviously not a logical course of action.

      IR is common, and it’s a useful tool in the armoury, so it’s right that it should be made a standard rather than forcing workarounds.

    • 11.

      So, what I don’t get about image replacement, is why? You want to have an image stand for some text. Fine, here’s my markup:

      <h1><img src=”blah.jpg” alt=”Welcome to Blah Blah!”></>

      Is this not close enough to the correct semantic meaning? Certainly just:

      <h1>Welcome to Blah Blah!</h1>

      Is exactly what we want, but by adding the image tag we are only depositing *extra* meaning. We are saying now, that the heading is still “Welcome to Blah Blah!” (thanks to the alternate text), but additionally is also a raster graphic. Clients that support raster graphics display it, clients that do not, display the alternate text.

      Isn’t that the end? What more do you need?

      Oh, you want a hover effect? OK, here you go:

      h1 {
      background-image: url(blah-hover.png);
      }
      h1 > img:hover {
      visibility: hidden;
      }

      Want a little title hover box?

      <h1 title=”Titles, ha ha!”>…</h1>

      Certainly, if we must support IE5, I don’t even need to be having a semantic meaning argument. If we need to support IE6, most of this will still work (I believe you lose the title?).

      No matter how poor IE7 is, I’m still pushing hard here for people to use it over IE6. Not so much because I need what IE7 has to over over IE6 (ha ha!), but rather because I want to encourage users to break the yoke of non-change with their browser — get them to upgrade today, and they are more likely to upgrade later too.

      Ah, but now I’m digressing.

      I stand by my question, why? All of these “techniques” to me seem to be just fancy ways of saying, “I’m not satisfied with alternate text, I want something… alternate”. Most want the image to be more alternate than the text, but yet still make the image displayed by default. Isn’t that a contradiction? Which is it, the image or the text? I thought it was the image. It’s an image that represents some text.

      Don’t be ashamed about that. Be ashamed that we can’t just use proper font files, but don’t be ashamed of working with what you have. Besides, you’d still need this if you want display a logo with text. (Blah blah, SVG, blah blah text over an image, yes I know).

      Anyway, it’s horribly early in the morning. Sorry if I’m rambling and incoherent — at least I have a spell checker.

      -Adam

    • 12.

      @ Adam Luter: I edited your comment to fix the code; let me know if I’ve done anything wrong there.

    • 13.

      If CSS3 allowed for a bullet proof solution to image replacement, it would put to rest the variety of image replacement flavors that currently exist. As an eduator, it is difficult in deciding which flavor(s) to promote. With that said, I have worked up a new flavor and would like to share with this commnity:

      http://www.wedelivery.com/du-jour/image-replace/

    • 14.

      Maybe this is a little bit off-topic but this article reminded me of this: I always thought that the “img” tag needed a redesign. It should work like the “object” tag: if a user-agent can’t display the object, it will fall back to the stuff enclosed in the object tag (instead of using an “alt” tag for text-only). E.g. you can make an SVG object and if the browser can’t display SVG files, it will display a raster image enclosed in the object tag instead.

      That way we could easily get more acceptance for newer and less-known formats, for example the virtually unsupported MNG format: if the UA can’t display MNGs, it will show an animated GIF instead, and if GIF animations are disabled in the browser, it could even fall back to a static image.

      Sorry for being a bit off-topic, but does anybody have thoughts about this too?

    • 15.

      Marcus: that makes me think that APNG relies on a “hacky” format in order to be backward compatible (which is why the PNG group rejected it), something which wouldn’t have been necessary if we had proper ways to define fall backs in the page codes, rather than encrypted inside images, in this case.
      I think they wanted to get rid of the img tag for XHTML 2.0, and rely on object instead, as you suggested…

    • 16.

      @Marcus
      Why wait? You can already now use the ‘object’ element instead of ‘img’ if you want.

      @Stifu
      From Wikipedia:
      “APNG uses a technically feasible solution for storing any frames except the first, but the majority of the PNG group thinks this conflicts with the purpose of the PNG format – which is to store a single image. APNG would be compatible to this vision with alterations to its signature and intended MIME type, but these would break the desired backwards compatibility.”
      Am I missing something, or couldn’t you just do something like

      Sure, it would require more markup, but it would still be ‘backwards compatible’, wouldn’t it?

    • 17.

      Trn: your code got eaten, I take it you were using the object tag?
      I had to deal with the object element at work last year (not for images though, but to replace an iframe), and noticed IE had problems with it, so had to revert to the iframe after all…
      If IE has poor support for the object element, that may explain why people stayed away from using it as a replacement for the img tag.

      A quick test seems to confirm that. I tried the code shown there: http://www.w3.org/TR/html401/struct/objects.html#h-13.1
      It worked with Firefox, but not with IE6.

    • 18.

      The object problem wasn’t fixed in IE7, unfortunately, so it still displays images with a huge border around them, and scrollbars; not ideal.

    • 19.

      Una propuesta de reemplazo de imágenes en CSS3…

      Parece ser que existe una propuesta para realizar reemplazos de imágenes de una manera "limpia" mediante la futura especificación de CSS3…

    • 20.

      [...] CSS3′de metin yerine resim koyma metodu. CSS3 ile her şey daha iyi olacak. Bağlantı [...]

    • 21.

      Hm. Does the content method replace the text that is in the element? Does it remove the text and insert the image? How would a screen reader handle that?

      Has there been any talk of a foreground-image property? I can think of some cool things to do with that off the top of my head some of them requiring multiple foreground images. Would the content method allow for that?

      My primary use for image replacement at the moment is displaying a different set of images to mobile users than to desktop users and (hopefully) preserving the text for people with images turned off or screen readers. The content method would achieve the first goal but does it achieve the second two? Would I have to duplicate the fall back text for each device in their targeted style sheets?

    • 22.

      Stephanie, keyword “contents” (without quotes) substitues element’s content itself (i.e. nothing changed). So you need to specify “fallback” text only once – in HTML code itself. If that’s what are you asking.

    • 23.
    • 24.

      so does “contents” refer to whatever is between the h1 tags, or do you have to actually write out what you want to display if the image were not available or turned off?

      this sounds like a neat feature, despite the low-priority.

    • 25.

      @ Mike: Yes, ‘contents’ refers to the content contained in the h1 tag.

    • 26.

      Perhaps, better way – just look at the side of “web fonts” in the css3?
      I can’t understand why some one may want use image instead of text.

    • 27.

      @Raven – Just having better fonts won’t stop people from wanting image replacement. What about company logo’s? Shouldn’t there be text backing that? Maybe a logo can’t be represented in any format besides a jpg/png properly. (Mabye it’s — shudder — animated!).

      But as I suggested, why is the alt=”" in a standard IMG so shunned? Are we trying to over engineer a solution? Certainly using an OBJECT tag would be best, since the “alt text” in it is arbitrary markup. But IE (even 7) totally botches this approach.

      Which brings me to a question, OBJECT is mainly botched because IE is handling them itself, but it’s really a trigger for ActiveX controls. Could we write a small ActiveX control that displays images and use the classid to trigger it over the default image handler (the one that puts it in a little iframe-like sub-window for us)?

      At worse, you’d have to put the image a second time in a second inner object tag (for the rest of the browsers). But maybe you can pull it off with one.

      Another caveat is performance, perhaps it will render fine, perhaps it will not. But, if it’s only for a few images on the page, hopefully it may still be useful.

      (This is IE afterall, we are working with little to begin with!)

      -Adam

    • 28.

      What about a foreground-image that sits on top of the text node and has the same options as background-image. I think this would be a nice solution to image replacement.

    • 29.
    • 30.
    • 31.
    • 32.

Hosting by: