How to Repeat Text as a Background Image in CSS Using element()

Avatar of Ollie Williams
Ollie Williams on

There’s a design trend I’ve seen popping up all over the place. Maybe you’ve seen it too. It’s this sort of thing where text is repeated over and over. A good example is the price comparison website, GoCompare, who used it in a major multi-channel advertising campaign.

Nike has used it as well, like in this advertisement:

Diggin’ that orange! (Source)

I couldn’t help but wonder how I would implement this sort of design for the web. I mean, we could obviously just repeat the text in markup. We could also export the design as an image using something like Photoshop, but putting text in images is bad for both SEO and accessibility. Then there’s the fact that, even if we did use actual text, it’s not like we’d want a screen reader speak it out.

Versatility
Versatility
Versatility
Versatility

OK, stop already!

These considerations make it seem unrealistic to do something like this on the web. Then I found myself pining for the long-existing, yet badly supported, element() feature in CSS. It enables the use of any HTML element as a background image, whether it be a single button element, or an entire <div> full of content.

According to the spec:

The element() function only reproduces the appearance of the referenced element, not the actual content and its structure. Authors should only use this for decorative purposes.

For our purposes, we’d be referencing a text element to get that repeating effect.

Let’s define an ID we can apply to the text element we want to repeat. Let’s call it #thingy. Note that when we use #thingy, we’ve got to prefix the element() value with -moz-. While element() has been supported in Firefox since 2010, it sadly hasn’t landed in any other browser since.

.element {
  background-image: -moz-element(#thingy);
}

Here’s a somewhat loose recreation of the Nike advertisement we saw earlier. Again, Firefox is required to see the demo as intended.

See how that works conceptually? I placed an element (#versatility) on the page, hid it by giving it zero height, set it as the background-image on the body, then used the background-repeat property to duplicate it vertically down the page.

The element() background is live. That means the background-image appearance on the thing using it will change if the referenced HTML element changes. It’s the same sort of deal when working with custom properties: change the variable and it updates everywhere it’s used.

There are, of course, other use cases for this property. Check out how Preethi used it to make in-page scrolling navigation for an article. You could also use a HTML canvas element as a background if you want to get fancy. One way I’ve used it is to show screenshots of pages in a table of contents. Vincent De Oliveira, has documented some wildly creative examples. Here’s an image-reflection effect, if you’re into retro web design:


Pretty neat, right? Again, I wish I could say this is a production-ready approach to get that neat design effect, but things are what they are at the moment. Actually, that’s a good reminder to make your voice heard for features you’d like to see implemented in browsers. There are open tickets in WebKit and Chromium where you can do that. Hopefully we’ll eventually get this feature in Safari-world and Chrome-world browsers.