Text masking — The standards way

As much as I like .net magazine, I was recently outraged by their “Texturizing Web Type” article. It features a way to apply a texture to text with -webkit-mask-image, presenting it as an experimental CSS property and misleading readers. There are even -moz-, -o- and -ms- prefixes for something that is not present in any specification, and is therefore unlikely to ever be supported by any non-WebKit browser, which further contributes to the misdirection. A while back, I wrote about how detrimental to our work and industry such proprietary features can be.

A common response to such complaints is that they are merely philosophical and who cares if the feature works right now and degrades gracefully. This argument could be valid for some cases, when the style is just a minor, gracefully degrading enhancement and no standards compliant alternative is present (for example, I’ve used ::-webkit-scrollbar styles myself). However, this is not the case here. We have had a standards compliant alternative for this for the past 11 years and it’s called SVG. It can also do much more than masking, if you give it a chance.

Here’s an example of texturized text with SVG:

Edit: Thanks to @devongovett’s improvements, the code is now simpler & shorter.

Yes, the syntax might be more unwieldy but it works in a much wider range of browsers: Chrome, Safari, Firefox, IE9, Opera. Also, it’s trivial to make a script that generates the SVG markup from headings and applies the correct measurements for each one. When WebKit fixes this bug, we can even move the pattern to a separate SVG file and reference it from there.

In case you’re wondering about semantics, the <svg> element is considered “flow content” and is therefore allowed in heading elements. Also, even if search engines don’t understand inline SVG, they will just ignore the tags and still see the content inside the <text> element. Based on that, you could even make it degrade gracefully in IE8, as long as you include the HTML5 fix for the <svg> element. Then the CSS rules for the typography will still apply. You’ll just need to conditionally hide the <image>, since IE8 displays a broken image there (a little known fact is that, in HTML, <image> is basically equivalent to <img>, so IE8 treats it as such) .

Credits to David Storey’s original example that inspired this.

  • Matt Wilcox

    And that “unwieldy” is *exactly* the reason why after 11yrs of the thing existing, it is still not used. The simplicity, recogniasibility, and predictability of -webkit-mask- is *exactly* why it would be used – it’s understandable with existing knowledge.

    Syntax is everything. SVG’s method has a shitty syntax, so it’s dead. A living corpse. As has been proven.

    • http://leaverou.me Lea Verou

      -webkit-mask only does one thing, SVG is much more powerful. That power comes at a cost. Also, the FX Task Force (a joint effort from the CSS and SVG working groups) is making many SVG features simpler for basic usage on HTML elements. They are currently working on blending modes and filters and have already published drafts for them (Editor’s Drafts, but still). Stay tuned ;)

      • Matt Wilcox

        I agree with the sentiment, but the cost of all that power has so far meant that no one bothers using it. There is no point in having powerful features that are never used – especially when you only want it for a simple job.

        I look forward to the group giving us something as simple as -webkit-mask but with the power of SVG.

      • http://profile.yahoo.com/VXAQ7VQMLRJ7PIJPTN4OKFXFAM Sprawl

        I’m sorry to disagree. I am totally onboard with destroying these stupid vendor prefixes that requires us to put a lot of extra coding on the page. However, the same logic exists for SVG. Too much keeps people from using it unless there are no other alternatives.

    • Ned Baldessin

      No, the reason SVG masks (and SVG in general) hasn’t taken off yet is simple: no support in legacy IE. (And no, using SVGweb or Raphael as polyfills isn’t robust for small text effects integrated in the flow of a page).
      I think the frontend web community has proven again and again that we will use whatever syntax, no matter how unwieldy, to get things done, as long they work on a wide scope of platforms.

      That said, I obviously agree with you that CSS masks have a much better syntax. But I don’t think that syntax is what is holding SVG back.

  • Mr C

    .net magazine’s example supports the use of ‘h1′ tags. surely a much more sensible approach if you ever want search engines to make sense of your markup, no?

    opera have recently proved that developers supporting proprietary markup will lead to adoption on other platforms, so why not webkit-mask-image too? if we all start using it en masse, opera/firefox/ie will soon fall in line.  from there a ‘standard’ can be derived.  same as happened with drag/drop support and more.

    not sure why things have to be a standard before anyone gets to use them? innovate like crazy, put cool stuff out there, see what gains traction and then fill in the specs later.

    • http://leaverou.me Lea Verou

      Yes, this happens. It results in some of the most poorly designed features in the web platform. You mentioned Drag & Drop, which is a prime example of this. Pretty much everyone agrees that it’s one of the worst APIs in HTML5. Features need diverse feedback to be elegant, which a single vendor can never provide. My AListApart article that I linked in the first paragraph is exactly about this. I’d suggest you read it.

      Also, I just didn’t include an h1 tag to keep the demo simple. You can always wrap the SVG with heading tags, it’s perfectly valid.

      • Mr C

        be interested to see if svg text inside a ‘h1′ carries the same search weight as a plain text string. may have to do some experimentation.

        drag and drop isn’t perfect, i agree. but it’s better than nothing. and nothing is what standards brought to the table ;)

        • http://leaverou.me Lea Verou

          I’d assume it does. If the search engine does not understand inline SVG, it will just ignore the extra tags and see the text. If it understands inline SVG, well, that’s a no-brainer. Also, if you use a script to generate the SVG markup, there is practically no difference.

          CSS itself was first developed as a standard and then implemented by browsers. And that’s just one example out of hundreds. Check your facts.

        • Mr C

          i’m not claiming the standards body never innovate, i’m just pointing out that there is also a case for browser developers to innovate (and standards to catch up).  drag/drop is but one example… there are many more.

          to my mind, thumping people over the head every time they dare to write about or encourage a non-standard web innovation seems like a pretty negative way to live life, that’s all.

          still. i am excited by svg inside h1′s so shall busy myself with that instead of annoying your good self any further.

        • Anonymous

          I’ve never understood why SVG was included in the content layer and not the presentation layer. It would have made much more sense in my eyes for it to be embedded into CSS instead of HTML.

          The whole idea of the HTML/CSS split was to separate content from design, so embedding a chunk of presentational markup seems wrong. The syntax would obviously have needed to be more CSS like and less XML like but hopefully you see what I’m saying.

  • Adam

    Lea

    Thank you

    SVG Doesn’t get nearly the respect it deserves. It has often surprised me how much energy is put into creating nifty effects that could be done easier with SVG if you took the time to learn it.

    What do you think about the possibility of doing page layout using SVG? It seems to me that is the next logical progression in our discipline. Layout your navigation along a curve and then have the CMS generate the items for the navigation, for example.

    • http://leaverou.me Lea Verou

      I think CSS, especially with the new layout modules, is much more suited for layout. Doing layout in SVG is just as bad as doing graphics with CSS & HTML.

  • Anonymous

    I gotta say @devongovett has the method that does indeed rock. If I understand the above correctly it means I can use any png as a texture “mask”, or more accurately, “fill” for text. Easy to do in Illustrator, but better to do right in the code as it leaves out the weight of bringing an external image into the doc to fake a title or logo.

    • http://leaverou.me Lea Verou

      Um, no. You can’t use an image directly, you have to use a pattern for this. @devongovett just removed the superfluous mask in my original code. I’m afraid it can’t be simplified further (for one isolated use, for multiple you can reuse the pattern element), but I’d love to be proven wrong.

      • Anonymous

        Yes but that pattern he’s using comes from a png file. So, SVG may see it as a pattern, but the source is a png. That’s what I was referring to. The code is no problem. And I agree, the big advantage is that once the #id is created it can be used multiple times. Which leads me to this question, does the pattern tag only accept id’s, or could a class be used instead. I personally like to limit the use of id’s as much as possible (and eliminate them altogether wherever possible, classes lead to more consistent design look and feel across a site imho).

        • http://leaverou.me Lea Verou

          No, as with other similar references, you have to use id.

        • http://twitter.com/svgeesus Chris Lilley

          You have to use an id to point to a specific element. But you are not restricted to only bare # so for example url(fills.svg#wood) lets you refer to an external file.

        • http://lea.verou.me/ Lea Verou

          True. Although WebKit doesn’t support external references in many things in SVG (e.g. doesn’t support them in the use element), so maybe not in fill either. :(

  • http://twitter.com/bfred_it Federico Brigante

    A problem with SVG text is that SVG 1.2′s text wrapping is not implemented in most (if any) browsers, making it impossible to use for headings longer than a few words, especially if you put responsiveness into consideration. 
    Technically, SVG behaves like an image, so you could still set max-width:100% and have it fit its container (FitText.js-like), but you still have the length limitation.

  • basecode

    Because you mentioned Safari, there is this webkit bug [1] that leads to undesired results on current Mobile Safari versions and also (Desktop) Safari versions prior to 5.1.5. The pattern-element is rendered upside down and even worse this bug also changes the position of the pattern on everything that causes a reflow (resizing the window, changing orientation, etc). See the bug in action: http://jsbin.com/isinef (I replaced the wood-pattern because that makes the bug more visible).

    `patternTransform=”scale(1, -1)”` would fix the upside down issue but not the reflow issue. Unfortunately I didn’t found a solid way to detect that bug (via JavaScript) so far.

    [1] https://bugs.webkit.org/show_bug.cgi?id=75741

    • krit

      This is fixed now.

  • Nathanael Mowbray

    I used a canvas to achieve a similar effect, though I will probably convert to SVG after reading this.

  • Pingback: Bruce Lawson’s personal site  : Reading List

  • Zoltan Hawryluk

    Brilliant article, as per usual! I wonder if it is possible use this with IE7-8′s Compositor Visual Filter to create a full-cross browser solution. Even though it is deprecated and proprietary, it would at least allow one to fill in support for those crappy widely-used browsers.

  • http://alexandrebroudin.net/ Alexandre Broudin

    Hi, ty for this post.

    In this case, i prefer use an image with a pseudo element like ::after , than SVG, less code, and more readable no ?

    How crawlers reacts with SVG ? is it good for SEO ?

    But again thank you for your example

    a suggestion, can you add a “white-space : nowrap” on you please ? =)

  • Pingback: Маскирование текста по стандарту

  • Pingback: Tweet-Parade (no.20 May 2012) | gonzoblog.nl

  • Anonymous

    SVG does rock. But you know what rocks more? An h1 tag.

    • http://leaverou.me Lea Verou

      Who said those two are mutually exclusive? SVG in an h1 tag is perfectly valid. Read the last paragraph, it’s exactly about that.

      • Anonymous

        Hm, that’s cool. I would probably implement this via JavaScript or something to save time and maintenance hassle when CSS masking isn’t available.

  • Pingback: Some links for light reading (25/5/12) | Max Design

  • Pingback: Texturizzazione di un font con css | Laboratorio CSS

  • Pingback: Tweet Heat - The hottest Tweets of the Month [May 2012] | Inspired Magazine

  • Pingback: Tweet Heat – The hottest Tweets of the Month [May 2012] | Web Dezining

  • Pingback: Text masking — The standards way | Lea Verou » Web Design

  • Pingback: Powerful New CSS- and JavaScript Techniques | t1u

  • Stan Rogers

    What I’m seeing here is markup (a subdocument, in fact) specifically aimed at styling. It doesn’t matter that SVG is a standard if we have to substantially change the document content in order to apply a style—that runs rather contrary to the whole idea of separation of concerns, mixing content generation (and/or creation and curation) with appearance (or, if you do the swap in the client DOM, appearance and behaviour, which is equally abhorrent). While I can understand a strong distaste for experimental features and vendor-specific implementations, I would much rather go that route than move back to what is the structural equivalent of FONT tags.

  • Pingback: Powerful New CSS- and JavaScript Techniques@smashing | seo博客大全

  • Pingback: Powerful New CSS- and JavaScript Techniques | Buypappa blog

  • Pingback: Powerful New CSS- and JavaScript Techniques | MyOfflineTheme.com Skyrocket Your Offline Business Just Now

  • Pingback: Powerful New CSS- and JavaScript Techniques | Web Design Kingston

  • Pingback: Powerful New CSS- and JavaScript Techniques | DigitalMofo

  • Pingback: Steve deGuzmanPowerful New CSS- and JavaScript Techniques » Steve deGuzman

  • Pingback: Powerful New CSS- and JavaScript Techniques « Web Development Website

  • Pingback: Powerful New CSS- and JavaScript Techniques » E BLADE

  • Pingback: Powerful New CSSand JavaScript Techniques - rehavaPress

  • Pingback: Rutweb Technology : Powerful New CSS- and JavaScript Techniques

  • Pingback: Powerful New CSS- and JavaScript Techniques | TuTsRUS - All Adobe Tutorials - Photoshop | Illustrator | Encore | Premeire | After Effects

  • Pingback: Powerful New CSS- and JavaScript Techniques — Заметки по дизайну

  • Pingback: Powerful New CSS- and JavaScript-Techniques (2012 Edition) | Smashing Coding

  • Pingback: Powerful New CSS- and JavaScript Techniques | Sedation Dentist Wayne

  • Pingback: Type News: Embooked | Uber Patrol

  • Pingback: Powerful New CSS – and JavaScript Techniques

  • Pingback: Powerful New CSS- and JavaScript Techniques

  • Pingback: Bergstrom Productions Powerful New CSS- and JavaScript Techniques | Bergstrom Productions

  • Pingback: CSS3 text with textured drop shadow effect - Tristan Denyer

  • Pingback: Powerful New CSS- and JavaScript Techniques « OhMyDev

  • Pingback: Nuevas técnicas CSS3, HTML5 y JavaScript. – Sweety Web Designs

  • DanOwen

    Sorry to be off topic. As an SVG newbie I can’t find a way to make SVG responsive. Without that, it’s useless to me. Tips, please. Thank you.

    • http://lea.verou.me/ Lea Verou

      In what way do you want to make it responsive?
      Btw: Media queries work in SVG too :)

      • DanOwen

        Thanks for the prompt reply. As a background (type) image, as a logo, as an image. Mainly, as an asset that can be used wherever appropriate in the context of responsive (or adaptive) web design. My problem is I can’t seem to avoid a fixed size. It ignores %. Sorry to show my ignorance.

        • http://lea.verou.me/ Lea Verou

          Just set width=”100%” height=”100%” on the SVG and viewBox with the dimensions you want (e.g. viewBox=”0 0 200 100″ for a width of 200px and a height of 100px). Then it will adapt to whatever size you give it.

  • Pingback: Powerful New CSS- and JavaScript-Techniques (2012 Edition)

  • ChristopherAnderton

    There are still some issues with SVG. Security wise, you could do remote execution and other things that could be of concern. Edit. Here is why SVG will not be supported in WordPress 3.6 (User Upload): https://core.trac.wordpress.org/ticket/24251

  • Pingback: Creating Image Galleries with Clipped Images Using CSS Pointer Events and SVG | Flippin' Awesome

  • Pingback: Küçük bir ipucu #4 « Ayhan Kuru & Blog

  • Kerry Snyder

    Am I missing something? It would seem something has changed since this was written. Here’s what the example looks like in Safari today.

  • Pingback: Cross browser CSS 3 text gradient - HTML5 Solutions - Developers Q & A

  • tchalvakspam

    Yeah, the SVG text looks super bad in the usually-good-with-standards Chrome (28.0): See this screenshot: http://imgur.com/uF6rGFo

  • Pingback: Tweet-Parade (no.20 May 2012) - The Best Articles of Last Week | gonzoblog

  • Pingback: Powerful New CSS- and JavaScript Techniques - Internet Business