Creative Coding with SVGs
zuubaDigital

Text

codepen practice page

The text element

You can add text to your SVG using… the text element. In the example below the browser will apply the font-family css styles defined for the containing page.

1 2 3 4 5 6 <svg width="500" height="500" viewBox="0 0 500 500" <text x="50" y="250">This is the text element</text> </svg>
This is the text element

font-size, font-family, and font-weight

The SVG font-size, font-family, and font-weight attributes should be familiar to anyone who has used CSS. We can, in fact use CSS instead of presentation attributes to style text elements, if we so choose. We'll discuss that in a later section.

1 2 3 4 5 6 7 8 <text x="65" y="250" font-size="50" font-family="Arial, Helvetica, sans-serif" font-weight="normal"> The text element </text>
The text element

y, dominant-baseline

The y attribute is used to position the text relative to its dominant-baseline, which is, by default, directly under the text. In the image below the dominant baseline is represented by the black line.

1 2 3 4 5 6 7 <text x="65" y="100" dominant-baseline="auto" fill="black" font-family="Arial" font-size="32"> The text element </text>

text_x_y.png

There are three possible values for dominant-baseline: auto (baseline is at the bottom), middle (baseline is in the middle), and hanging (baseline is at the top). In this example I've created horizontal lines at the same y value as the text to show how dominant-baseline affects the text position.

dominant-baseline: "auto" (under the text) | "middle" | "hanging"
dominant-baseline-autodominant-baseline-middledominant-baseline-hanging

x, text-anchor

The text-anchor attribute is used to set the horizontal alignment of the text element. By default the x attribute positions the text element horizontally using it's left edge. Each of the three text elements below has the same x position (250, the middle of the svg), but different text-anchor positions.

text-anchor: "auto" (start) | "middle" | "end
1 2 3 4 5 6 7 <text x="250" y="250" fill="black" fontSize="30" textAnchor="middle"> text-anchor middle </text>
text-anchor starttext-anchor middletext-anchor end

tspan

The tspan element allows you apply formatting or change the position of individual sections of text within the text element.

1 2 3 4 5 6 7 8 9 10 11 <text x="250" y="250" text-anchor="middle" font-size="35" fill="black"> styling <tspan fill="red" fontSize="45"> with </tspan> tspan </text>
stylingwithtspan

tspan - x, y

The x, y attributes allow for “absolute” positioning of the tspan. However, you'll need to be careful - any text that follows the tspan will also have this new positioning, as TSPAN has in the example below, even though it sits outside the tspan element!

1 2 3 4 5 6 7 8 9 10 11 12 13 <text x="250" y="250" text-anchor="middle" font-size="35" fill="black"> styling <tspan x="100" y="50" fill="red"> with </tspan> TSPAN </text>
stylingwithTSPAN

tspan dx, dy

The dx, dy attributes relatively moves tspan text from where it would normally be. In this example below the text has been shifted vertically from the rest of the text element.

1 2 3 4 5 6 7 8 9 10 11 12 13 <text x="250" y="250" text-anchor="middle" font-size="35" fill="black" > styling <tspan dx="0" dy="100" fill="red"> with </tspan> TSPAN </text>
styling withTSPAN

tspan - rotate

The rotate attribute allows for the rotation of the tspan text.

1 2 3 4 5 6 7 8 9 10 11 12 13 <text x="250" y="250" text-anchor="middle" font-size="35" fill="black" > styling <tspan fill="red" rotate="25"> with </tspan> TSPAN </text>
stylingwithTSPAN

You can rotate individual characters by passing in a series of rotation values. Make sure to pass in the same number of values as there are characters in the tspan.

1 2 3 4 5 6 7 8 9 10 11 12 13 <text x="250" y="250" text-anchor="middle" font-size="35" fill="black" > styling <tspan fill="red" rotate="-25 0 25 90"> with </tspan> TSPAN </text>
stylingwithTSPAN

textpath

The textpath element allows you to connect your text to the shape of a path.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, reiciendis libero. Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi! Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi!

First, you'll need a path you want your text to wrap around, and some text.

1 2 3 4 <path d="M37.5 159.5C149.1 158.7 179.333 324.5 180.5 407.5L239 90.5L312 407.5C308.667 319.833 325.7 147.5 420.5 159.5" stroke="#000" stroke-width="2" />
path element
1 2 3 4 5 6 7 <text x="0" y="150" font-size="16" fill="black"> Lorem ipsum dolor sit amet consectetur adipisicing elit.. </text>
text element
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, reiciendis libero. Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi! Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi!

Give the path element an id - we'll use mypath for this example.

<path
    id="mypath"
    d="M37.5 159.5C149.1...

Enclose the text you want to wrap in the textPath element, and pass in the id of the path in the href attribute. It will look something like this:

<text>
  <textpath href="#mypath">
    Lorem ipsum dolor sit amet consectetur adipisicing elit..
  </textpath>
</text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, reiciendis libero. Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi! Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi!

You can hide the path by just setting the stroke attribute to "none"

1 2 3 4 5 <path id="mypath" d="M37.5 159.5C149.1 158.7 179.333 324.5 180.5 407.5L239 90.5L312 407.5C308.667 319.833 325.7 147.5 420.5 159.5" stroke="none" />
hiding the path
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, reiciendis libero. Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi! Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi!

startOffset

You can change the start point of the text along the path by using the startOffset attribute, and passing in a percentage value. (The percentage is that of the total length of the path)

1 2 3 <textPath startOffset="10%" href="#thebigw">sample text...</textPath>
startOffset
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate, reiciendis libero. Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi! Earum, ullam dicta provident sapiente minima consectetur deleniti nulla quibusdam, voluptatum illo quisquam veniam molestiae commodi doloribus molestias sequi!

CSS styling

Setting the font-family of svg text is no different than doing so for any other text in your html page. For example, if you set the body text for your document to serif, it will also be applied to your svg text

css example
1 2 3 body { font-family: serif; }
css styling
css svg text element selector
1 2 3 text { font-family: serif; }
css svg text element selector
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <svg width="500" height="200" viewbox="0 0 500 200"> <style> .text-style { font-family: serif; font-size: 100px; font-weight: bold; fill: #eaeaea; stroke: #212121; stroke-width: 2; } </style> <text class="text-style" x="250" y="100" text-anchor="middle">css styling</text> </svg>
css styling

foreignObject

SVG text doesn't wrap. You can solve this by wrapping html text with foreignObject element within your svg.

1 2 3 4 5 6 7 <svg width="500" height="500" viewbox="0 0 500 500"> <foreignObject x="125" y="100" width="250" height="160"> <div xmlns="http://www.w3.org/1999/xhtml"> This is text that wraps. You need to put it in a <strong>foreignObject</strong> tag and include the namespace for it to work! </div> </foreignObject> </svg>
This is text that wraps. You need to put it in a foreignObject tag and include the namespace for it to work!