This article comes from SmashingMagazine’s excellent CSS layout overview, which summarizes various CSS layout techniques and provides links to in-depth reading of them. Thanks to Rachel Andrew.

The introduction

Whether you’re a beginner who wants to learn CSS layouts, or a more experienced front-end developer who wants to consolidate and learn the latest CSS layouts, this guide will help you get a complete picture of how CSS layouts are evolving today.

Over the years, CSS layouts have changed dramatically, just as front-end development has changed dramatically. Now we need alternative CSS layouts to develop our sites, which requires us to choose between them. In this article, I will introduce you to the basic use of various CSS layouts and their purposes.

If you’re new to CSS and want to know what the best layout method is, this article is for you. Of course, if you are a more experienced developer and want to get up to date on CSS layouts, this article is a must. Of course, I won’t cover all the details of the various technologies in this article (it could be a book), but rather give you a basic overview and links to learn more about them.

If you like, please follow my blog or subscribe to RSS feed.


1. Normal document Flow

If you open a web page without changing the layout of the page with any CSS, the elements of the page will be arranged in a normal flow. In normal flow, element boxes are arranged one after another based on the writing mode of the document. This means that if your writing pattern is horizontal (sentences are written left to right or right to left), normal flow will arrange the block-level elements of the page vertically, one after the other.

Of course, if you’re writing in vertical mode, sentences are written vertically, so block-level elements are arranged horizontally.

Normal flow is the most basic layout: when you apply CSS to a document and create some CSS layout, you are actually asking the blocks to do something other than normal document flow.

1.1. Take advantage of normal document flow through page structure

By making sure your pages have a well-structured manner, you can take full advantage of normal flow. Imagine if there was no normal flow in the browser, and all the elements you created would pile up in the top right corner of the browser. This means that you must specify how all elements should be laid out.

With normal flow, users can still read your page even if CSS loads fail. At the same time, tools that don’t use CSS (such as some readers) read the content of the page based on the position of the elements in the document. This is definitely helpful from a usability perspective, and also makes things easier for developers. If your content is in the order that users expect to read it, you don’t need to do a lot of layout tweaking to get elements in the right place. As you read on, you’ll see how using the new layout can make page layout more efficient.

Therefore, before thinking about layout, you need to think carefully about the structure of your document and the order in which you want users to read it.

1.2. Out of normal document flow

Once you have a well-structured page, you need to decide how to take advantage of it and turn it into the layout structure we need. This involves moving away from normal flow, which I’ll cover later in this article. We have a number of layout “sharps” at our disposal, the first of which is float, which is a great example of what it means to deviate from normal document flow.


2. This is a Float.

Floats are used to place the box to the left or right while the content is displayed around it.

To float an element, you set a float property with either a left or right value for the element. The default value is None.

.item {
    float: left
}
Copy the code

It’s worth emphasizing that when you float an element and surround it with text, the content’s line box is truncated. If you float an element and set a background color for the following element that contains text, you will find that the background color appears below the floating element.

If you want to create a margin between the floating element and the surrounding text, you need to set a margin for the floating element. Setting a margin on a text element will only indent it relative to the container. For example, in the following example, you need to set the right margin and bottom margin for the image floating on the left.

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,. 3); }Copy the code

2.1. Clear the float

Once you float an element, all subsequent elements wrap around it until the content is below it and normal document flow is applied. If you want to avoid this, you can manually clear the float.

When you do not want an element to be affected by its previous floating element, add the clear attribute to it. The left value clears left floats, the right value clears right floats, and both clears left floats.

.clear {
    clear: both;
}
Copy the code

However, problems can arise when you find a floating element inside the container and the container text is too short. The text box is drawn under the floating element, and the rest of the text is drawn in normal flow after it.

To avoid this, we need to apply the clear attribute to an element in the container. We can add an empty element to the end of the container and set the clear property. However, in some cases this approach may not be possible (for example, pages generated by some CMS systems). Therefore, the most common hack to clear floats is to add a CSS pseudo-element to the container and set its clear property to both.

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,. 3); }.container::after {
  content: "";
  display: table;
  clear: both;
}
Copy the code

example: Smashing Guide to Layout: clearfix on Codepen

2.2. Block Formatting Context

Another way to clear up floats is to create BFC inside the container. A BFC element completely wraps all of its internal elements, including the internal floating element, ensuring that the floating element does not go beyond its bottom. There are many ways to create BFC, and one of the most common ways to clear float is to set overflow property values for elements other than visible (the default).

.container {
    overflow: auto;
}
Copy the code

Using overflow as above is generally effective. However, in some cases, this may cause some shading truncation or unexpected scrollbars. It also makes your CSS less intuitive: Do you set overflow because you want to show scrollbars or just for the ability to clear floats?

To make the intent to clear the float more intuitive, and to avoid the negative effects of BFC, you can use flow-root as the value of the display property. Display: The only thing flow-root does is to create a BFC, thus avoiding the problems associated with other methods of creating BFC.

.container {
    display: flow-root;
}
Copy the code

2.3. Some legacy uses of float

Before the new layout, float was often used to create multi-column layouts. We’ll set the width of a series of elements and float them one by one. You can create a grid-like effect by setting some fine percentage sizes for the floating elements.

I do not recommend overusing this approach today. However, with existing sites, this approach will still exist for many years to come. So when you come across an app with a page full of floats, you can be sure it’s using this technique.

2.4. Additional reading on floating and clearing floats

  • “The Clearfix: Force an Element To Self-clear its Children,” Chris Coyier, CSS-Tricks
  • “Float,” CSS: Cascading Style Sheets, MDN Web Docs
  • “Clear,” CSS: Cascading Style Sheets, MDN Web Docs
  • “Understanding CSS Layout And The Block Formatting Context,” Rachel Andrew, Smashing Magazine

3. Positioning

To remove an element from normal flow or change its position in normal document flow, use the Position property in the CSS. When in normal document flow, the position attribute of the element is static. At the block level the elements are arranged one after the other, as you scroll through the page.

When you change the position property of an element, you usually also set some offset to move the element relative to the reference point. Different positions produce different reference points.

3.1. Relative Postioning

If an element has the attribute Position: relative, its offset reference bit is its original position in the normal document flow. You can use the top, left, bottom, and right attributes to move relative to its normal flow position.

.item {
    position: relative;
    bottom: 50px;
}
Copy the code

Note that other elements on the page are not affected by the element’s position. The element’s position in the normal stream is preserved, so you have to deal with overwriting elements yourself.

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,. 3);position: relative;
  bottom: 50px;
}
Copy the code

example: Smashing Guide to Layout: position: relative on Codepen

3.2. Absolute Postioning

Setting position: Absolute to an element removes it completely from normal flow. The space it used to occupy will also be removed. The element is positioned relative to the viewport container unless one of its ancestors is also positioned (position is not static).

So, when you set position: Absolute for an element, the first thing that happens is that the element is positioned in the upper left corner of the viewport. You can move elements to the desired position by setting the top, left, bottom, and right offsets.

.item {
    position: absolute;
    top: 20px;
    right: 20px;
}
Copy the code

Normally you don’t want the element to be positioned relative to the viewport, but relative to the container element. In this case, you need to set the container element to a value other than the default static.

Since setting position: Relative to an element does not remove it from normal flow, this is usually a good choice. Set position: relative to the container elements you want to be relative to to offset the absolutely positioned elements.

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,. 3);position: absolute;
  top: 20px;
  left: 20px;
}
Copy the code

example: Smashing Guide to Layout: position: absolute on Codepen

3.3. Fixed Positioning

In most cases, the position: fixed element is positioned relative to the viewport and is removed from the normal document flow without retaining the space it occupies. As the page scrolls, the fixed elements remain in place relative to the viewport, while the rest of the normal flow scrolls as usual.

.item {
    position: fixed;
    top: 20px;
    left: 100px;
}
Copy the code

This works great when you want a fixed navigation bar that stays on the screen all the time. As with any position value, this can cause some elements to be obscured, and care needs to be taken to ensure that the page content is readable without being obscured by fixed elements.

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,. 3);position: fixed;
  top: 20px;
  left: 20px;
}
Copy the code

example: Smashing Guide to Layout: position: fixed on Codepen

To keep a fixed positioned element from being positioned relative to the viewport, you need to set one of the transform, Perspective, or filter attributes (not the default none) for the container element. This way the fixed element is offset with respect to the block-level element, not the viewport.

3.4. STICKY position

Setting position: sticky causes an element to scroll on the page as if it were in normal flow, but when it is rolled to a specific position relative to the viewport it will be fixed on the screen, as if it were fixed. The value of this property is a relatively new CSS property and will be less compatible with browsers, but will be ignored in incompatible browsers and will revert to normal scrolling.

.item {
    position: sticky;
    top: 0;
}
Copy the code

The following code shows how to create a very popular navigation bar effect: the navigation bar scrolls along the page and stays at the top as it scrolls to the top of the page.

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 30px;
  background-color: rgba(111,41,97,. 3);position: sticky;
  top: 0;
  width: 100%;
}
Copy the code

example: Smashing Guide to Layout: position: sticky on Codepen

3.5. Additional reading on Positioning

  • “Positioning,” MDN Learning Area, MDN Web Docs, Mozilla
  • “The position: sticky; , “Chris Coyier, CSS Tricks
  • CSS position:sticky, Browser support information for sticky Positioning, Caniuse

4. Flex Layout

Flexbox layout is a layout method designed for one-dimensional layout. One-dimensional means you want the content to be laid out in rows or columns. You can use display: flex to turn elements into elastic layouts.

.container {
    display: flex;
}
Copy the code

The immediate children of the container become flex items and are arranged in rows.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: flex on Codepen

4.1. Axes of elastic Box

In the example above, we would say that the elastic terms are aligned from the starting position in the row, not that they are left-aligned. These elements are arranged in line because the default flex-direction value is row, which represents the line direction of the text. Since we are working in English (and Chinese), a left-to-right language, the starting position of the line is on the left, so our elastic term starts on the left. Therefore, the flex-direction value is defined as the main axis of the elastic box.

A cross axis is an axis perpendicular to the main axis. If your flex-direction is row and the elastic items are arranged in inline directions, then the cross axis is the alignment of the block-level elements. If flex-direction is column, the elastic items are arranged in the same direction as the block-level elements, and the cross axis becomes row.

If you’re used to using elastic boxes from a spindle and cross axis perspective, it’s pretty easy.

4.2. Direction and sequence

The elastic box model allows us to change the orientation of the elastic items on the main axis by setting a row-reverse or column-reverse value for the flex-direction property.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
  flex-direction: row-reverse;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: flex-direction on Codepen

Of course, you can also change the order of an elastic term using the order attribute. Be aware, however, that this can cause problems for users accessing your site via a keyboard (rather than a mouse or touch screen), because TAB order is the order in which elements on the page appear in the source code, not the order in which they appear. You can read more about this in the “Display and document Order” section below.

4.3. Some Flex properties

These Flex properties are used to control the size of the elastic item on the main axis. The three properties are:

  • flex-grow
  • flex-shrink
  • flex-basis

You can usually use the short form: Flex. The first value represents flex-grow, the second is flex-shrink, and the third is flex-basis.

.item {
    flex: 1 1 200px;
}
Copy the code

Flex-basis sets the initial size of the elastic item without stretching and compression. In the example above, the size is 200px, so we give each item 200px space. However, most of the time the container element size will not be exactly divided into many 200px items, but may have some insufficient or spare space. The Flex-grow and flow-shrink attributes allow us to control the size of each elastic item when the container size is insufficient or available.

If the flex-grow value is arbitrarily positive, the elastic term is allowed to stretch to take up more space. So, in the example above, when the terms are set to 200px, all the extra space is bisected and filled by each elastic term.

If the flex-shrink value is an arbitrarily positive number, then the element will shrink when it overflows the container after the elastic term is set to Flex-basis. In the CSS example above, if the container runs out of space, each elastic item is scaled equally to fit the container size.

The flex-grow and Flex-shrink values can be any positive number. An elastic term with a larger flex-grow value will stretch a larger percentage of the container when it has free space; An item with a larger Flex-shrink value will be compressed more when the container space is insufficient.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 0;
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.container :first-child {
  flex: 2 1 0; 
}
Copy the code

example: Smashing Guide to Layout: flex properties on Codepen

Understanding these properties is key to understanding how to use elastic layouts, and some of the resources listed below will help you learn more about the details. Consider using the elastic box model when you need to stretch or compress elements in one dimension of the container. If you find yourself trying to arrange your content in both row and column dimensions and you need a grid model, the elastic box model is probably not the best tool.

4.4. Additional reading on flexible box layouts

  • “CSS Flexible Box Layout,” A Complete Guide to the Specification, MDN Web Docs, Mozilla
  • “A Complete Guide to Flexbox,” Chris Coyier, CSS-Tricks
  • “Flexbox Froggy,” A Game for Learning Flexbox
  • “Flexbugs,” A community curated list of Browser bugs relating to Flexbox
  • Learn Flexbox for free-12 interactive screencasts to take you from beginner to advanced from scrimba

5. Grid Layout

CSS Grid Layout is a technique for two-dimensional layout. Two-dimensional (two-dimesional) means you want to arrange your content in rows and columns. Like elastic boxes, grid layouts require a display value. You can set display: grid for container elements and use grid-template-columns and grid-template-rows attributes to control rows and columns in the grid.

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}
Copy the code

The CSS above creates a grid of column and column elements of a fixed size. But that may not be what you want. The default value is auto, which you can assume stands for “make the grid as large as possible.” If you do not specify the size of each row track, all added row contents will be set to Auto. A common pattern is to specify column widths for the grid, but allow the grid to add rows as needed.

You can set up rows and columns using any length unit or percentage of hours, and you can use the new unit created for the grid system – FR. The FR is an elastic unit that specifies how the space within the grid container is divided.

The grid calculates and allocates space for you, you don’t need to calculate the percentage of elements to fit the container size. In the following example, we use FR to create the grid’s columns, which makes the grid’s columns adaptive. We also use grid-gap to ensure spacing between elements (more on spacing between elements and elements in the grid in the “Alignment” section).

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5<br>has more content.</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: a simple grid on Codepen

5.1. Some terminology for grids

A grid system always has two axes: an inline axis represents the alignment of text in the page, and a block axis represents the alignment of block-level elements in the page.

An element set to display: grid is called a grid container. In the grid container there are grid lines, which are the rows and columns in the grid when you specify grid-template-columns and grid-template-rows. The smallest unit in a grid (that is, the area cut off by four grid lines) is called a grid cell, and further, a rectangular area composed of several cells is called a grid area.

5.2. Automatic grid arrangement rules

Once you have created the grid, the immediate children of the grid container begin to place themselves, one by one, in the cells of the grid. Child elements are placed according to the grid’s auto-placement rule. These rules ensure that elements within the grid are arranged in empty cells and do not cover each other.

Any immediate child element in the grid that has not been positioned is placed according to the automatic arrangement rule. In the following example, I make the first of every three elements occupy two rows, but still auto-arrange from the starting line.

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.container > div:nth-child(3n+1) {
  grid-row-end: span 2;
  background-color: rgba(193225237, 3);border: 2px solid rgba(193225237, 5); }Copy the code

example: Smashing Guide to Layout: auto-placement on Codepen

5.3. Basic positioning method based on row/column

The simplest way to locate grid elements is to use a row/column (LINE) based location method, which simply tells the browser from which row to which row to merge. For example, if you need a 2 by 2 grid area, you can specify elements from row 1 to row 3 and from column 1 to column 3 to cover up to four cells.

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}
Copy the code

These attributes can be denoted by abbreviations: grid-column and grid-row, where the first value represents the start value and the second value represents the end value.

.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}
Copy the code

You can also have grid items occupy the same cell. Support for design overlays between some content. Grid items are stacked on top of each other as they would normally be on a web page. In HTML source code, the bottom grid items are stacked on top of each other. You can still use z-index to control the stack order.

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
}

.one {
  grid-column: 1 / 4;
  grid-row: 1;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.two {
  grid-column: 1 / 3;
  grid-row: 2;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.three {
  grid-column: 2 / 4;
  grid-row: 2 / 5;
  background-color: rgba(193225237, 3);border: 2px solid rgba(193225237, 5); }.four {
  grid-column: 1;
  grid-row: 4 ;
  background-color: rgba(193225237, 3);border: 2px solid rgba(193225237, 5); }.five {
  grid-column: 3 ;
  grid-row: 4 / 5;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: line-based placement on Codepen

5.4. Locate elements by naming regions

You can locate elements in a grid by naming areas. To do this, you need to give each element a name and describe the layout using the values of the Grid-template-Areas attribute.

.item1 {
    grid-area: a;
}

.item2 {
    grid-area: b;
}

.item3 {
    grid-area: c;
}

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c c";
}
Copy the code

There are a few caveats to using this approach. If you want to combine cells as your grid items, you need to repeat the element’s name. The grid area needs to form a complete rectangle — each cell needs to be filled with a value. If you want to free up some cells, you need to use it. This value. For example, in the CSS below I leave the lower-right cell blank.

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c .";
}
Copy the code

You can also use the following demo code to see the layout in action.

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(50px, auto);
  grid-gap: 20px;
  grid-template-areas: 
    "a a a"
    "b c c"
    ". . d"
    "e e d"
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.one {
  grid-area: a;
}

.two {
  grid-area: b;
}

.three {
  grid-area: c;
}

.four {
  grid-area: d;
}

.five {
  grid-area: e;
}

Copy the code

example: Smashing Guide to Layout: grid-template-areas on Codepen

5.5. Additional reading on grid layout

This article has only covered the basics of CSS grid layouts. There is much more to learn, and the following materials can help you learn more. Grids can be used for the layout of some components or entire pages. If you need to lay out in two dimensions, a grid layout is a good choice — regardless of the size of the area you need to lay out.

  • “CSS Grid Layout,” Web Technology for Developers, MDN Web Docs, Mozilla
  • “Grid by Example,” Everything You need to learn CSS Grid Layout, Rachel Andrew
  • “Grid Garden,” A fun interactive game to test and improve your CSS skills
  • “Layout Land,” Jen Simmons, YouTube
  • Learn CSS Grid for free-14 interactive screencasts to take you from beginner to advanced from scrimba

I have also written a few articles at Smashing Magazine to help you understand more about the various mesh concepts:

  • “Best Practices With CSS Grid Layout”
  • ‘Styling Empty Cells With Generated Content And CSS Grid Layout’
  • “Using CSS Grid: Supporting Browsers Without Grid”
  • “CSS Grid Gotchas And Stumbling Blocks”
  • Naming Things In CSS Grid Layout

6. Visual and Document Order (Visual and Document Order)

At the beginning of this article, I recommend that you organize your documents from top to bottom, which will help readability and CSS layout. From our brief introduction to elastic boxes and CSS grids, you can see that using these layouts can dramatically change the order of the elements displayed on the page in the document. This can lead to an implicit problem.

In some non-visual application scenarios, the browser will follow the documented source code. Thus, a screen reader reads the order of documents, and a user using the TAB key accesses documents based on the order of the source code, not the order in which the elements are presented. Many screen reader users are not completely blind and may be able to see where these elements are in a document while using a screen reader. In these cases, the chaotic presentation of the page can be confusing when compared to the source code.

When you change the original order of elements in a document, make sure you know what you’re doing. If you find yourself reordering your elements in CSS, you should go back and see if you want to reorganize your page elements. You can test your page by using TAB access.

6.1. Additional reading on display order and document order

  • CSS Grid Layout and Accessibility, Web Technology for Developers, MDN Web Docs, Mozilla
  • “HTML Source Order vs CSS Display Order,” Adrian Roselli
  • “Flexbox And The Keyboard Navigation Disconnect,” Code Things, Tink
  • “The Responsive Order Conflict For Keyboard Focus,” Alastair Campbell

7. Box Generation

Everything you write on a web page generates a box, and everything in this article is really about how you can use CSS to layout those boxes according to your design. However, in some cases, you may not want to create a box at all. There are two display property values that will help you handle this situation.

7.1. Not generating boxes or content (display: none)

If you want the element and all of its contents (including all of its children) not to be generated, you can use display: None. This way elements are not displayed and do not retain the space they should occupy.

.item {
    display: none;
}
Copy the code

7.2 Do not generate this element, but generate all its children (display: contents)

Display: content is a new property value of display. Applying the display: content attribute to an element causes its own box to not be generated but all child elements to be generated as usual. How does that help? This can be useful if you want an elastic layout or grid layout to be applied to indirect child elements.

In the following example, the first elastic term contains two children, and since it is set to display: contents, its box is not generated and its two children become elastic terms and are laid out as direct children of the elastic box container.

<div class="container">
  <div class="item">
    <div class="subitem">A</div>
    <div class="subitem">B</div>
  </div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }.subitem {
  padding: 10px;
  background-color: rgba(193225237, 3);border: 2px solid rgba(193225237, 5); }.container .item:first-child {
  display: contents;
}
Copy the code

example: Smashing Guide to Layout: display: contents on Codepen

7.3. Other readings on Box Generation

  • “Vanishing Boxes With Display: Contents,” Rachel Andrew
  • How display: contents; Works, “Ire (Aderinokun,
  • CSS display: contents,” Browser support information, caniuse

Alignment 8.

In the past alignment used to be tricky and the methods available were very limited. All this has changed with the advent of the CSS Box alignment Module. You will use it to control the alignment between the mesh container and the elastic box container. Various other layout methods will apply these alignment properties in the future. A series of detailed properties in the Box Alignment Specification are as follows:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

Because different layout models have different characteristics, there are some differences in the presentation of the alignment attributes used for different layout models. Let’s see how alignment works in some simple grid and elastic layouts.

The align-items and context-items properties are a bulk form of the align-self and context-self properties, in contrast. These attributes control the alignment with the element in its grid area.

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div class="special">5</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-items: center;
  justify-items: start;
}

.special {
  grid-column: 2 / 4;
  align-self: end;
  justify-self: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: Grid align-items, justify-items, align-self, justify-self on Codepen

The align-content and context-Content properties control the alignment of rows/columns in the grid (the grid container needs extra space after the row/column elements are aligned).

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-content: space-between;
  justify-content: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: Grid align-content, justify-content on Codepen

In elastic boxes, align-items and align-self are used to solve alignment problems on cross axes, while justice-content is used to solve space allocation on the main axis.

<div class="container">
  <div>1</div>
  <div>2</div>
  <div class="special">3</div>
  <div>4</div>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

.special {
  align-self: stretch;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: Flex justify-content, align-items, align-self on Codepen

After wrapping the flex lines and extra space in the elastic container on the cross axis, you can use align-content.

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
Copy the code
p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}

.container > div {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,. 3);border: 2px solid rgba(111,41,97,. 5); }Copy the code

example: Smashing Guide to Layout: Flex align-content on Codepen

The links below discuss box model alignment in more detail in various layout methods. Taking the time to understand how alignment works is well worth the effort to understand elastic boxes, grid layouts, and future layout methods.

8.1. Row/column spacing

A multi-column layout has the column-gap attribute. So far, grid layouts have grid-Column-gao, grid-row-Gap, and grid-Grid. These have now been removed from the Grid standard and added to box model alignment. At the same time, the prefix properties of grid- have been renamed column-gap, row-gap, and gap. Browsers will replace prefixed attributes with new renamed attributes, so don’t worry if you use older, more compatible names in your current code.

The renaming means that these properties can also be applied to other layout methods, with elastic boxes being an obvious candidate. While no browser currently supports the gap attribute in the box model, in the future it should be possible to use column-gap and row-gap to create the spacing between elastic project elements.

8.2. Additional reading on Box Generation

  • “CSS Box Alignment,” CSS: Cascading Style Sheets, MDN Web Docs, Mozilla
  • Box Alignment in Flexbox, CSS Flexible Box Layout, MDN Web Docs, Mozilla
  • Box Alignment in CSS Grid Layout, CSS Grid Layout, MDN Web Docs, Mozilla
  • “The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment,” Rachel Andrew, Smashing Magazine
  • “Box Alignment Cheatsheet,” Rachel Andrew

9. Multi-column layout (Multi-column layout)

A multi-column layout is a type of layout that supports the creation of multiple columns, as in a newspaper. Each block is divided into columns, and you read down the column by block direction and then go back to the top of the next column. Reading in this way doesn’t always work with web content, however, because people don’t want to scroll around. This is useful when you need to show a small amount of content, collapse a set of check boxes, or other small UI components.

Multi-column layouts are also useful when displaying a set of cards or products of different heights.

9.1. Set the width of the column

To set a maximum column width and tell the browser to display as many columns as possible by this width, use the following CSS:

.container {
    column-width: 300px;
}
Copy the code

This will create as many 300px columns as possible, and all the remaining space will be shared by all columns. Therefore, unless there is nothing left when the space is partitioned to 300px, you will have slightly more columns than 300px.

9.2. Set the number of columns

In addition to setting the width, you can use column-count to set the number of columns. In this case, the browser will divide the space equally among as many columns as you need.

.container {
    column-count: 3;
}
Copy the code

If you add both column-width and column-count, the column-count attribute will be used as a maximum limit. In the code below, the column is added until it reaches three, at which point any extra space is divided into three columns, even if there is enough space to make an extra new column.

.container {
    column-width: 300px;
    column-count: 3;
}
Copy the code

9.3. Spacing and column rules

You can’t add a margin or an inner margin to a single column box. You need to set the spacing using the column-gap property. If you do not specify a column-gap value, it defaults to 1em to prevent collisions between columns. This differs from the behavior of column-gap in other layout methods, where the default is 0. You can use any length unit on the spacing, including 0 (if you don’t want column spacing).

The column-rule attribute gives you the ability to add rules between two columns. It is a short form of column-rule-width, column-rule-color, and column-rule-style, and border behaves similarly. Note that a rule by itself does not take up any space. It occupies the top of the spacing, increasing or decreasing the space between the rules and the content where you set column-gap.

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted # 000;
}
Copy the code

example: Smashing Guide to Layout: multicol on Codepen

9.4. Allow elements to span multiple columns

You can use the column-span attribute to allow elements in a multi-column container to span multiple columns, like a full column.

h3 {
    column-span: all;
}
Copy the code

When column-span is present, the multi-column container will stop on that element, so the contents of the container will form a multi-column style above the element and then a new column box will form underneath the spanning element.

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <h2>Veggies!</h2>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted # 000;
}

.container h2 {
  column-span: all;
  background-color: rgba(193225237, 6);border:2px solid rgba(193225237, 6);margin: 1em 0;
  padding:.5em;
}
Copy the code

example: Smashing Guide to Layout: multicol span on Codepen

You can only use column-span: all or column-span: None, and you can’t have elements that span several columns (non-columns). As of this writing, Firefox does not support the column-span property.

9.5. Additional reading on multi-column layouts

  • Using Multi-column Layouts, CSS Multi-column Layout, MDN Web Docs, Mozilla

10. Fragmentation

The multi-column layout is an example of fragmentation, where page content is divided into columns. This is very similar to printing when the content is divided into different pages. This process is addressed by the Fragmentation Specification. This specification includes several attributes that help control content sharding.

For example, if you have a set of cards in multiple columns and you want to make sure the cards don’t get cut in half into different columns, you can use the break-inside property avoid value. For browser compatibility reasons, you may also want to use the legacy Page-break-inside property.

.card {
    page-break-inside: avoid;
    break-inside: avoid;
}
Copy the code

If you want to disallow line breaking after the heading element, you can use the break-after attribute.

.container h2 {
    page-break-after: avoid;
    break-after: avoid;
}
Copy the code

These properties can be used in print styles or multi-column styles. In the following example, three paragraphs in a multi-column container are split into three columns. I set break-inside: avoid for the P element, which means that each multiple column ends up in its own column (even if it makes the columns different in length).

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut.  Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout</p>
  
  <p>Groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
Copy the code
body {
  padding: 20px;
  font: 1emHelvetica Neue, Helvetica, Arial, sans-serif; {} *box-sizing: border-box; }p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb,41,97 (111);border-radius:.5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted # 000;
}

.container p {
  page-break-inside: avoid;
  break-inside: avoid;
}
Copy the code

example: Smashing Guide to Layout: multicol fragmentation on Codepen

10.1. Additional reading on fragmentation

  • “A Guide To The State Of Print Stylesheets In 2018,” Rachel Andrew, Smashing Magazine
  • “The Column Breaks,” QuirksMode.org

11. How to choose layout type?

Most web pages use a mixture of layout types. Each layout specification defines exactly how they interact with each other. For example, you might use an elastic layout for grid items in a grid layout. Some elastic containers may have positioning properties or floats. These specifications already include a mix of layout models based on optimal layout. In this guide, I’ve tried to outline the basic use of this layout type to help you understand the best possible way to achieve an effect.

However, don’t be afraid to use multiple methods to achieve layout design. Worrying about whether your choices will actually cause problems is much less common than you think. So organize your document from the beginning, and pay attention to the visual order in which your document content is presented. Most of the rest is to test your layout in the browser to see if it works as expected.


Getting Started With CSS Layout, thanks to Rachel Andrew.