Skip to content

Add Canvas writingMode and textOrientation#12153

Open
schenney-chromium wants to merge 3 commits intowhatwg:mainfrom
schenney-chromium:writing-mode
Open

Add Canvas writingMode and textOrientation#12153
schenney-chromium wants to merge 3 commits intowhatwg:mainfrom
schenney-chromium:writing-mode

Conversation

@schenney-chromium
Copy link
Contributor

@schenney-chromium schenney-chromium commented Feb 11, 2026

Add canvas text style attributes for writingMode and textOrientation, as discussed in #issue11449

The writingMode attribute determines the orientation of the text string when measured and rendered, while textOrientation controls the orientation of individual glyphs within the string.

In addition to documenting the attributes, this PR also updates the text preparation algorithm and the measureText algorithm. Some other things are re-worded to make them direction agnostic, primarily by using CSS inline direction terminology.

The choices made in defining behavior, particularly around the alignment attributes and the text metric bounding box attributes, are an attempt to capture the expectations of developers. Of particular concern is anything related to text baseline metrics which have no obvious interpretation for vertical text.


/canvas.html ( diff )
/infrastructure.html ( diff )

@zcorpan
Copy link
Member

zcorpan commented Feb 12, 2026

cc @whatwg/canvas

@dbaron
Copy link
Member

dbaron commented Feb 12, 2026

cc @fantasai

<p>Can be set, to change the writing mode. The possible values and their meanings are given
below. Other values are ignored. The default is "<code
data-x="dom-context-2d-writingMode-horizontal">horizontal</code>".</p>
</dd>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These domintro boxes are supposed to be self-contained. I see "given below" is an established pattern, but it seems wrong. Can we describe these new ones here and file an issue to redo the older ones?

The level of detail can be fairly low, just enough so someone knows what to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this problem too. In particular the developer version of the spec does not include the "given below" descriptions. I started another PR at some point to address this but dropped it. I can pick it up again.

object implementing the <code>CanvasTextDrawingStyles</code> interface is created, the <code
data-x="dom-context-2d-writingMode">writingMode</code> attribute must initially have the value
"<code data-x="dom-context-2d-writingMode-horizontal">horizontal</code>".</p>
</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this modify an associated concept of the context instead of continuing to conflate public and private API. We should also use the modern "getter steps" and "setter steps" terminology.


<div algorithm>
<p>The <dfn attribute for="CanvasTextDrawingStyles"><code
data-x="dom-context-2d-textOrientation">textOrientation</code></dfn> IDL attribute, on getting,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

</dl>

<p>The <code data-x="dom-context-2d-writingMode">writingMode</code> attribute's allowed keywords
are as follows:</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this section adds much. Some of it should be inside the domintro and some of it should be part of the normative processing model probably.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Will do.

<tr>
<td><span>'writing-mode'</span></td>
<td><var>target</var>'s <code data-x="dom-context-2d-writingMode">writingMode</code>
using "vertical-rl" for <code data-x="dom-context-2d-writingMode-vertical">vertical</code>.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be marked up as a string. And maybe it should link back to its definition?


<p>Horizontal position:</p>
<p>Apply the appropriate step from the following list to determine the value of
<var>inline offset</var>:</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use camel case for variable names. And I'd make the switch return a value. That seems clearer.

</dl>
</li>

<li><p>Set the <var>anchor point</var> as follows:</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping is wrong here as the <li> has multiple children.

<p>Vertical position:</p>
<li>
<p>Apply the appropriate step from the following list to determine the value of
<var>baseline offset</var>:</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Camel case plus return from the switch.


<li><p>Return <var>result</var>, <var>physical alignment</var>, and the inline
box.</p></li>
<li><p>Return <var>result</var>, the inline box and <var>anchor point</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oxford comma.

@dbaron
Copy link
Member

dbaron commented Feb 13, 2026

I think it's worth considering whether the divergence from CSS (just vertical rather than vertical-rl and vertical-lr) is going to cause problems in the long term.

(Is all canvas text today single-line? How likely is it to stay that way?)

@schenney-chromium
Copy link
Contributor Author

I think it's worth considering whether the divergence from CSS (just vertical rather than vertical-rl and vertical-lr) is going to cause problems in the long term.

I've thought about these issues. My reasoning on vertical-rl and vertical-lr is that they imply different block flow directions in CSS, so developers familiar with these would expect different interpretations of textBaseline in canvas code. To me that's added complexity with little practical value.

(Is all canvas text today single-line? How likely is it to stay that way?)

All canvas text right now is single line. If you want multi-line you put the textBaseline at a point that makes sense for the font (a point that should be consistently spaced from line to line) and you draw the lines one at a time with constant offset in the block direction. I don't think distinguishing between "block" direction for each individual line help with this.

There have been various proposals for more complex text styling in canvas including methods for laying out multiple lines, but they have all been made redundant by HTML-in-Canvas. We've even got TAG feedback on other canvas text features saying they would rather we moved HTML-in-Canvas forward due to the accessibility benefits. I'm not great at predicting the future but HTML-in-Canvas seems more likely than not. Once it exists I think the desire for new canvas APIs for styled and multi-line text will disappear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants