Text Decoration in SVG 2

Background

SVG 1.1 includes simple text decoration based on CSS 2 with one main difference: SVG uses the 'fill' and 'stroke' values to paint the text decorations.

SVG 1.1 underlined text showing 'fill' and 'stroke'.

A line of SVG text with red 'fill' and blue 'stroke'. SVG

SVG cannot only use solid colors for painting the decorations, but can also use gradients and patterns.

One thing to note about text decorations in SVG is that the 'fill' and 'stroke' values of a decoration are set to the 'fill' and 'stroke' values of an element when the 'text-decoration' property is explicitly set. These values are applied to all child elements even if the child elements have different 'fill' and 'stroke' values. (This parallels what is done with HTML/CSS2.)

The <tspan> for 'same' has a different 'stroke' value; the <tspan> for 'different' has a different 'stroke value and the 'text-decoration' property is explicitly set to 'underline'. SVG

CSS 3 Text Decorations

CSS 3 Text Decorations introduces the new properties:

In addition, the CSS 2.1 'text-decoration' property is converted to a shorthand.

The 'text-decoration-line' and 'text-decoration-style' properties are immediately usable in SVG.

Example use of 'text-decoration-style' in SVG 2 as implemented in Inkscape. SVG

The 'text-decoration-color' property has some problems. SVG does not use the 'color' property for painting text so it is not clear how 'text-decoration-color' should be mapped to the 'fill' and 'stroke' of SVG text decoration. 'text-decoration-color' also does not allow the use of gradients, patterns, or other SVG paints.

The 'text-decoration-color' property is quite useful. It allows one to have a different color stroke from the text color without resorting to nested <tspan>'s (in SVG) or nested <span>'s (in HTML).

With CSS2, the crossed-out section requires two nested <tspans>, the outer to set the 'fill' to red and the 'text-decoration' to 'line-through' and the inner to restore the 'fill' to black. SVG

This leads to the question, how should text decoration paint be handled with CSS 3 text decorations. Here are some options:

Option 1: Don't allow 'text-decoration-color'

This would be the simplest route. SVG would then still require the nested <tspan> 'hack' shown above to set a different decoration paint than used for the text.

Option 2: Let 'text-decoration-color' set text 'fill'

This is also fairly straight forward to implement but it breaks the SVG pattern of treating 'fill' and 'stroke' the same in terms of paints.

Option 3: Add new SVG only 'text-decoration-fill' and 'text-decoration-stroke' properties

This keeps the SVG pattern of treating the 'fill' and 'stroke' the same way and it allows the use of all SVG type paints (gradients, etc.). This actually is trivial to implement as any SVG renderer already has to track the 'fill' and 'stroke' paints used for text decoration separately due to the inheritance rules.

Inkscape trunk implements CSS3 text decorations (rendering only), for the moment with option 2 but option 3 is highly preferred and is only a few lines of code to implement.


Appendix: Implementation Observations

  1. Chrome implements CSS3 text decorations in HTML but not SVG except that it recognizes 'text-decoration-line' as an alias for 'text-decoration' in SVG.
  2. Chrome text decoration does not respect the 'paint-order' property (it does use 'paint-order' for rendering text).
  3. Chrome seems to have problems with decorating white space.
  4. Firefox only implements CSS2 text decorations.
  5. Inkscape trunk implements CSS3 text decorations (rendering only).

Appendix: CSS Text Decoration in HTML

CSS 2

Underline Overline Line-through Blink Underline and Overline

CSS 3 - Shorthand

Underline Solid Blue Overline Double Red Line-through Dashed Green Blink Wavy Purple Underline Wavy Purple

CSS 3 - Longhand

Underline Solid Blue Overline Double Red Line-through Dashed Green Blink Wavy Purple Underline Wavy Purple

Inheritance

This is an example of crossed out words with a different color text decoration.

This is an emphasized word. This is an emphasized word. This is an emphasized word. This is an emphasized word.