Writing Modes And CSS Layout

Writing Modes And CSS Layout

Writing Modes And CSS Layout

Rachel Andrew

In this article I am going to take a look at the CSS writing-mode property. However 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.

See the Pen [Writing Mode demo](https://codepen.io/rachelandrew/pen/dxVVRj) by Rachel Andrew.

See the Pen Writing Mode demo by Rachel 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 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.

See the Pen [width vs. inline-size](https://codepen.io/rachelandrew/pen/RXLLyd) by Rachel Andrew.

See the Pen width vs. inline-size by Rachel Andrew.

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 realise 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 start
  • grid-column-start: 2 - inline start
  • grid-row-end: 3 - block end
  • grid-column-end: 5 - inline end

See the Pen [grid-area](https://codepen.io/rachelandrew/pen/zgEEQW) by Rachel Andrew.

See the Pen grid-area by Rachel Andrew.

Flexbox Rows And Columns

If you use flexbox, and add display: flex to a container, your items will display as a row as the intial 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.

See the Pen [flex-direction: row](https://codepen.io/rachelandrew/pen/XvezrE) by Rachel Andrew.

See the Pen flex-direction: row by Rachel Andrew.

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.

See the Pen [flex-direction: column](https://codepen.io/rachelandrew/pen/RXLjbX) by Rachel Andrew.

See the Pen flex-direction: column by Rachel 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) by Rachel Andrew.

See the Pen Grid auto-placement row by Rachel Andrew.

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.

See the Pen [Grid auto-placement column](https://codepen.io/rachelandrew/pen/xvXPby) by Rachel Andrew.

See the Pen Grid auto-placement column by Rachel 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 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.

See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/mNBqEy) by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel 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 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 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.

See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/jgGaML) by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel Andrew.

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.

See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/RXLjpP) by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel 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 main axis versus cross axis. The align- properties are used on the cross axis. On the main axis all you have is justify-content due to the fact that in flexbox we deal with items as a group. 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.

See the Pen [Flexbox alignment](https://codepen.io/rachelandrew/pen/YmrExP) by Rachel Andrew.

See the Pen Flexbox alignment by Rachel 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 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.

See the Pen [Multicol and writing-mode](https://codepen.io/rachelandrew/pen/pMWdLL) by Rachel Andrew.

See the Pen Multicol and writing-mode by Rachel Andrew.

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.

Smashing Editorial (ra)

Everything You Need To Know About CSS Margins

Everything You Need To Know About CSS Margins

Everything You Need To Know About CSS Margins

Rachel Andrew

One of the first things most of us learned when we learned CSS, was details of the various parts of a box in CSS, described as The CSS Box Model. One of the elements in the Box Model is the margin, a transparent area around a box, which will push other elements away from the box contents. The margin-top, margin-right, margin-bottom and margin-left properties were described right back in CSS1, along with the shorthand margin for setting all four properties at once.

A margin seems to be a fairly uncomplicated thing, however, in this article, we will take a look at some of the things which trip people up with regard to using margins. In particular, we will be looking at how margins interact with each other, and how margin collapsing actually works.

The CSS Box Model

As with all articles about parts of the CSS Box Model, we should define what we mean by that, and how the model has been clarified through versions of CSS. The Box Model refers to how the various parts of a box — the content, padding, border, and margin — are laid out and interact with each other. In CSS1, the Box Model was detailed with the ASCII art diagram shown in the image below.

ascii art drawing of the box model
Depiction of the CSS Box Model in CSS1

The four margin properties for each side of the box and the margin shorthand were all defined in CSS1.

The CSS2.1 specification has an illustration to demonstrate the Box Model and also defines terms we still use to describe the various boxes. The specification describes the content box, padding box, border box, and margin box, each being defined by the edges of the content, padding, border, and margin respectively.

diagram of the CSS Box Model
Depection of the CSS Box Model in CSS2

There is now a Level 3 Box Model specification as a Working Draft. This specification refers back to CSS2 for the definitions of the Box Model and margins, therefore it is the CSS2 definition we will be using for the majority of this article.

Margin Collapsing

The CSS1 specification, as it defined margins, also defined that vertical margins collapse. This collapsing behavior has been the source of margin-related frustration ever since. Margin collapsing makes sense if you consider that in those early days, CSS was being used as a documenting formatting language. Margin collapsing means that when a heading with a bottom margin, is followed by a paragraph with a top margin, you do not get a huge gap between those items.

When margins collapse, they will combine so that the space between the two elements becomes the larger of the two margins. The smaller margin essentially ending up inside the larger one.

Margins collapse in the following situations:

Let’s take a look at each of these scenarios in turn, before looking at the things which prevent margins from collapsing in these scenarios.

Adjacent Siblings

My initial description of margin collapsing is a demonstration of how the margins between adjacent siblings collapse. Other than in the situations mentioned below, if you have two elements displaying one after the other in normal flow, the bottom margin of the first element will collapse with the top margin of the following element.

In the CodePen example below, there are three div elements. The first has a top and bottom margin of 50 pixels. The second has a top and bottom margin of 20px. The third has a top and bottom margin of 3em. The margin between the first two elements is 50 pixels, as the smaller top margin is combined with the larger bottom margin. The margin between the second two elements in 3em, as 3em is larger than the 20 pixels on the bottom of the second element.

See the Pen [Margins: adjacent siblings](https://codepen.io/rachelandrew/pen/OevMPo) by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel Andrew.

Completely Empty Boxes

If a box is empty, then it’s top and bottom margin may collapse with each other. In the following CodePen example, the element with a class of empty has a top and bottom margin of 50 pixels, however, the space between the first and third items is not 100 pixels, but 50. This is due to the two margins collapsing. Adding anything to that box (even padding) will cause the top and bottom margins to be used and not collapse.

See the Pen [Margins: empty boxes](https://codepen.io/rachelandrew/pen/JQLGMr) by Rachel Andrew.

See the Pen Margins: empty boxes by Rachel Andrew.

Parent And First Or Last Child Element

This is the margin collapsing scenario which catches people out most often, as it does not seem particularly intuitive. In the following CodePen, I have a div with a class of wrapper, and I have given that div an outline in red so that you can see where it is. The three child elements all have a margin of 50 pixels. However, the first and last items are flush with the edges of the wrapper; there is not a 50-pixel margin between the element and the wrapper.

See the Pen [Margins: margin on first and last child](https://codepen.io/rachelandrew/pen/BgrKGp) by Rachel Andrew.

See the Pen Margins: margin on first and last child by Rachel Andrew.

This is because the margin on the child collapses with any margin on the parent thus ending up on the outside of the parent. You can see this if you inspect the first child using DevTools. The highlighted yellow area is the margin.

The item with a yellow highlighted margin showing outside the parent
DepvTools can help you see where your margin ends up

Only Block Margins Collapse

The last example also highlights something about margin collapsing. In CSS2, only vertical margins are specified to collapse — that is the top and bottom margins on an element if you are in a horizontal writing mode. So the left and right margins above are not collapsing and ending up outside the wrapper.

Note: It is worth remembering that margins only collapse in the block direction, such as between paragraphs.

Things Which Prevent Margin Collapsing

Margins never collapse if an item has absolute positioning, or is floated. However, assuming you have run into one of the places where margins collapse outlined above, how can you stop those margins collapsing?

The first thing that stops collapsing is situations where there is something between the elements in question.

For example, a box completely empty of content will not collapse it’s top and bottom margin if it has a border, or padding applied. In the example below I have added 1px of padding to the box. There is now a 50-pixel margin above and below the box.

See the Pen [Margins: empty boxes with padding do not collapse](https://codepen.io/rachelandrew/pen/gNeMpg) by Rachel Andrew.

See the Pen Margins: empty boxes with padding do not collapse by Rachel Andrew.

This has logic behind it, if the box is completely empty with no border or padding, it is essentially invisible. It might be an empty paragraph element thrown into the markup by your CMS. If your CMS was adding redundant paragraph elements, you probably wouldn’t want them to cause large gaps between the other paragraphs due to their margins being honored. Add anything to the box, and you will get those gaps.

Similar behavior can be seen with margins on first or last children which collapse through the parent. If we add a border to the parent, the margins on the children stay inside.

See the Pen [Margins: margin on first and last child doesn’t collapse if the parent has a border](https://codepen.io/rachelandrew/pen/vqRKKX) by Rachel Andrew.

See the Pen Margins: margin on first and last child doesn’t collapse if the parent has a border by Rachel Andrew.

Once again, there is some logic to the behavior. If you have wrapping elements for semantic purposes that do not display visually, you probably don’t want them to introduce big gaps in the display. This made a lot of sense when the web was mostly text. It is less useful as behavior when we are using elements to lay out a design.

Creating a Block Formatting Context

A new Block Formatting Context (BFC) will also prevent margin collapsing through the containing element. If we look again at the example of the first and last child, ending up with their margins outside of the wrapper, and give the wrapper display: flow-root, thus creating a new BFC, the margins stay inside.

See the Pen [Margins: a new Block Formatting Context contains margins](https://codepen.io/rachelandrew/pen/VJXjEp) by Rachel Andrew.

See the Pen Margins: a new Block Formatting Context contains margins by Rachel Andrew.

To find out more about display: flow-root, read my article “Understanding CSS Layout And The Block Formatting Context”. Changing the value of the overflow property to auto will have the same effect, as this also creates a new BFC, although it may also create scrollbars that you didn’t want in some scenarios.

Flex And Grid Containers

Flex and Grid containers establish Flex and Grid formatting contexts for their children, so they have different behavior to block layout. One of those differences is that margins do not collapse:

“A flex container establishes a new flex formatting context for its contents. This is the same as establishing a block formatting context, except that flex layout is used instead of block layout. For example, floats do not intrude into the flex container, and the flex container’s margins do not collapse with the margins of its contents.”

Flexbox Level 1

If we take the example above and make the wrapper into a flex container, displaying the items with flex=direction: column, you can see that the margins are now contained by the wrapper. Additionally, margins between adjacent flex items do not collapse with each other, so we end up with 100 pixels between flex items, the total of the 50 pixels on the top and bottom of the items.

See the Pen [Margins: margins on flex items do not collapse](https://codepen.io/rachelandrew/pen/mZxreL) by Rachel Andrew.

See the Pen Margins: margins on flex items do not collapse by Rachel Andrew.

Margin Strategies For Your Site

Due to margin collapsing, it is a good idea to come up with a consistent way of dealing with margins in your site. The simplest thing to do is to only define margins on the top or bottom of elements. In that way, you should not run into margin collapsing issues too often as the side with a margin will always be adjacent to a side without a margin.

Note: Harry Roberts has an excellent post detailing the reasons why setting margins only in one direction is a good idea, and not just due to solving collapsing margin issues.

This solution doesn’t solve the issues you might run into with margins on children collapsing through their parent. That particular issue tends to be less common, and knowing why it is happening can help you come up with a solution. An ideal solution to that is to give components which require it display: flow-root, as a fallback for older browsers you could use overflow to create a BFC, turn the parent into a flex container, or even introduce a single pixel of padding. Don’t forget that you can use feature queries to detect support for display: flow-root so only old browsers get a less optimal fix.

Most of the time, I find that knowing why margins collapse (or didn’t) is the key thing. You can then figure out on a case-by-case basis how to deal with it. Whatever you choose, make sure to share that information with your team. Quite often margin collapsing is a bit mysterious, so the reason for doing things to counter it may be non-obvious! A comment in your code goes a long way to help — you could even link to this article and help to share the margin collapsing knowledge.

I thought that I would round up this article with a few other margin-related pieces of information.

Percentage Margins

When you use a percentage in CSS, it has to be a percentage of something. Margins (and padding) set using percentages will always be a percentage of the inline size (width in a horizontal writing mode) of the parent. This means that you will have equal-sized padding all the way around the element when using percentages.

In the CodePen example below, I have a wrapper which is 200 pixels wide, inside is a box which has a 10% margin, the margin is 20 pixels on all sides, that being 10% of 200.

See the Pen [Margins: percentage margins](https://codepen.io/rachelandrew/pen/orqzrP) by Rachel Andrew.

See the Pen Margins: percentage margins by Rachel Andrew.

Margins In A Flow-Relative World

We have been talking about vertical margins throughout this article, however, modern CSS tends to think about things in a flow relative rather than a physical way. Therefore, when we talk about vertical margins, we really are talking about margins in the block dimension. Those margins will be top and bottom if we are in a horizontal writing mode, but would be right and left in a vertical writing mode written left to right.

Once working with logical, flow relative directions it becomes easier to talk about block start and block end, rather than top and bottom. To make this easier, CSS has introduced the Logical Properties and Values specification. This maps flow relative properties onto the physical ones.

For margins, this gives us the following mappings (if we are working in English or any other horizontal writing mode with a left-to-right text direction).

  • margin-top = margin-block-start
  • margin-right = margin-inline-end
  • margin-bottom = margin-block-end
  • margin-left = margin-inline-start

We also have two new shorthands which allow for the setting of both blocks at once or both inline.

  • margin-block
  • margin-inline

In the next CodePen example, I have used these flow relative keywords and then changed the writing mode of the box, you can see how the margins follow the text direction rather than being tied to physical top, right, bottom, and left.

See the Pen [Margins: flow relative margins](https://codepen.io/rachelandrew/pen/BgrQRj) by Rachel Andrew.

See the Pen Margins: flow relative margins by Rachel Andrew.

You can read more about logical properties and values on MDN or in my article “Understanding Logical Properties And Values” here on Smashing Magazine.

To Wrap-Up

You now know most of what there is to know about margins! In short:

  • Margin collapsing is a thing. Understanding why it happens and when it doesn’t will help you solve any problems it may cause.
  • Setting margins in one direction only solves many margin related headaches.
  • As with anything in CSS, share with your team the decisions you make, and comment your code.
  • Thinking about block and inline dimensions rather than the physical top, right, bottom and left will help you as the web moves towards being writing mode agnostic.
Smashing Editorial (il)