Canvas Text
HTML5 canvas lets you draw text using font properties. See examples of fillText, strokeText, adding color, and centering text.
The HTML5 <canvas> element lets you draw text directly onto a bitmap surface. Unlike regular DOM text, canvas text is painted as pixels — once drawn, it has no markup, cannot be selected, copied, or read by screen readers, and never reflows. You control its appearance through the drawing context (getContext("2d")) rather than with CSS, which makes canvas text ideal for graphics, charts, game UI, and image generation, but a poor choice for body copy.
This chapter builds on the Canvas introduction and the drawing basics. For coloring text with gradients, see Canvas Gradients.
Properties and Methods
| Property / Method | Description |
|---|---|
| font | It returns the current font settings and can be set to change the font. |
| textAlign | It returns the current text alignment settings and can be set to change the alignment. The property has the following values: start, end, left, right, and center. Note that start and end depend on the text direction. |
| textBaseline | It returns the current baseline alignment settings and can be set to change the baseline alignment. The property has the following values: top, hanging, middle, alphabetic, ideographic, and bottom. |
| fillStyle | Sets the color used to fill text. |
| strokeStyle | Sets the color used to stroke text. |
| fillText(text, x, y [, maxWidth]) | It draws a filled text at the position indicated by the given coordinates x and y. The optional maxWidth argument scales the text down so it never exceeds that width in pixels. |
| strokeText(text, x, y [, maxWidth]) | It strokes (outlines) the text at the position indicated by the given coordinates x and y. It also accepts the optional maxWidth argument. |
| measureText(text) | It returns a TextMetrics object whose width property tells you how wide the text would be with the current font. Useful for centering, wrapping, or fitting text. |
The font property
The font property accepts the same value as the CSS font shorthand. You can combine style, weight, size, and family in one string, for example "italic bold 18px serif". If you set only a size and family (e.g. "30px Arial"), the other values fall back to their defaults. Always include a size and a family — omitting either makes the declaration invalid and the change is ignored.
ctx.font = "italic bold 18px serif";
ctx.font = "small-caps 24px 'Courier New', monospace";
ctx.font = "30px Arial"; // size + family only — also validExample of the fillText() method:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 70, 80);
</script>
</body>
</html>Example of the strokeText() method:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="250" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
ctx.font = "27px Arial";
ctx.strokeText("Canvas text", 40, 70);
</script>
</body>
</html>Example of adding color and centering text:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="400" height="250" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
ctx.font = "40px Comic Sans MS";
ctx.fillStyle = "red";
ctx.textAlign = "center";
ctx.fillText("Canvas Text", canvas.width / 2, canvas.height / 2);
</script>
</body>
</html>Aligning text with textAlign
The x coordinate you pass to fillText/strokeText is the anchor point. The textAlign property decides where the text sits relative to that anchor. The default is "start", which follows the text direction — so it behaves like "left" for left-to-right text and like "right" for right-to-left text. With "left" the anchor is the left edge; with "center" the text is centered on the anchor; with "right" the anchor is the right edge; "start" and "end" map to the edges according to the text direction.
The example below draws a vertical reference line at x = 150, then prints three labels anchored to that same x with different textAlign values so you can see how each one positions the text.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="300" height="160" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
const x = 150;
// Reference line at the anchor x
ctx.strokeStyle = "#d3d3d3";
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, 160);
ctx.stroke();
ctx.font = "20px Arial";
ctx.fillStyle = "black";
ctx.textAlign = "left";
ctx.fillText("left", x, 40);
ctx.textAlign = "center";
ctx.fillText("center", x, 80);
ctx.textAlign = "right";
ctx.fillText("right", x, 120);
</script>
</body>
</html>Positioning text vertically with textBaseline
The y coordinate is measured against the text's baseline, and textBaseline controls which part of the glyphs that baseline refers to. The default is "alphabetic", where y sits roughly on the bottom of letters like "x". Set it to "top" to make y the top of the text, or "middle" to vertically center the text on y — handy when you want the text centered in a box.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="320" height="120" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
const y = 60;
// Reference line at the anchor y
ctx.strokeStyle = "#d3d3d3";
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(320, y);
ctx.stroke();
ctx.font = "20px Arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top";
ctx.fillText("top", 10, y);
ctx.textBaseline = "middle";
ctx.fillText("middle", 90, y);
ctx.textBaseline = "bottom";
ctx.fillText("bottom", 200, y);
</script>
</body>
</html>Outlined-fill text (strokeText + fillText)
You can combine a fill and a stroke on the same text to get an outlined effect. Call fillText first to lay down the solid color, then strokeText on top so the outline stays crisp. Set fillStyle, strokeStyle, and lineWidth to control the look.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="360" height="120" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
ctx.font = "bold 60px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const x = canvas.width / 2;
const y = canvas.height / 2;
ctx.fillStyle = "gold";
ctx.fillText("Canvas", x, y);
ctx.lineWidth = 2;
ctx.strokeStyle = "black";
ctx.strokeText("Canvas", x, y);
</script>
</body>
</html>Measuring text with measureText()
measureText() returns a TextMetrics object describing how the text would be rendered with the current font. Its width property is the most commonly used: you can subtract it from the canvas width to center text manually, or compare it against an available width to break long text into multiple lines.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<canvas id="exampleCanvas" width="320" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
<script>
const canvas = document.getElementById("exampleCanvas");
const ctx = canvas.getContext("2d");
const text = "Measured!";
ctx.font = "30px Arial";
const metrics = ctx.measureText(text);
// Center horizontally without changing textAlign
const x = (canvas.width - metrics.width) / 2;
ctx.fillText(text, x, 55);
</script>
</body>
</html>Tip: when you only need the text to fit a fixed width, the simpler option is the optional
maxWidthargument —ctx.fillText("Long label", 10, 40, 120)shrinks the text so it never exceeds 120 pixels.