Writing Modes And CSS Layout
This is not an article about the practical or creative application of this property. Instead, I want to demonstrate why understanding writing modes is so important — even to those of us who rarely need to change the writing mode of a page or component. The support of multiple writing modes is key to the way that our new layout methods of Flexbox and Grid Layout have been designed. Understanding this can unlock a better understanding of how these layout methods work.
What Are Writing Modes?
The writing mode of a document or a component refers to the direction that text flows. In CSS, to work with writing modes we use the writing-mode
property. This property can take the following values:
horizontal-tb
vertical-rl
vertical-lr
sideways-rl
sideways-lr
If you are reading this article on Smashing Magazine in English, then the writing mode of this document is horizontal-tb
, or Horizontal Top To Bottom. In English, sentences are written horizontally — the first letter of each line starting on the left.
A language such as Arabic also has a horizontal-tb
writing mode. It is written horizontally, top to bottom, however Arabic script is written right to left, and so sentences in Arabic start on the right.
Chinese, Japanese and Korean are written vertically, with the first character of the first sentence being top right. Following sentences being added to the left. Therefore, the writing mode used is vertical-rl
. A vertical writing mode running from right to left.
Mongolian is also written vertically, but from left to right. Therefore, should you want to typeset Mongolian script you would use the writing mode vertical-lr
.
The other two values of writing-mode
are designed more for creative purposes than for typesetting vertical scripts. Using sideways-lr
and sideways-rl
turns text sideways — even characters normally written vertically and upright. The values, unfortunately, are only supported in Firefox at the moment. The following CodePen shows all of the different values of writing-mode
, you will need to use Firefox if you want to see the sideways-*
ones in action.
Writing Modes can be used when creating a document that uses a language written using that writing mode. They can also be used creatively, for example, to set a heading vertically down the side of some content. In this article, however, I want to take a look at the impact that supporting vertical languages, and the possibility of vertical text, has on CSS layout, and across CSS in general.
Before I do so — if you are interested in the use of writing modes for vertical text — here are some useful resources:
- The W3C Internationalization site has a wealth of useful information. Read about RTL scripts and vertical text.
- Jen Simmons wrote an excellent article about CSS Writing Modes which also includes several examples from print of these modes in use.
- Thoughts on the world and our writing systems - Chen Hui Jing
- Vertical Typesetting With Writing Mode revisited - Chen Hui Jing
- The writing-mode property on MDN
The Block And Inline Dimensions
When we change the writing mode of a document, what we are doing is switching the direction of the block flow. Therefore, it quickly becomes very useful for us to understand what is meant by block and inline.
One of the first things we learn about CSS is that some elements are block elements, for example, a paragraph. These elements display one after the other in the block direction. Inline elements, such as a word in a sentence display one after the other in the inline direction. Working in a horizontal writing mode, we become used to the fact that the block dimension runs top to bottom vertically, and the inline dimension left to right horizontally.
As block and inline elements relate to the writing mode of our document, however, the inline dimension is horizontal only if we are in a horizontal writing mode. It doesn’t relate to width, but instead to inline size. The block dimension is only vertical when in a horizontal writing mode. Therefore it doesn’t relate to height, but to block size.
Logical, Flow-Relative Properties
These terms, inline size and block size are also used as the names of new CSS properties designed to reflect our new writing mode aware world. If, in a horizontal writing mode you use the property inline-size
instead of width
, it will act in exactly the same way as width - until you switch the writing mode of your component. If you use width
that will always be a physical dimension, it will always be the size of the component horizontally. If you use inline-size
, that will be the size in the inline dimension, as the below example shows.
The same is true for height
. The height
property will always be the size vertically. It relates to how tall the item is. The block-size
property, however, gives the size in the block dimension, vertically if we are in a horizontal writing mode and horizontal in a vertical one.
As I described in my article “Understanding Logical Properties And Values”, there are mappings for all of the physical properties, those which are tied to the dimensions of the screen. Once you start to think about it, so much of CSS is specified in relation to the physical layout of a screen. We set positioning, margins, padding and borders using top, right, bottom, and left. We float things left and right. Sometimes tying things to the physical dimension will be what we want, however increasingly we are thinking about our layouts without reference to physical location. The Logical Properties and Values specification rolls out this writing mode agnostic way of working right across CSS.
Writing Modes, Grid And Flexbox
When our new layout methods landed on the scene, they brought with them an agnostic way of looking at the writing mode of the component being laid out as a flex or grid layout. For the first time people were being asked to think about start and end, rather than left and right, top and bottom.
When I first started to present on the subject of CSS Grid, my early presentations were a rundown of all of the properties in the specification. I mentioned that the grid-area
property could be used to set all four lines to place a grid item. The order of those lines was not, however, the familiar top, right, bottom and left we use to set all four margins. Instead, we need to use top, left, bottom, right - the reverse of that order! Until I understood the connection between grid and writing modes, this seemed a very odd decision. I came to realize that what we are doing is setting both start lines, then both end lines. Using top, right, bottom and left would work fine if we were in a horizontal writing mode, turn the grid on its side however and that makes no sense. If we use grid-area: 1 / 2 / 3 / 5;
as in the pen below the lines are set as follows:
grid-row-start: 1;
- block startgrid-column-start: 2
- inline startgrid-row-end: 3
- block endgrid-column-end: 5
- inline end
Flexbox Rows And Columns
If you use Flexbox and add display: flex
to a container, your items will display as a row as the initial value of the flex-direction
property is row
. A row will follow the inline dimension of the writing mode in use. Therefore if your writing mode is horizontal-tb
a row runs horizontally. If the text direction of the current script is left to right then items will line up starting from the left, if it is right to left they will line up starting on the right.
Use a vertical writing mode however, such as vertical-rl
and flex-direction: row
will cause the items to lay out vertically, as the inline direction is vertical. In this next CodePen all of the examples have flex-direction: row
, only the writing mode or direction has changed.
Add flex-direction: column
, and the items layout in the block dimension of your writing mode. In a horizontal writing mode the block dimension is top to bottom, so a column is vertical. With a writing mode of vertical-rl
a column is horizontal. As with the previous example, the only difference between the below flex layouts is the writing mode being used.
Grid Auto-Placement
When using auto-placement in grid, you will see similar behavior to that in flex layout. Grid items auto-place according to the writing mode of the document. The default is to place items in rows, which will be the inline direction - horizontally in a horizontal writing mode and vertically in a vertical one.
Try changing the flow of items to column
as in the example below. The items will now flow in the block dimension - vertically in a horizontal writing mode and horizontally in a vertical one.
Grid Line-Placed Placement
Line-based placement also respects writing mode. The lines of our grid start at 1, both for rows and columns. If we position an item from column line 1 to column line 3, and are in a horizontal writing mode with a left to right direction, that item will stretch from the left-most column line across two grid tracks horizontally. Thus spanning two columns.
Change the writing mode to vertical-rl
and column line 1 will be at the top of the grid, the item spanning two tracks vertically. Still spanning two columns, but the columns are now running horizontally.
Alignment In Grid And Flexbox
One of the first places many people will have come into contact with the way Flexbox dealt with writing modes, would be when aligning items in a flex layout. If we take the flex-direction: row
example above, and use the justify-content
property to align all of the items to flex-end
the items move to the end of their row. This means that in a horizontal writing mode with left to right direct the items all move to the right, as the end of that row is on the right. If the direction is right to left, then they all move to the left.
In the vertical writing mode, they move to the bottom, assuming there is space for them to do so. I have set an inline-size
on the components in this example to ensure that we have spare space in our flex containers to see the alignment in action.
Alignment is a little easier to understand in grid layout, as we always have the two axes to play with. Grid is two-dimensional, those two dimensions are block and inline. Therefore, you can remember one rule if you want to know whether to use the properties that begin with align-
or those which begin with justify-
. In grid layout the align-
properties:- align-content
, align-items
, align-self
are used to do block axis alignment. In a horizontal writing mode that means vertically, and in a vertical writing mode horizontally.
Once again, we don’t use left and right or top and bottom, as we want our grid layout to work in exactly the same way no matter what the writing mode. So we align using start
and end
. If we align to start
on the block dimension, that will be top
when in horizontal-tb
, but will be right
when in vertical-rl
. Take a look in the example below, the alignment values are identical in both grids, the only difference is the writing mode used.
The properties justify-content
, justify-items
, justify-self
are always used for inline alignment in grid layout. That will be horizontal in a horizontal writing mode and vertical in a vertical writing mode.
Flexbox alignment is complicated somewhat by the fact that the main axis can be switched from row to column. Therefore, in Flexbox, we need to think about the alignment method as the main axis versus cross axis. The align-
properties are used on the cross axis. On the main axis, all you have is justify-content
because we deal with items as a group in Flexbox. On the cross axis, you can use align-content
in cases where you have multiple flex lines and space in the flex container to space them out. You can also use align-items
and align-self
to move the flex items on the cross axis in relationship to each other and their flex line.
For more on alignment in CSS layout see my previous Smashing Magazine articles:
Writing Mode Awareness And Older CSS
Not all of CSS has fully caught up with this flow-relative, writing mode agnostic way of working. The places where it has not start to stand out as unusual the more you think of things in terms of block and inline, start and end. For example, in a multi-column layout, we specify column-width
, which really means column inline-size, as it isn’t mapped to the physical width when working in a vertical writing mode.
As you can see, writing modes underpin much of what we do in CSS, even if we never use a writing mode other than horizontal-tb
.
I find it incredibly helpful to think about CSS layout in this writing mode agnostic way. While it is perhaps a little early to be switching all of our properties and values to logical ones, we are already in a flow-relative world when dealing with new layout methods. Having your mental model be one of block and inline, start and end, rather than tied to the four corners of your screen, clarifies many of the things we come across when using FlexBox and grid.
Further Reading
- Modern CSS Layouts: You Might Not Need A Framework For That
- Useful DevTools Tips and Tricks
- Level Up Your CSS Skills With The :has() Selector
- Deploying CSS Logical Properties On Web Apps