Skip to content

Instantly share code, notes, and snippets.

@nathggns
Created June 24, 2012 17:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathggns/2984123 to your computer and use it in GitHub Desktop.
Save nathggns/2984123 to your computer and use it in GitHub Desktop.
Text Stroke SCSS Mixin (SASS)
@mixin stroke($width, $color) {
$shadow: 0 0 0 transparent;
$i: 0;
@while ($i < $width) {
$i: $i + 1;
$j: 0;
@while ($j < 2) {
$j: $j + 1;
@for $k from 1 through 3 {
$x: 0;
$y: 0;
@if ($k == 1) {
$x: $i;
}
@if ($k == 2) {
$y: $i;
}
@if ($k == 3) {
$x: $i;
$y: $i;
}
@if ($j != 1) {
$x: $x * (0 - 1);
$y: $y * (0 - 1);
}
$shadow: #{$shadow}, #{$x}px #{$y}px 0 $color;
}
}
}
text-shadow: $shadow;
@media screen and (-webkit-min-device-pixel-ratio: 0) {
text-shadow: none;
-webkit-text-stroke: #{$width}px $color;
}
}
@lellimecnar
Copy link

This creates a very messy and jagged stroke. Here is a better solution which generates a nice smooth stroke:

@mixin stroke($width, $color) {
    $width: $width + 0;
    $shadow: 0 0 0 transparent;
    $i: 0;
    $w: 1;

    @while ($i < $width) {
        $i: $i + 1;
        $j: 0;
        $w: $w + 2;

        @for $r from 1 through $w {
            @for $c from 1 through $w {
                $x: $c - ceil($w / 2);
                $y: $r - ceil($w / 2);

                $shadow: #{$shadow}, #{$x}px #{$y}px 0 $color;
            }
        }
    }

    text-shadow: $shadow;
}

text-shadow and -webkit-text-stroke don't produce the same effect, so I removed the -webkit-text-stroke from my version.

@onzag
Copy link

onzag commented Apr 3, 2015

lellimecar, now that's the absolute solution, even for people that do no use sass; you get in here:

http://sassmeister.com/

And with that mixin you get your css result; as long as it may be.

You should put that somewhere else more visible, It took me long to find a solution.

@alexzaworski
Copy link

alexzaworski commented Aug 17, 2016

So this is super old but I stumbled across it searching for a solution to this exact problem— figured I'd leave this for people in the same situation.

If I'm not mistaken, @lellimecnar's solution produces waaaaay more CSS than needed (like, exponentially more). Here's what I'm using:

@mixin stroke($width, $color) {
  $shadow: ();
  @for $i from -$width through $width {
    $shadow: append($shadow,#{$width}px #{$i}px $color, comma);
    $shadow: append($shadow,#{-$width}px #{$i}px $color, comma);
    $shadow: append($shadow,#{$i}px #{$width}px $color, comma);
    $shadow: append($shadow,#{$i}px #{-$width}px $color, comma);
  }
  text-shadow: $shadow;
}

Ain't fancy but as far as I can tell the effect is identical and the output is much less verbose.

@erickskrauch
Copy link

For anyone, who will search for text-stroke mixin for LESS:

.text-stroke(@width, @color) when (@width > 0) {
    .text-stroke(@width - 1, @color);
    text-shadow+:  @width  @width 0 @color;
    text-shadow+: -@width -@width 0 @color;
    text-shadow+:  @width -@width 0 @color;
    text-shadow+: -@width  @width 0 @color;
}

Usage:

.selector {
    .text-stroke(2px, #fff);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment