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.
MeetSmashing Workshops onfront-end, design & UX, with practical takeaways, live sessions,video recordings and a friendly Q&A. With Brad Frost, Stéph Walter andso many others.
Jump to the workshops ↬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 thewriting-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 ishorizontal-tb
, orHorizontal 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 ahorizontal-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 isvertical-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 modevertical-lr
.
The other two values ofwriting-mode
are designed more for creative purposes than for typesetting vertical scripts. Usingsideways-lr
andsideways-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 ofwriting-mode
, you will need to use Firefox if you want to see thesideways-*
ones in action.
See the Pen [Writing Mode demo](https://codepen.io/rachelandrew/pen/dxVVRj) byRachel Andrew.
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 aboutRTL scripts andvertical text.
- Jen Simmons wrote an excellent article aboutCSS 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
- Thewriting-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 theblock 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 propertyinline-size
instead ofwidth
, it will act in exactly the same way as width - until you switch the writing mode of your component. If you usewidth
that will always be a physical dimension, it will always be the size of the component horizontally. If you useinline-size
, that will be the size in the inline dimension, as the below example shows.
See the Pen [width vs. inline-size](https://codepen.io/rachelandrew/pen/RXLLyd) byRachel Andrew.
The same is true forheight
. Theheight
property will always be the size vertically. It relates to how tall the item is. Theblock-size
property, however, gives the sizein 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 thegrid-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 usegrid-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
See the Pen [grid-area](https://codepen.io/rachelandrew/pen/zgEEQW) byRachel Andrew.
Flexbox Rows And Columns
If you use Flexbox and adddisplay: flex
to a container, your items will display as a row as the initial value of theflex-direction
property isrow
. A row will follow the inline dimension of the writing mode in use. Therefore if your writing mode ishorizontal-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 asvertical-rl
andflex-direction: row
will cause the items to lay out vertically, as the inline direction is vertical. In this next CodePen all of the examples haveflex-direction: row
, only the writing mode or direction has changed.
See the Pen [flex-direction: row](https://codepen.io/rachelandrew/pen/XvezrE) byRachel Andrew.
Addflex-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 ofvertical-rl
a column is horizontal. As with the previous example, the only difference between the below flex layouts is the writing mode being used.
See the Pen [flex-direction: column](https://codepen.io/rachelandrew/pen/RXLjbX) byRachel Andrew.
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.
See the Pen [Grid auto-placement row](https://codepen.io/rachelandrew/pen/eqGeYV) byRachel Andrew.
Try changing the flow of items tocolumn
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.
See the Pen [Grid auto-placement column](https://codepen.io/rachelandrew/pen/xvXPby) byRachel Andrew.
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 tovertical-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.
See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/mNBqEy) byRachel Andrew.
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 theflex-direction: row
example above, and use thejustify-content
property to align all of the items toflex-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 aninline-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 withalign-
or those which begin withjustify-
. In grid layout thealign-
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 usingstart
andend
. If we align tostart
on the block dimension, that will betop
when inhorizontal-tb
, but will beright
when invertical-rl
. Take a look in the example below, the alignment values are identical in both grids, the only difference is the writing mode used.
See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/jgGaML) byRachel Andrew.
The propertiesjustify-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.
See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/RXLjpP) byRachel Andrew.
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. Thealign-
properties are used on the cross axis. On the main axis, all you have isjustify-content
because we deal with items as a group in Flexbox. On the cross axis, you can usealign-content
in cases where you have multiple flex linesand space in the flex container to space them out. You can also usealign-items
andalign-self
to move the flex items on the cross axis in relationship to each other and their flex line.
See the Pen [Flexbox alignment](https://codepen.io/rachelandrew/pen/YmrExP) byRachel Andrew.
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 specifycolumn-width
, which really means column inline-size, as it isn’t mapped to the physical width when working in a vertical writing mode.
See the Pen [Multicol and writing-mode](https://codepen.io/rachelandrew/pen/pMWdLL) byRachel Andrew.
As you can see, writing modes underpin much of what we do in CSS, even if we never use a writing mode other thanhorizontal-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
