Borderlands Text Effect Challenge
From time to time I like to set myself challenges of reproducing certain design elements in pure code, partly as amean to fex my development muscle and partly to try and learn something absolutely new. When I first decided I would play with some typographical effects some months ago I was playing Borderlands and figured reproducing the Borderlands logo in CSS should be relatively straight forward. Unfortunately I was wrong and even though I’ve come pretty close I can’t quite reproduce it. Here’s the original logo I’m trying to reproduce:
Should be challenging, yet achievable right?
Breaking down the problem
Lets ignore the transform for the moment as we know that’s relatively doable in itself. its the styling of the text itself I’m trying to reproduce. In my mind this breaks down into:
- All-Caps tight font
- A sort of grungy textured yellow fill
- A thick border to the text
- A bottom left drop-shadow/emboss
So now trying to work out in my head how to create this effect via CSS:
- Use the Impact font which is a pretty close match and thus doesn’t require @font-face (which is well documented anyway these days)
- Maybe a mask (webkit only), a tight text background-clip to the text (webkit only too) or an overlay perhaps
- Either some text-shadows or text-stroke (webkit only again)
- More text shadows probably
Attempt #1 – Texture overlay
Attempt one was the most simplistic and cross browser, but I also could see in advance there were a couple of issues. I used the ‘texture overlay’ method documented on various ‘Grunge-style text’ examples such as this tutorial by Janko At Warp Speed. The problems I see with this are firstly that there’s an irritating empty span required as an elements to be ‘textured’ over the text, and then there’s the problem of the texturing trick whereby it relies on the background behind the text being the same colour as the texture so you don’t see that the texture is being applied as a panel to the area rather than just the text. My extra complication here is that I want to show the text extruding from the background, which in this case I’ve done with Text-shadow. The text-shadow code is really quite overkill to achieve the effect, unfortunately, and I’m half convinced that this abuse of the CSS could lead to performance /rendering issues – but it does at least look right.
Attempt #2 – Transparent text, background clipped to text
Next I started thinking about how to get the texture behind the text and have it show through. I was just making progress when CSS-Tricks posted an article entitled “Show Image Under Text” about doing exactly that using -webkit-background-clip. The obvious compatibility issue with this technique is that my overloaded text-shadow code is incompatible as it effectively block the view of the background what with being in between the text and the background in the rendering stack. While not happy with using a Webkit only solution, i decided to run with it as an example so experimented the -webkit-text-stroke CSS property. This text stroke isn’t in any official spec, and its not even very well though out as you can’t specify the stroke as being inside or outside the font character edges so its always centred with isn’t always desirable and makes this example look slightly different.
Attempt #3+4 – Masks
While reading up on how -webkit-text-stroke and -webkit-background-clip worked I stumbled upon -webkit-mask. By this point in my experimentation I was basically praying for a text-fill CSS property and from reading the -webkit-mask properties were pretty similar. Unfortunately upon experimentation they aren’t quite right either, but are the closest. They still allow me to use the text-shadow stacking, but there are some big implementation quirks between Safari and Chrome. Chrome seems to require -webkit-text-stroke to be set with both a pixel and colour value or else it doesn’t apply the text-shadow, plus it will only apply the mask if the -webkit-mask-clip is specified with text twice, thus meaning its also applied twice making it a little darker. Safari, completely differently, requires there not to be a stroke set else it doesn’t show the text-shadow, plus if its set to clip to text twice it clips to the shadow too, making it looks quite wrong. On top of this it seems to be inverting the mask making it a white rather than black texture which is no good for me. The Chrome example is half-way decent, and the closest so far but is essentially unusable since it renders the Safari version unreadable.
I should note at this point I’m not exactly clear on how a mask is supposed to work in general, or in a browser and the Webkit documentation on this isn’t very extensive or clear.
I did think about using JS to create a clone of the wording that could be used as a drop-shadow, but that wouldn’t really buy me anything and besides I wanted to use pure CSS. Similarly I thought about marking this up using SVG or Canvas but similarly its not really the point as I wanted to use CSS and wanted this to be in-line selectable text for headings and the like.
If anyone out there has any other ideas, feel free to post them in the comments. I’d like to hope this is still doable in CSS, but alas that’s not always the case.
I’ve uploaded my code here: /experiments/decorative_text/
As you can see from the image below or by testing it yourself from the link above, the results vary. The closest is the Chrome Mask, but that’s unreadable in Safari unfortunately – and what’s more the shame is that its also acceptable enough in most of the other browsers, and although the contrast isn’t great in IE8 I’d probably not use this yellow version on a white background. Mind you, I’ve not got IE9 to hand to test that, so have no idea what that’s going to think of the various examples.
In the end what I’ve concluded is that while I can create some interesting effects with all of this, I can’t actually reliably reproduce the original example, which is a shame. What’s ultimately missing is text-fill, which would ideally be very similar in syntax to background (i.e. position, repeat, color, image, etc). So my request to the CSS Working Group is that for CSS3.1 or CSS4 we have such a property. I Only which that while I was a member of the CSS Working Group (on behalf of the BBC) I had formally suggested it.