Setting Text Free

My web development students are currently working on an unsolicited redesign of a site of their choosing. Most of my students this semester are predominantly designers; code is new to them, but they appreciate the visual side of what we’re doing. Being designers, typography and font choice plays a huge role in some of their designs, but I noticed a bad habit with a few students: text trapped in images.

I get it: it’s easier to have pixel-perfect control of type in programs that designers are already used to, like Photoshop, and to create an image for use on the web. For logos and designs that are more illustrative than textual, this can make sense, as there’s a lot that webfonts just plain can’t do yet. Still, when you’re already using a webfont on the rest of your site, trapping the text just feels unnecessary. We also run into a few problems with that approach:

  • Google is blind. It’s a crawling bot; it can’t read images (though it can read the text we have in alt codes). For non-critical text, this isn’t a huge deal, but some websites (like one of my favorite sushi places, Sakura) have entire menus that are image-only. These are a huge pain to read on mobile devices; text doesn’t reflow, so users need to pinch-to-zoom and pan back and forth across the page to read things. Not fun.

  • We’re moving towards higher-resolution displays (I can’t wait for 4k to be more affordable!) and low-resolution images don’t look as crisp.

  • Raster images (JPG, PNG, GIF) are intended for a specific size. Resize them larger and they get fuzzy; resize them smaller and they can look okay, choppy, blurry… it’s a wildcard, and I don’t like to rely on wildcards. That’s also just talking about uniform resizing where changes are made to both dimensions.

  • You can’t quickly change the text in your image. If you want to edit the copy, you need to export a new image. You’ll also need a separate image for each headline you use. That adds up!

With my lectures still fresh in my mind, I knew what I needed to do when I came across an image-based header on It looks nice on their site, but text doesn’t need to be trapped in an image. This example is admittedly not as critical as an entire menu as one image, but I wanted to challenge myself: how in the world could I create that odd shape just with CSS? Changing just the border radius alone wouldn’t do it, and the traditional approach to use the border hack to create the small triangles in the top corners wouldn’t take care of the rounded trapezoid.

See the pen on CodePen.

Through a lot of experimentation, I ended up using a combination of transform: perspective() rotateX(), border-radius, and box-shadow. I’ve used the last two dozens of times and rotate() in a handful, but perspective() was new to me. As expected, I could not apply the perspective and rotation to the entire <div class="banner">, as the text would also be affected. Overall, I was able to create the header background without resorting to excessive empty elements (this uses a <div> container and just the <h2> inside it). I also incorporated a chunky slab-serif from Google Fonts (since H&Co.’s Vitesse isn’t a freebie) and an image from Unsplash.

Since this was just a quick exercise, I used pixel values for the banner container’s height and width, but one of the other benefits of using code instead of images is that this banner could also become responsive with a few tweaks. The setup requires a bit more work, but I find that the effort absolutely pays off.

© Stephy Miehle as Blinding Stars