SVG text tag: designing pretty pages titles

Graphics of a site may be improved in full compatibility thank to the SVG text tag.

Most browsers now recognize the SVG code, and when this is not the case, the tags are ignored and the browser sees the HTML code so that the page is fully functional and its contents still presented to the user ... in the old way.

SVG has four features that are missing from CSS to text rendering:

  1. Outline.
  2. Gradients.
  3. Texture.
  4. Effect of light.

It is possible to convert an SVG filter to a CSS attribute, but this will only work on Firefox.

To use SVG with a fallback to CSS for old browsers, we put the SVG code in H1 tag, like this:

<h1>
  <svg><text>... Title ...</text></svg>
</h1>

On older browsers the <svg> and, <text> tags are ignored, only remain <h1>title</h1>. For search engines too.

Text with a border

The SVG text tag allows you to display a text and apply properties. Fill and stroke properties allow filling with a color and drawing a border.

Demonstration
<svg width="100%" height="64px">
  <text font-size="64" fill="#bbccee" stroke="#003366" stroke-width="1px" 
           x="0" y="48" font-family="Arial">
    Demonstration
  </text>
</svg>

Using gradients

We build a gradient and stop-color attributes define the limits of areas of degraded colors. We could add more than two.

Demonstration
<svg width="100%" height="64px">
  <linearGradient id="shaded" x1="0" x2="0" y1="0" y2="1">
    <stop offset="0%" stop-color="#bbccee" stop-opacity="0"/>
    <stop offset="80%" stop-color="#6699cc"/>
  </linearGradient>
  <text font-size="64" fill="url(#shaded)" stroke="#000" stroke-width="1px" x="0" y="48px"
     font-family="Arial">
    Demonstration
  </text>
</svg>  

Adding a shadow

We build a filter that creates a shadow of the original image and assigns it through the filter property. I recommend a rounded font because SVG does not provide good shade results on straight lines.

Demonstration
<svg  width="100%" height="64px">
  <defs>
    <filter id="drop-shadow" filterUnits="userSpaceOnUse" width="100%" height="92">
      <feGaussianBlur in="SourceAlpha" result="blur-out" stdDeviation="3" />
      <feOffset in="blur-out" result="shadowoffset" dx="2" dy="2"/>
      <feBlend in="SourceGraphic" in2="shadowoffset" mode="normal"/>
    </filter>
  </defs>
  <linearGradient id="shaded" x1="0" x2="0" y1="0" y2="1">
    <stop offset="0%" stop-color="#bbccee" stop-opacity="0"/>
    <stop offset="70%" stop-color="#6699cc"/>
  </linearGradient>
  <text font-size="64" fill="url(#shaded)" stroke="#336" stroke-width="1px" 
      filter="url(#drop-shadow)" x="0" y="48px"  font-family="Arial">
    Demonstration
  </text>
</svg>

Using a texture

The image tag loads an image as texture. This applies in the same way as a gradient.

Demonstration
<svg height="64px" width="480px">
 <pattern id="pattern1" patternUnits="userSpaceOnUse" viewBox="0 0 184 162" width="184" height="162">
   <image xlink:href="texture.jpg" width="184" height="162"/>
  </pattern>
  <text x="0" y="48" font-size="64" fill="url(#pattern1)" stroke="#000" stroke-width="1px"
           font-family="Arial">
    Demonstration
  </text>
</svg>

Adding a light effect to the texture

We define a filter that creates a new image. The feComposite attribute merges the original image and the image with the filter.

Demonstration
<svg height="64px" width="480px">
  <defs>
  <filter id="lighting">
    <feGaussianBlur in="SourceAlpha" stdDeviation = "1" result = "blur1"/>
    <feSpecularLighting result="specOut" in="blur1" specularExponent="20" lighting-color="#fff">
      <fePointLight x="-200" y="30" z="150"/>
    </feSpecularLighting>
    <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
  </filter>
 </defs>
 <pattern id="pattern1" patternUnits="userSpaceOnUse" viewBox="0 0 184 162" width="184" height="162">
  <image xlink:href="texture.jpg" width="184" height="162"/>
 </pattern>
 <text filter="url(#lighting)" x="0" y="48" fill="url(#pattern1)" stroke="#000" stroke-width="1px"
           font-size="64px" font-family="Arial">
    Demonstration
 </text>
</svg>

Adding a shadow and light effect with a texture

This time we need two filters but the standard does not allow to apply multiple filters to an object, so we create a single filter that combines the two effects.
The feMerge tag contains two nodes corresponding to a shading effect and light effect. The text is still filled with a texture through the fill tag and the filter tag applies the composite filter.

Demonstration
<svg height="64px" width="480px">
 <defs>
   <filter id="shadelight">
      <feGaussianBlur in="SourceAlpha" stdDeviation = "1" result = "lightblur"/>
      <feSpecularLighting result="specOut" in="lightblur" specularExponent="20" lighting-color="#fff">
          <fePointLight x="-200" y="30" z="150"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"
                             result="lighted" />
      <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blurred" />
      <feOffset in="blurred" result="shadowoffset" dx="3" dy="3"/>
      <feMerge>
        <feMergeNode in="shadowoffset"/>
        <feMergeNode in="lighted"/>
       </feMerge>
    </filter>
  </defs>
  <pattern id="pattern1" patternUnits="userSpaceOnUse" viewBox="0 0 184 162" width="184" height="162">
    <image xlink:href="texture.jpg" width="184" height="162"/>
  </pattern>
  <text filter="url(#shadelight)" x="0" y="48" fill="url(#pattern1)" stroke="#221" stroke-width="1px"
           font-size="64" font-family="Arial">
    Demonstration
  </text>
</svg>