Search code examples
htmlcsscss-content

How to replace HTML text with images using CSS content cross browser


So I have a navigation menu that is generated by my CMS:

enter image description here

The menu's HTML is straightforward (edited for clarity):

 <ul>
     <li><a href="...">Journal</a></li>
     <li><a href="...">Art</a></li>
     <li><a href="...">Work</a></li>
   </ul>

I want the items to show up as hand-written text, in keeping with the general theme of the site, using separate PNG files for each menu item.

To do that, I used the CSS content property like so:

#headerNav .nav li a[href="/_site/en/journal/"]  
 { content: url(/path/to/image.png); }

And it worked great! The HTML text of each item was replaced by the correct image:

enter image description here

However, alas, then I learned not every browser supports the content property on selectors other than :before and :after! Chrome and Safari do it, but Firefox doesn. However when I use :before, the HTML node isn't replaced, but the image is added:

enter image description here

How do I work around this?

What didn't work:

  • Making the <a> element display: none removed the :before part as well.
  • Making the <a> element position: absolute and moving it elsewhere won't work either.
  • Making the <a> element width: 0px screws up the layout because the images added through content aren't in the document flow.

What I don't want to do:

  • Of course I can output the images by hand but I want to work with the HTML the CMS is giving me, which is <li>s with text in them.

  • Any solution involving background-image would require me to specify each item's width and height in the style sheet, which I would like to avoid for the purposes of this question.

  • Turning the handwriting into a font is not an option.

  • Using JavaScript to replace the items on the fly is not an option. This needs to work using pure HTML and CSS.


Solution

  • Since you are doing this into a navigation bar you should have a fixed height making the next method possible to work:

    • First insert the image as content on the :before element and make it display:block to push the actual text of the a tag below.

      li a:before {
         content:url(http://design.jchar.com/font/h_1.gif);
         display:block;
      }
      
    • Then hide that text with a fixed height on your a tag:

      li a{
         height:50px;
         overflow:hidden;
      }
      

    The Working Demo