Texturise web type with CSS

Texturise web type with CSS

  • Knowledge needed: Basic CSS and HTML
  • Requires: Text editor and WebKit Browser (Chrome or Safari)
  • Project time: 30 mins

As newer CSS properties, such as text-shadow, gain traction, there’s no limit to what can be done with web type. Trent Walton from Paravel goes a step further by texturising it

This article first appeared in issue 221 of .net magazine - the world's best-selling magazine for web designers and developers.

Thanks to the growing acceptance of WOFF and services such as Typekit, Fontdeck, Font Squirrel, and Fontspring, web fonts are everywhere. Now that web designers have access to more type choices, they want the same level of control over fonts that print designers have. While much can be achieved with web-safe fonts and core CSS properties such as font-weight or letter-spacing, many CSS3 properties can now be used to provide even greater control. WebKit browsers have a little-known but fantastic property that can be applied to text called mask-image.

Mask-image can be used to knock out small textural pieces of headline text. Using this technique with paragraph text would hurt readability, but when applied to a large-format display font, it can create a subtle point of interest. Though it’s currently only a WebKit safe (Safari and Chrome) property, it degrades gracefully by just showing no texture to non-supporting browsers.

In this tutorial we’ll walk through texturising type from scratch – beginning with basic HTML and CSS, then creating a semi-transparent texture in Photoshop and implementing it on some headline text within a web page. We’ll finish it off by adding some extra CSS and JavaScript love.

The design for this page has been inspired by the colour and type found on 1970s American muscle cars, particularly the Boss 302 Mustang.

Step 1: Setting up with HTML and CSS

Let’s begin by setting up an extremely simple index.html page with the following markup:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.         <meta charset="utf-8"/>
  4.         <title>Netmag / Mask-Image</title>
  5.         <link rel="stylesheet" href="style.css" type="text/css" />     
  6.         <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  7. </head>
  8.         <header>
  9.         <h1>Netmag</h1>
  10.         </header>
  11. </body>
  12. </html>

From there, we’ll start adding basic style and layout via the style.css style sheet we’re loading:

  1. body {
  2.         background-color: #d8411f;
  3.         color: #222;
  4.         font: 2em/1 sans-serif;
  5.         text-align: center;
  6. }
  7.  
  8. header {
  9.         margin: 15% auto;
  10.         width: 700px;
  11. }

Now we’re sitting pretty with some dark grey (#222) text on an orange background. In this case, just any ol’ sans-serif font won’t cut it, so we’ll be loading in League Gothic, courtesy of theleagueofmoveabletype.com. Here’s the updated CSS for the body, h1, and the Font Squirrel-generated @font-face:

  1. /* Generated by Font Squirrel (http://www.fontsquirrel.com) on July 5, 2011 */
  2. @font-face {
  3.     font-family: 'LeagueGothicRegular';
  4.     src: url('/fonts/league_gothic-webfont.eot');
  5.     src: url('/fonts/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
  6.          url('/fonts/league_gothic-webfont.woff') format('woff'),
  7.          url('/fonts/league_gothic-webfont.ttf') format('truetype'),
  8.          url('/fonts/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
  9.     font-weight: normal;
  10.     font-style: normal;
  11. }
  12. body {
  13.         background-color: #d8411f;
  14.         color: #222;
  15.         font: 2em/1  'LeagueGothicRegular', sans-serif;
  16.         text-align: center;
  17. }
  18. h1 {
  19.         border: .12em solid #222;
  20.         font-size: 8em;
  21.         line-height: 1;
  22.         padding: .08em .08em 0;
  23.         text-transform: uppercase;
  24. }
 the padding specified for the h1 simply helps to center the League Gothic set text within the border
Note: the padding specified for the h1 simply helps to center the League Gothic set text within the border

Step 2: Adding texture via mask-image

Let’s start by opening up Photoshop to create a semi-transparent .png texture to mask the text. It’s important to remember that when an image is masked using CSS, wherever there is transparency, the text will be erased or knocked out. That being the case, we only want to have subtle amounts of texture to ensure that the text remains legible.

Take a look at the three layers found in knockout.psd. Here’s the step-by- step for what I did from the bottom layer up:

The Background layer is simply the orange fill. I used the Texture – pre knockout layer to add some grunge, a few brush strokes at a time. While this layer isn’t used in the export, it’s included to help track the progression.

 

Next, I duplicated the Texture – pre knockout layer and renamed it Texture – used. In the Photoshop layer styles palette, I set the Fill Opacity to 0% and the Knockout to Deep to gain transparency.

 

When exporting/saving for web, be sure to export your image as a PNG-24 with the transparency checkbox checked.

Whew! Back to code. This part is magically simple – just expand the code for the h1 to include the mask image code:

  1. h1 {
  2.         border: .12em solid #222;
  3.         font-size: 8em;
  4.         line-height: 1;
  5.         padding: .08em .08em 0;
  6.         text-transform: uppercase;
  7.         -webkit-mask-image: url(/img/knockout.png);
  8.         -o-mask-image: url(/img/knockout.png);
  9.         -moz-mask-image: url(/img/knockout.png);
  10.         -ms-mask-image: url(/img/knockout.png);
  11.         mask-image: url(/img/knockout.png);
  12. }

And presto! That flat and boring text in a box now has texture. And never fear if the text takes up more space than the image you export because it automatically repeats. As I said before, this only works in WebKit, but I’ve added all the other vendor prefixes with high hopes that the property gains acceptance very soon.

I would say it’s appropriate to use this property as-is on client sites today because the fallback is perfectly acceptable. In this particular case, it would simply render as black text with no texture. No harm, no foul. As thrilling as this all is, I’d like to turn things up not one, but two
more notches!

Step 3: Make it skew with CSS3

CSS Transforms are rapidly gaining support among browsers that include IE9+, Safari 5, Firefox 4, Opera 11.1 and Google Chrome, so let’s put them to good use here:

  1. h1 {
  2.         border: .12em solid #222;
  3.         font-size: 8em;
  4.         line-height: 1;
  5.         padding: .08em .08em 0;
  6.         text-transform: uppercase;
  7.         -webkit-mask-image: url(/img/knockout.png);
  8.         -o-mask-image: url(/img/knockout.png);
  9.         -moz-mask-image: url(/img/knockout.png);
  10.         -ms-mask-image: url(/img/knockout.png);
  11.         mask-image: url(/img/knockout.png);
  12.         -webkit-transform: skewY(-7deg);
  13.         -o-transform:skewY(-7deg);
  14.         -moz-transform: skewY(-7deg);
  15.          -ms-transform: skewY(-7deg);
  16.         transform: skewY(-7deg);
  17. }

Voilà! That’s a lot of style being applied without any extra HTML whatsoever, and it’s not hard to imagine how one or all of these steps could be used to spruce up your work today. That is, unless you’re charged with building an adaptive or responsive layout. How can all of this pixel-pushed love translate to a fluid, flexible, and/or media queried layout without falling apart?

Step 4: Make it scalable via FitText

While redesigning my blog last Spring, I hit a major roadblock when I realised how difficult it would be to scale large-format headline titles where I didn’t want the text to wrap. I needed a way to achieve scalable headlines that fill the width of a parent element. Thankfully, my Paravel cohort, Dave Rupert, responded to the challenge by creating FitText.

Let’s put it to the test with this design, and make it perfectly scalable from a full-width desktop view down to a mobile device.

To start, let’s adjust the width of our header in the CSS:

  1. header {
  2.         margin: 20% auto;
  3.         width: 80%;
  4. }

Now that the width will be 80 per cent of our browser window, let’s load jQuery and FitText in that order in index.html:

  1.         <header>
  2.         <h1>Netmag</h1>
  3.         </header>
  4.         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  5.         <script src="js/jquery.fittext.js"></script>
  6. </body>

FitText needs us to set the compression. The larger the number, the more compression you get on the size of the font. Here’s the final HTML with all the FitText JavaScript from lines 14-18:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.         <meta charset="utf-8" />
  4.         <title>Netmag / Mask-Image</title>
  5.         <link rel="stylesheet" href="style.css" type="text/css" />     
  6.         <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  7. </head>
  8.         <header>
  9.         <h1>Netmag</h1>
  10.         </header>
  11.         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  12.         <script src="js/jquery.fittext.js"></script>
  13.         <script type="text/javascript">
  14.                 $("h1").fitText(.24);
  15.         </script>
  16. </body>
  17. </html>

How exciting that we’re able to do all the fine-tuning we want to type and make it scalable, built on a flexible foundation!

13 comments

Comment: 1

Me gusta

Comment: 3

Nice tutorial, but the text in the demo isn't visible in Chrome (18.0.1025.168) or Safari (5.1.5).

Comment: 4

It seems to not be working on most browsers.

Comment: 5

Howdy! It looks like some of the image and font assets aren't loading, which would cause this demo to break. I believe a fix is on its way. Stay tuned! :)

Comment: 8

"newer CSS properties, such as text-shadow"
Just a small correction: text-shadow is part of the CSS 2 spec and was first implemented in WebKit with Safari 1.1 (from 2005, I think). So it's really not a new property.

Comment: 9

Whether it works in all browsers or not at the moment is somewhat irrelevant to me. It's a great tutorial with some novel use of background images, transparency, and transformation/translation features of CSS3. Lends itself to jQuery or CSS animation by virtue of being a multilayered method. Thanks for sharing.

Comment: 10

It looks great and works well but I can't help but feel let down. I feel that the title and intro to this article imply the solution will be a CSS only solution rather than one using images created in photoshop...

Comment: 11

@ Leaverou: I agree with your ALA article. This was written for the print version before that was published and I've since been more careful about how I classify things like this.

And I'd actually love to hear more about the political & philosophical issues (maybe via blog post). I've got no agenda. I just like the idea of having no reason to resort to image replacement when laying out type on the web.

Comment: 12

Great post as a demo, it's only by trying these things in the community we will get further browser support.

Comment: 13

Such creative use of some clever CSS!

So what if it's not 'in the spec'? We all know how long that takes! Why not just use this just in case it's available, or just for the fun of it?! It's just an experimentation and demo!

Don't be a slave to the 'ratified' standards, which are well behind us all anyway. If it's there, use it for those who can see it.

Thanks, Trent.

Martin
June issue on sale now!

The Week in Web Design

Sign up to our 'Week in Web Design' newsletter!

Hosting Directory
.net digital edition
Treat yourself to our geeky merchandise!
site stat collection