Animated TextFills All

Demo     Download

I like to think that the future is already here. We have already so many exciting possibilities in CSS and SVG that some time ago we could only dream about. For example, we now have many possible ways to create text with an animated fill!

About a year ago the article Techniques for creating textured text by Sara Soueidan was published here on Codrops. This wonderful article will tell you all about the different methods for creating textured text with some modern web techniques including canvas.

I’m very interested in this topic but from a different perspective. I have the following questions: Can the text fill be animated? Can we fill text with animated shadows or gradients? Or what about using videos for filling the text?

In this article I’m going to share my experiments and five ways to create patterned filled text. In three out of these five cases we will retain the ability to select the text. Of course we’d like to have that for every case but with some workarounds we can solve this problem, too.

For each of the techniques I’ll show the browser support, the ability to select text and, most importantly, the possibility to animate the fill (highly experimental).

I will not include all the code here, only the most important parts, but you can find everything inside the download files and play with it.

Let’s begin.

Attention: Some of these techniques are very experimental and won’t work in all browsers. Please see the browser support at the beginning of each section. Internet Explorer has very little support.

Method 1: Using background-clip: text

The markup looks as follows:

<div class="box-with-text">
    Text
</div>

And the CSS looks like this:

.box-with-text {
  background-image: url(IMAGE URL);
  -webkit-text-fill-color: transparent;
  -webkit-background-clip: text;
}

textfill_image1
Demo:2

This simple trick with a gradient will allow us to fix the view in non-Webkit browsers if we don’t want to show an image but I believe that a workaround like this makes this method not a good choice for textured text yet.

If we want to animate the fill for example, CSS backgrounds don’t give us many possibilities. We can only animate the background position and size, but we can’t smoothly change colors.

textfill_image4

The technique using background-clip: text is not cross-browser and it only has limited possibilities for animating the fill.

Method 2: SVG text

SVG is a wonderful format which has good browser support. With SVG we have three ways to make patterned text:

  • fill
  • mask
  • clip-path

I’ll cover all three techniques here, so let’s begin with using fill.

If you are not familiar with SVG, I recommend reading the SVG specification, the articles by Sara Soueidan or the SVG tutorials on WebPlatform.org.

This is how we can use text in an SVG:

<svg viewBox="0 0 600 300">
  <text text-anchor="middle"
          x="50%"
          y="50%"
          dy=".35em"
          class="text"
          >
      Text
    </text>
</svg>

We can also have a dashed stroke and animate it in different ways:textfill_image13For this type of stroke we need to duplicate the text as many times as colors are used. A better way to make this, is to use the symbol:

<svg viewBox="0 0 600 300">

  <!-- Symbol -->
  <symbol id="s-text">
    <text text-anchor="middle"
            x="50%" y="50%" dy=".35em">
        Text
     </text>
  </symbol>

  <!-- Duplicate symbols -->
  <use xlink:href="#s-text" class="text"
            ></use>
  <use xlink:href="#s-text" class="text"
            ></use>
  <use xlink:href="#s-text" class="text"
            ></use>
  <use xlink:href="#s-text" class="text"
            ></use>
  <use xlink:href="#s-text" class="text"
            ></use>

</svg>

And this is how we can control the colors and the animation:

$colors: #F2385A, #F5A503, #E9F1DF, #56D9CD, #3AA1BF;
$max: length($colors);
$dash: 70;
$dash-gap: 10;
$dash-space: $dash * ($max - 1) + $dash-gap * $max;
$time: 6s;
$time-step: $time/$max;

.text {
  fill: none;
  stroke-width: 6;
  stroke-linejoin: round;
  stroke-dasharray: $dash $dash-space;
  stroke-dashoffset: 0;
  animation: stroke $time infinite linear;

  @for $item from 1 through $max {
    &:nth-child(#{$max}n + #{$item}){
      $color: nth($colors, $item);
      stroke: $color;
      animation-delay: -($time-step * $item);
    }
  }
}

@keyframes stroke {
  100% {
    stroke-dashoffset: -($dash + $dash-gap) * $max;
  }
}

And this results into the following CSS:

.text {
  fill: none;
  stroke-width: 6;
  stroke-linejoin: round;
  stroke-dasharray: 70 330;
  stroke-dashoffset: 0;
  animation: stroke 6s infinite linear;
}

.text:nth-child(5n + 1) {
  stroke: #F2385A;
  animation-delay: -1.2s;
}

.text:nth-child(5n + 2) {
  stroke: #F5A503;
  animation-delay: -2.4s;
}

.text:nth-child(5n + 3) {
  stroke: #E9F1DF;
  animation-delay: -3.6s;
}

.text:nth-child(5n + 4) {
  stroke: #56D9CD;
  animation-delay: -4.8s;
}

.text:nth-child(5n + 5) {
  stroke: #3AA1BF;
  animation-delay: -6s;
}

@keyframes stroke {
  100% {
    stroke-dashoffset: -400;
  }
}

For each symbol we set an individual animation delay, so the parts of the stroke don’t accumulate in one place but spread through the contour of a letter.

Method 3: SVG mask and SVG clippath

There are two types of masks in SVG. We also have masks in CSS that can be applied to HTML elements, but browser support is not good enough, so let’s dive into SVG masks.

SVG masks can be applied to HTML elements too, but for now this feature only works in Firefox. SVG masks for SVG elements work fine in all modern browsers. And both clippath and mask can contain text.

What is the difference between mask and clippath?

clippath simply cuts the object to its path boundaries. It’s like a scissor cut.
mask takes transparency and brightness of the mask into account which allows for a kind of filtering of the object.
textfill_image15
Masks can contains symbols, which is very convenient for text with rich effects, when we need several copies of the text.

<symbol id="s-text">
  <text text-anchor="middle"
        x="50%"
        y="50%"
        dy=".35em"
        class="text"
        >
    Text
  </text>
</symbol>

<!--Mask-->
<mask id="m-text"
      maskunits="userSpaceOnUse"
      maskcontentunits="userSpaceOnUse">
   <use xlink:href="#s-text"
      class="text-mask"
    ></use>
</mask>

The markup for the group will be the same but the mask is applied by using the attribute mask:

<g mask="url(#m-text)">
  ...
</g>

In both mask and clippath, the text can be styled, i.e. we can change the font family and font size. But the text can’t be selected.

This problem can be solved by duplicating the text from the mask/clippath, place it above the masked element and remove its fill by setting fill: transparent. Like that we’ll get a transparent text which can be selected and copied.

Method 4: Mix blend mode

Attention: in order to view the demos in this section, you’ll need to use Firefox or Safari, or in Chrome with the activated flag under chrome://flags/#enable-experimental-web-platform-features (relaunch required). To view the demos in Opera activate the flag opera://flags/#enable-experimental-web-platform-features and relaunch browser, too.

How it works: different blend modes work differently on the colors of the layer they are applied to. For example, the mode lighten will show only light areas of the content, dark areas will disappear. On the other hand, the mode darken will select dark areas, and light areas will disappear. This allows us to create a HTML layer with transparent areas of a complex shape, even in the shape of regular text which can be changed on the fly!
textfill_image19The following is a simplified version of the markup:

<div class="box-with-text">
    <div class="text">Text</div>
</div>

And this is the CSS:

.box-with-text {
  background: url(IMAGE URL)
    50% 70% / cover;
  }
  .text {
    background: black;
    color: white;
    mix-blend-mode: darken;
    }

All the magic is contained in the line mix-blend-mode: darken. With this blend mode all white areas will become fully transparent and we can see the background of the parent
animatedfills_demo19

.box-with-text {
  background: url(IMAGE URL) 50% 70%/cover;
  /* Hack to hide thin transparent lines while resizing objects */
}

.box-with-text:after {
  content: '';
  position: absolute;
  top: -2px;
  right: -2px;
  bottom: -2px;
  left: -2px;
  display: block;
  border: 4px solid black;
}

.text {
  background: black;
  color: white;
  mix-blend-mode: darken;
}

Method 5: SVG mask and HTML

This last technique is a little peculiar, too. It’s quite similar to the previous one, but it has better browser support, because yes — it’s SVG again!

I call this method the “reverse mask”. In its essence it consists in using a SVG mask to get a layer with a solid fill and a transparent area in the shape of text, so that, in the next step, this layer can be put over an HTML element with any content.

We won’t cut the extra bits of the layer with content (as we do when using mask or clippath). On the contrary, we’ll make holes of the needed shapes in the layer with the solid fill, similar to a stencil. And this is how it looks:textfill_image21For this case, the SVG is divided into two parts. The first invisible part contains a symbol with the text and the mask:

<svg viewBox="0 0 600 300" class="svg-defs">
  <!-- Symbol with text -->
  <symbol id="s-text">
    <text text-anchor="middle"
          x="50%" y="50%" dy=".35em"
          class="text">
      Text
    </text>
   </symbol>

   <!-- Mask with text -->
   <mask id="m-text"
      maskunits="userSpaceOnUse"
      maskcontentunits="userSpaceOnUse">

     <rect
           width="100%"
           height="100%"
           class="mask__shape"/>
     <use xlink:href="#s-text"
        class="mask__text"/>

  </mask>
</svg>

In simple cases you don’t have to add the symbol, but it helps make the code of the mask more readable. In more complex cases it will help you make some interesting effects.

In this case we need the mask inverted, that’s why it’s needed to set the white color for the shape which is filling the mask:

.mask__shape {
  fill: white;
}

The color of text must be black because the transparent area in the mask must be in the shape of the text.

Also, we’ll need a more complex HTML structure

<div class="box-with-text">
  <!-- Content for text -->
  <div class="text-fill"></div>

  <!-- SVG to cover text fill -->
  <svg viewBox="0 0 600 300"
       class="svg-inverted-mask">
    <!-- Big shape with hole in form of text -->
    <rect
         width="100%" height="100%"
         mask="url(#m-text)"
         class="shape--fill"/>
    <!-- Transparent copy of text to keep patterned text selectable -->
    <use xlink:href="#s-text"
         class="text--transparent"/>
  </svg>
</div>

The lowermost layer contains the HTML element, to which we can apply a background or it can be filled with some HTML content. In simple cases the background can be applied to the parent container, but for more flexibility it’s better to use a separate element.

The next layer is the SVG which contains the shape with the fill and the mask. It’s a visible layer with a transparent area in the shape of the text. Above this layer we place a symbol with the text; this is needed to keep the text accessible.

The disadvantage of this technique is that the layer with the content is not cut off by the mask. The underlying layers can be seen through the transparent area of the topmost layer. We can’t cut off the text from the background and place it over other layers.

But this technique has some advantages, too. The first advantage is that HTML is placed outside the SVG and may contain anything we want: any animations and media content.

Final words

Now you know several techniques to create text with patterned fills, including animated ones. Even if we can’t use some of listed techniques right now, I’m sure that we will be able to use them in the future. And now, I think it’s time for you to start creating some impressive text effects for your next project .

Demo     Download

courtesy:http://tympanus.net

Animated TextFills All

| Canvas, CSS3, CSS3 Animation, HTML5, Javascript, Responsive, SVG | 0 Comments
About The Author
- Thank you for visiting my profile page. I have over 8+ years experience in web development. Product quality, Client service, and results are my priority. I offer unparalleled expertise and services in web design and front-end development, including responsive websites (Using Twitter bootstrap framework) and Hybrid Mobile Application (Using IONIC Framework) . I am proficient in a wide spectrum of technologies and learn new ones fast. I am seeking new opportunities to design, build and extend websites and web applications.