Proposals/Wrapping Text

From SVG

These are proposals for simple wrapping of text into a rectangular area.

Width and Height

This proposal is based on the geometric dimensions of width and height of the text rendering area. In CSS, this area is called the "inner box", and is the area inside the margins and padding.

Obviously, the effects of these dimensions must be reversed for vertical text, such as some Asian scripts and normally-horizontal scripts that are being rendered vertically for stylistic reasons.

Width

Width is the most important determinant for horizontal text, because it determines the point at which text is wrapped to the next line; whether words are broken and hyphenated depends on other text layout properties.

<code>
   <text x="20" y="30" style="width:200px; font-size: 20px;">This is some text that should wrap after 200 pixels to the next line, 
   without the need for a 'tspan'. That makes sense, right?</text>
</code>

Height

Height is important for vertical text, in which it plays the same role as width does for horizontal text.

<code>
   <text x="20" y="30" style="height:65px; font-size: 20px;">该文本将换行后三个词</text>
</code>

Height in horizontal text also has several considerations, since it determines how many lines of text will be rendered. There are several options for horizontal text that does not fit in the rendered area:

  • if the overflow property is visible, each new line will render regardless of area height
  • if the overflow property is clipped, only the portion of the characters that are inside the rendering area will be shown
    • in some cases, the final line of the text may not precisely correspond to the rendered area, and the bottom text may appear to be clipped (that is, the lower portion of the characters may not be rendered; sometimes this is desirable (the author may want the user to know there is more text to scroll through), and sometimes it is not (the author may wish the text to look tidy); we could provide a new value for the overflow property to allow the author control over whether clipped text renders in part, in whole, or not at all.
<code>
   <text x="20" y="30" style="width:200px; height:30px; font-size: 20px;">This should wrap after 200 pixels, 
   and subsequent lines should be cut off.</text>
</code>

Positioning (x and y)

The x and y attributes/properties would behave the same as they do today, with y representing the origin of the glyph cell (e.g., the baseline of the text... do I mean character cell here?).

This default behavior for y is different than CSS's top property, which defines the origin as the top of the rendering area, rather than the baseline. For typical rendering, and backwards compatibility, the baseline origin is the expected default behavior.

However, there is also a common use case for the origin being the top of the rendering area; specifically, if you are rendering text "inside" a visible rectangle, it is easier to align if the origins are the same. To meet this use case, authors can use SVG's alignment-baseline property with a value of top (or its wordier-but-more-internationalized equivalent text-before-edge), which will align the text origin to the top of the character cell, which is also the top of the rendering area.


Internationalized Text

If we want to decouple geometry from text-rendering, to make it possible for the same SVG to have translated text between vertical and horizontal text without changing the styling assumptions, we could introduce new properties that do not make assumptions about width and height.

Note: This proposal was an alternative to the main proposal, and is being deferred to later CSS behavior.

text-wrap

The proposed text-wrap property would take length values, and would wrap text after the desired length in either the horizontal or vertical direction.

text-extent

The proposed text-extent property would take length values, and may introduce a new unit line, and would describe how many lines of wrapped text would be rendered.


<code>
   <text x="20" y="30" style="text-wrap:200px; text-extent:3line; font-size: 20px;">
      This text should wrap after 200 pixels 
      with either horizontal or vertical text, and subsequent lines 
      should be cut off after three lines of text.
   </text>
</code>