The CSS Corner: writing-mode

Introduction

The writing-mode property enables text layout for non-Latin languages like Japanese and Arabic. Supported in IE since release 5.5, this property has been significantly updated in IE8. Our goals were threefold:

  • To make its behavior more predictable for developers
  • To align with relatively newer CSS concepts like shrink-to-fit sizing
  • To further the CSS3 Text Layout module by providing the first implementation.

This post walks through the basics of the new implementation and the background you need to start experimenting. We’re looking forward to your feedback!

The Basics – properties and values

The writing-mode property, as defined in CSS3 Text Layout, is a shorthand for the ‘direction’ and ‘block-progression’ properties. Direction can be thought of as the flow of characters on a line; ‘block-progression’ can be thought of as the direction of line flow.­ The following table (mostly borrowed from the spec) shows its eight possible values:

writing-mode

direction

block-progression

Common Usage:

lr-tb

ltr

Tb

Latin-based, Greek, Cyrillic writing systems (and many others)

rl-tb

rtl

Tb

Arabic, Hebrew writing systems

tb-rl

ltr

Rl

East Asian writing systems in vertical mode

bt-rl

rtl

Rl

Arabic script block quote embedded in East Asian vertical text

tb-lr

ltr

Lr

Mongolian script writing system

bt-lr

rtl

Lr

Arabic script block quote embedded in Mongolian script document

lr-bt

ltr

Bt

None

rl-bt

rtl

Bt

None

(Note that the last two rows refer to combinations that are currently undefined because they are not used by the world’s scripts and languages. For completeness they are implemented in IE8.)

In understanding vertical text layout it is important to agree on terminology as the meaning of width and height can change based on context. We always refer to width and height as physical properties i.e. width is always horizontal and height is always vertical. In addition left, top, right and bottom are also considered physical.

The best way to understand writing-mode and vertical text layout is through examples. The simple scenarios below will help you understand sizing, overflow and tables.

Block dimensions

Vertical sizing algorithms swap width and height calculations, so the algorithm which was used for width in horizontal layout is now used for height in vertical layout.

Consider this example:

example #1

Here no widths and heights are specified for the two div elements; the first is parallel to the parent body, the second is orthogonal with writing-mode set to tb-lr.

Notice how the first div is as wide as the viewport and its height fits its content. This is as per the normal rules of CSS.

The sizing of the second div is exactly analogous with width and height swapped – the height is now the same as that of the viewport, and the width is sized to fit the content.

Note, viewport is used in this example, but if the body’s height was specified then its value would be used to compute the auto height as expected. The reasoning behind this behavior is that the user can scroll to the vertical content (if the first horizontal div was very long) and then start scrolling horizontally while all content still fits the vertical landscape of the viewport.

This example becomes more interesting as one adds a second orthogonal div, this time with a relative size:

example #2 

The second vertical div has width set to 50%; notice how its physical width is 50% of that of viewport (body).

Note that the last block appears below the previous one because the block flow of the parent (body) is top to bottom. It may be natural to assume that the writing-mode of an element affects the block progression of the element itself but that is not the case. Changing block progression on the body to LR would place the blocks side by side. However, if BODY was to overflow horizontally it would do so in the writing direction of its parent. In this case the HTML element which is LR-TB, thus, overflow will be to the right thus hiding the beginning of the content. This is a subtle yet very important point since most users would expect that the origin point (where the first letter of the content appears) will be visible regardless of overflow. The reason is that overflow to the left and top (assuming LR-TB direction) is not a scrollable and hence clip-able area (see next section).

Overflow in vertical layout

Handling overflow in vertical layout is still under debate. IE8 positions scrollbars according to the direction of overflow i.e. if content overflows to the left of the element then the vertical scrollbar will be on the left side.

Consider an example where a fixed-sized element has writing-mode:bt-rl and overflowing content.

example #3

Notice the position of the scrollbars and also their initial state. Since the start of the content is the physical bottom of the element, that is the initial position of the vertical scroller.

Another interesting case is when the element is too wide for the window, thus forcing viewport scrollbars:

example #4

The start of the text is off the screen and the user must scroll right to see it. In addition the vertical scroller is not accessible after the user has scrolled to the right. This may seem odd but it is the expected result as the direction of the parent (body) is LR-TB. When developing pages in mixed mode layout, consider the effects of overflow.

Vertical layout and tables

In the case of vertical tables, rows become vertical and columns become horizontal. Using the following mark-up…

 <body writing-mode=”??-??”>
     ABCDEF
     <table>
          <tr> 
              <td> 1 </td> <td> 2 </td> <td> 3 </td>
          </tr>
          <tr>
              <td> 4 </td> <td> 5 </td> <td> 6 </td>
          </tr>
          <tr>
              <td> 7 </td> <td> 8 </td> <td> 9 </td>
          </tr>
     </table>
</body>

…these are the results in all eight modes:

view of all IE8 writing modes

Table sizing follows the same principle as box sizing: height and width calculations are swapped. The cell width / column width / table width calculation algorithms now use all height values. The cell height / row height / table height calculation algorithms now use all width values.

Padding, Margins and Percentage values

Most web authors who use CSS to design their web sites know that understanding margin collapsing takes time. This is why one of our goals while designing and implementing multiple writing directions was to limit any added complexity to margin collapsing logic. In essence, margin collapsing follows the same rules as in CSS 2.1 – 8.3.1. The only difference is that margins are collapsed in the direction of block-progression. The reason for that is that when an orthogonal change of direction (vertical inside of horizontal) occurs, the element changing direction becomes a Block Formatting Context. Hence, no margins of its nested elements (vertical ones) are collapsed with it. This is illustrated in the following example – note that none of nested blocks are collapsing their margins with the container (the dark-blue block) even thought the container has no borders.

example #5

Percentage values for padding and margins are computed based on the logical width. That is, the computed value of width if parent element is in horizontal or computed value of height if parent element is in vertical block-progression.

Thanks for reading. We will be following the comments for feedback and look forward to hearing from you.

Saloni Mira Rai – Program Manager and
Rossen Atanassov – Software Developer