SVG text tag: designing pretty pages titles

We can improve the graphics of a site in full compatibility with 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 ... less graphic qualities.

SVG has four features missing in CSS for 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. For web users, we should therefore insert the SVG code in H1 tag on each page, like this:

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

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

Text with a border

The 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>
Compatibility Full compatibility on Firefox, Chrome, Internet Explorer 10, Safari, Opera. The CSS code is ignored, rendering relies on the SVG code.
Partial support for Internet Explorer 9. SVG is supported but not the filter attribute.
Partial compatibility of Internet Explorer prior to version 9. SVG code is ignored and text rendering depends on CSS.