Nate Eagle

Front-End Developer

My First Compass Mixin: Text-3d

So I started using Compass because Chris Eppstein himself told me via a tweet that I should check it out. (I mentioned SASS in a tweet, and Mr. Eppstein seems to be as dedicated a promoter as he is talented a developer.) Compass is pretty fantastic, though I will menition that it’s not trivially easy to learn how to use effectively: I’m still working on learning a lot of the ins and outs of using SASS and mixins.

I won’t get too much into Compass itself – part of the idea of this blog is to keep things short and simple – but my favorite part of Compass is the mixins. These work like functions in JavaScript that let you pass in a minimal number of inputs and get out some more complex CSS as a result. This is great for simplifying CSS3, especially, which often requires outputing essentially the same information with the various vendor prefixes. Compass comes with a whole slew of them, but you can also define your own.

While working on the design for this blog, I found myself using (as I often do) a small trick that uses multiple text shadows to create a 3d text effect.

David DeSandro Made This

The technique was created, as far as I know, by Dave DeSandro, one of the classiest folks in interaction design, who uses it prominently on his homepage. Regardless of its ultimate origin, that’s where I picked it up. It creates the illusion of blocky three-dimensional letters that have a side in shadows that stretches back in space. The CSS for it is easy to understand: it just uses the fact that the text-shadow property can have multiple, comma-separated backgrounds.

#mytext {
    text-shadow:
        1px 1px 0 #000,
        2px 2px 0 #000,
        3px 3px 0 #000,
        4px 4px 0 #000,
        5px 5px 0 #000;
    }

The shadow is made up of 1px layers, each offset slightly from the one that preceded it. Here’s an example that should make that obvious. (Note: example will not work in browsers that do not support text-shadow.)

Nate Eagle Made This

h3.example1 {
    text-shadow:
        1px 1px gray,
        2px 2px white,
        3px 3px gray,
        4px 4px white,
        5px 5px gray;
    }

I alternated the shadows between gray and white: you can see clearly how they stack. But if you make them a single color:

Nate Eagle Made This

h3.example2 {
    text-shadow:
        1px 1px gray,
        2px 2px gray,
        3px 3px gray,
        4px 4px gray,
        5px 5px gray;
    }

…it creates the illusion of a solid side, receding in space. Lovely, yeah? Only problem: it’s kind of a complex declaration. And fiddling around with the color and size of the effect is annoyingly complex: you have to add and remove whole lines, change multiple numbers, change the name of the color multiple times.

It’s the perfect candidate for a mixin. Here’s the documentation for defining a mixin. In this example, I’m going to reference another mixin – Compass’s text-shadow plugin – after generating the string of shadows I want.

 @mixin text-3d($size: 5, $directionX: 1, $directionY: 1, $blur: 1px, $color: black ) {
    @if unitless($blur) {
        @warn "Assuming #{$blur} to be in pixels";
        $blur: 1px * $blur;
    }
    $string: '';
    @for $i from 1 through $size {
        $string: $string + ( #{$i * $directionX}px #{$i * $directionY}px $blur $color );
        @if $i < $size {
            $string: $string + ', ';
        }
    }
    @include text-shadow(
        #{$string}
    )
}

Pretty simple: this looks and works a lot like a function in JS/PHP. I accept a size parameter, which determines how many shadows to create (my examples above have five), then two direction parameters. This lets you send your 3d text down and to the right (1, 1), up and to the right (1, -1), up and to the left (-1, -1) or down and to the left (-1, 1). You can even use values like (-1, -0.5) to have the text go at 22.5° rather than 45°.

Using the mixin is as simple as this:

 @include text-3d( 3, -1, -1, 0, $someColor );