Fitting Text Into a Box

Background

Fitting text into a box is a common problem. The designer has a given region, be it a button, a label, a node in a flowchart, etc. and needs to fit some text into that region. This is the opposite of sizing the box to fit the text.

SVG has the 'textLength' attribute which is often used to fit text into a given region. The intent of the attribute was to allow for alignment of text objects regardless of how the user agent performs the text layout (for example, it can account for the use of a substitute font face). There is a note in the SVG 2 specification noting that this attribute is not intended to "obtain effects such as shrinking or expanding text".

LABEL LABEL

Example of using 'textLength' to fit text into a label.
Left: Unadjusted text. Right: 'textLength' set to 95% of box width.

The question then becomes: How should one adjust text to fit inside a given box? Is the solution one that can/should be shared between SVG and CSS?

Requested Features

We have had requests for more flexible ways of scaling text to fit inside a box. In particular the following attributes/attribute values have been requested:

A related issue: How should 'textLength' work with multi-line text? It would be especially useful to allow text to auto-fit into a shape.

Text wrapped into a circle with padding.

Text wrapped into a circle. The text will not look as good font properties are not matched exactly.

Alternative Methods

All require JavaScript to automate.

Change 'font-size'

Easiest method.

LABEL LABEL

Left: unadjusted text. Right: 'font-size' reduced to fit.

Example:

LABEL

Use 'font-stretch'

Unimplemented in many browsers. Requires having condensed/expanded font faces.

LABEL LABEL

Use 'letter-spacing'

Unimplemented in FireFox for SVG.

LABEL LABEL

Related Issue: Vertical alignment (for horizontal text)

If you change 'font-size', how do you keep text centered vertically? Two options: use 'dominant-baseline: middle' or 'dy=0.35em'.

	<text x="50%" y="50%" style="dominant-baseline:middle">LABEL</text>
    
	<text x="50%" y="50%" dy="0.35em">LABEL</text>
    
LABEL LABEL