CSS Generated Content

tagged as css

We’re going to look at when to use CSS generated content and when not to. CSS generated content? Yep, you read that right. It’s a real thing. A pretty awesome thing too, honestly. What it enables web designers and developers to do is pretty swanky and [can be] pretty helpful to boot.

So what do I mean when I say CSS generated content? Well, it’s somewhat complicated, so lemme try to break it down. CSS generated content is a technique that allows content (HTML and/or images) to be inserted into the DOM without actually being included in the HTML. Say what? A bit odd, but basically if you view the source of a page using this, you won’t find the corresponding code in the HTML. It’s being added in via CSS, and therefore is usually considered just for presentational purposes.

For this, you, or whomever, will be using pseudo elements of :before and :after, relating to a particular elements normal styling. For example (just a stupidly simple example):

<style type="text/css">
  * {
    padding:0;
    margin:0;
  }
  body {
    padding:50px;
    text-align:center;
    width:500px;
    margin:0 auto;
    font-family:sans-serif;
    line-height:1.5;
  }
  h1 {
    font-size:40px;
    text-transform:uppercase;
  }
  h1:after {
    content:"Wowzers!";
    display:block; /* optional depending on what you want to do with this */
    color:blue;
    font-size:40%;
    text-transform:none;
    padding:10px 0 40px;
    opacity:.5;
  }
  p {
    text-align:left;
  }
</style>

View Demo

So after all this, we have the <h1> with This be a headline. and right after we have Wowzers!. But it’s no where in the HTML markup (and, assuming this was coded normally, no where on the page at all). We specified this in the CSS, and then using some CSS trickery we rendered this in HTML. It’s not really rendered in the HTML, it’s just visually there. That leads into the next section, but for now let's focus on what else we can do. Right now this content is static, and we’d have to go into our CSS every time we wanted to change this. So, what’s a better way to do this then? Enter HTML5. With HTML5 we can specify new attributes for any element by prefixing it with data-. So let’s create one called data-info on a new div.

  <div data-info="This be some info."></div>

And add this CSS:

div:after {
  content:attr(data-info);
  display:block;
  margin:40px 0;
  font-weight:bold;
  text-align:right;
  opacity:.5;
}

Then, the content in this new attribute will be displayed when we view this in our browser. Right now this is still static, but if you’re site is running on a server-side language, or even with some JavaScript, this can become dynamic and able to change on the fly, or if you’re rendering multiples of these elements. A popular trend, or technology perhaps (and something I really love!), is something called icons fonts, and most of these work the same way as this. I blogged more on Icon Fonts and CSS generated content a few weeks ago too.

Okay, so now we know what I’m talking about, why?

Because it’s awesomesauce, right? Well yes, but that’s not a good reason to do something on it’s own. So what are some creative ways we can use this? The number reason I can think of is for optimizing for page load time. With some creativity and a bit o’ gumption, we can often replace extra images with some generated content. A prime example was a simple interface I just worked on for Google Chromebook (see image below). The design comps called for a circular icon with a ‘i’ in it to signal ‘hey, this is some important info’. Rather than create another image and require another http request, this was done simply with generated content. Plus, since most often these will be using HTML content, they are resolution independent, which is becoming more and more important as more retina (or high-res) screens become more ubiquitous.

Example of the Goolge site using CSS generated content.

Another reason to use this might be to add in content to a page dynamically that is not important enough to be in the HTML, or important enough for SEO purposes, but still helps users visually. Kind of like how microcopy helps users get through forms and other non-linear tasks in an app, dynamic CSS generated content can also help out here. I can imagine using this technique with e-commerce site and in particular a product page. For example, for a site that sells different colors of a product, a lot of times the image is shown with a radio button below, or some other method selecting it. If the site has been setup properly, the image has an alt tag with a good description of the color for screen readers and spiders. This is great, but using CSS generated content, we can perhaps add a bit more useful info for the rest of us, not to mention the color blind. All we’d need to do is to add in a data-color attribute to the HTML likes:

<div class="samp" data-color="Red -- hex color #d0272c">
  <img width="50" height="35" alt="color-red" src="color-red.png" class="samp">
  <br />
  <input id="foo" type="radio" checked="checked" value="foo" name="foo">
  <br />
</div>

And add some CSS:

.samp:after {
  content:attr(data-color);
  display:block;
  font-size:11px;
}

And there we have it. It’s a little bit extra to help massage the user in their selection process, but it’s not required for screen readers or spiders (as this content in already in the image alt tag). Another way to use this I’ve seen done often is in print stylesheets to include an iteration of the actual URL for a link. Obviously, a printed page won’t be clickable (although some people still struggle with this…), so it's nice to be able to include the URL that was linked in the printout, or PDF, as well. So, how would we do this? Simple:

View Demo

a:after {
  content:attr(href);
  font-size:10pt; /* for easy reading */
}

On the other hand, using generated content to render a design element that’s too complicated to just be HTML is another great reason for going this route. Say you have a design comp that calls for some sort of crazy border, or design or whatever, that is to follow all articles on a page. Rather than hard-coding these in (either in a static site, or with dynamic scripting), using CSS generated content is a better way to do this, for a few reasons. There are no extra images or empty HTML elements inserted to the page, and thus there is less HTML to be downloaded, always a good thing. Okay, how do we do this now?

.reused-design:after {
  content:url(facebook-icon.png); /* your image URL */
  display:block;
  height:50px; /* can be any size */
  width:50px; /* can be any size */
  margin:10px auto; /* can be anything */
}

View Demo

Pretty slick stuff, right?

This isn’t even the half of it. In terms of purely styling a page, there’s tons of great examples out there that other folk have posted. However, I think we really need to push ourselves to really use the dynamic ability of this technique to add more beneficial content / location-aware content to our apps whenever possible.

Some resources:

For IE7 & those poor saps using IE6

We can just use a jQuery (or just Javascript) polyfill to faux generate this content, as these browsers don’t understand these pseudo elements. For example:

$(function(){
  var elements = $('#closest_id_to_elements').find('elements');
  // find all elements that match
  elements.after('<div class="some-name"></div>');
  // add a new div after these & style them
  // if you want to add in data-* info, that's party simple too
  elements.after('<div class="some-name">'$(this).data('whatevs');'</div>');
});

As an aside: I started out by saying what was & wasn’t possible

Technically, anything is pretty much possible with generated content. Some animations and other crazy CSS3ness might not be greatly supported yet, but I suspect that will change. However, I was referring more to the content itself, and not what can be done with it. As I’ve referenced Spiderman before, with great power comes great responsibility. So, yes, you can add in almost any kind of content with these techniques, but as usual, always keep the user in mind. If the information is critical for your business or for general SEO purposes, don’t do it. If it’s just glitter on the icing on the cake, then by all means, have at it.


Mused on July 20, 2012


© somewhere through 2014

head home view some work read some thoughts jeff on twitter check my résumé

© 2014

hide