How to Create a Newspaper-Style Column Layout

Years ago, Netscape supported a proprietary markup tag called MULTICOL. This tag could be used to format text into multiple columns. However, it was only ever supported by Netscape Navigator and was never added to the HTML specification. In addition, control over MULTICOL was extremely limited and this lack of flexibility coupled with limited support meant it did not see broad adoption. Today, MULTICOL and Netscape Navigator are both a distant memory. However, a multiple column layout is easier than ever to create using the CSS columns property. Support for CSS columns is good between browsers and getting better, and column layouts degrade gracefully into a single column for visitors using an unsupported browser.

Where Can CSS Columns Be Used?

Columns can be used to contain both block and inline level elements. For example, a blog post wrapped in a div, and containing an h1, several additional subheading elements, and several paragraphs of text could be “columnized” in a couple of different ways.

  • Individual paragraphs could be formatted into columns and separated by headings.
  • A portion of the post that included headings and paragraphs could be dropped into a column layout.
  • The entire blog post div could be laid out using CSS columns.

In other words, columns can be used to contain any type and combination of content including both block and inline elements.

Support for Columns

Columns have full support in Microsoft browsers IE 10+ and Edge, and support for nearly all column features is offered by every other major browser as long as the -webkit- and -moz- prefixes are used. Prior to IE 10, columns were not supported at all in Internet Explorer. However, multiple column layouts degrade gracefully into a single column in unsupported browsers. As a result, web designers can use columns without worrying about leaving users of older browsers behind.

The CSS Column Properties

There are seven primary CSS column properties:

  • column-count: This property specifies the maximum number of columns that the columned content should fill.
  • column-width: This property is used to specify the minimum width of any single column. When column width falls below this value, one column will be removed until just two columns are left, at which point the layout will revert to a single column.
  • columns: This property is shorthand for the column-count and column-width properties.
  • column-gap: Adjust the spacing between columns with this property.
  • column-rule: This property adds a vertical bar between columns.
  • column-span: Identify elements that should span multiple columns with this property.
  • column-fill: This property is used in combination with the height property to force Mozilla Firefox to fill columns sequentially. All other browsers fill fixed-height columns sequentially by default, and this property only affects the behavior of the Firefox browser.

This tutorial will show you how to use each of these properties. Our goal as we go along will be to create a responsive column layout that renders into a beautiful and readable column layout on larger screens and degrades into a single column layout on smaller screens.

Identifying Content to Put Into Columns

Before we can work with columns, we need some text to manipulate. A few paragraphs from the first chapter of Alice in Wonderland will do just fine. Note: In this example we’re going to use an internal stylesheet for the sake of simplicity. However, best practice when implementing columns or any other CSS styling is to use an external stylesheet.

<head>     <style>     <!--we'll add column styling here-->     </style> </head> <body>     <div class="cols_ex">         <p>Just at this moment her head struck against the roof          of the hall: in fact she was now rather more than nine          feet high, and she at once took up the little golden key          and hurried off to the garden door.</p>         <p>Poor Alice! It was as much as she could do, lying down          on one side, to look through into the garden with one eye;          but to get through was more hopeless than ever: she sat          down and began to cry again.</p>         <p>"You ought to be ashamed of yourself," said Alice,          "a great girl like you" (she might well say this), "to          go on crying in this way! Stop this moment, I tell          you!"</p>         <p>But she went on all the same, shedding gallons of tears,          until there was a large pool all round her, about four          inches deep, and reaching half down the hall.</p>     </div> </body> 

Without adding styling to our content, here’s how it renders:

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Setting Up our Columns

The column-count property is used to set the number of columns the columned content should be divided between. It accepts any numeric value. To divide our content between three columns, we would add the following bit of CSS to our document.

.cols_ex {     -webkit-column-count: 3;     -moz-column-count: 3;     column-count: 3; } 

Here’s how our content looks split between three columns.

.cols_ex_2 { -webkit-column-count: 3; -moz-column-count: 3; column-count: 3; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

We aren’t limited to three columns. We could use any numeric value to split up our content. Just for the sake of example, let’s see what seven columns look like.

.cols_ex_3 { -webkit-column-count: 7; -moz-column-count: 7; column-count: 7; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Now obviously the readability of the content suffers when split into 7 columns, but our point is that you can use column-count to create as many or as few columns as you wish.

Assigning a Minimum Column Width

Columns automatically resize to fit the width of their parent container by growing as tall as necessary to maintain the specified number of columns. However, as was obvious in the case of the seven-column layout above, there comes a point at which columns become unreadably narrow. To avoid a situation where columns become too narrow, use the column-width property to specify a minimum column width. In our example, we’re going to use 150 pixels as the minimum acceptable width.

.cols_ex {     -webkit-column-width: 150px;     -moz-column-width: 150px;     column-width: 150px; } 

If we use that code to replace the column-count property, the content in the columns will be automatically split between as many 150-pixel-wide columns as the parent element can fit. Each column will be 150 pixels wide, or wider, and as soon as an additional 150-pixel column can be added, all of the columns will resize to 150 pixels and an additional column will be added. If the width of the columns drops below 150 pixels, one column will be dropped until just two remain, at which point the column layout will degrade into a single column if two 150-pixel wide columns cannot be displayed. Here’s how our content looks with the column-width: 150px; rule applied.

.cols_ex_4 { -webkit-column-width: 150px; -moz-column-width: 150px; column-width: 150px; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Controlling Width and Count Simultaneously

A column layout is at it’s best when the number of columns and the column width are both specified.

  • Specifying just the column count can create problems on smaller devices if the columns become unreadably narrow.
  • Specifying just the column width can cause the content to spread into an excessive number of columns on wider screens.

By specifying the column width and count we ensure that the columns remain wide enough to be readable yet doesn’t split into an excessive number of columns. We can control both count and width by specifying them both at the same time, or by using the shorthand columns property.

.cols_ex {     -webkit-columns: 3 150px;     -moz-columns: 3 150px;     columns: 3 150px;      /***************************************************     The code below would produce the same results as the     shorthand columns property used in the code above.     ***************************************************/      /*-webkit-column-count: 3;     -moz-column-count: 3;     column-count: 3;     -webkit-column-width: 150px;     -moz-column-width: 150px;     column-width: 150px;*/ } 

Here are the results of using the shorthand columns property with the values 3 for column count and 150px for column width.

.cols_ex_5 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px;}

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Now our content will never spread into more than three columns, and if column width drops below 150 pixels the column count will be reduced until we are left with just one column.

Adjusting Column Spacing and Adding a Vertical Rule

Now that we have our columns set up the way we want them, we can take a look at a few visual elements. The column-gap property can be used to adjust the amount of space between columns. The default value for column-gap is 1em. In most cases, this gap looks pretty good, but if you want to adjust it you can use pixels or ems. Just for the sake of example, let’s see how our columns look if we adjust the gap a bit.

.cols_ex {     -webkit-columns: 3 150px;     -moz-columns: 3 150px;     columns: 3 150px;     -webkit-column-gap: 3em;     -moz-column-gap: 3em;     column-gap: 3em; } 

Increasing column gap to 3em will produce the following results.

.cols_ex_6 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px; -webkit-column-gap: 3em; -moz-column-gap: 3em; column-gap: 3em;}

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

The column-rule property adds a customizable vertical rule between the columns. The rule can be customized by modifying the rule width, style, and color. Let’s add a gray dashed rule that is 2 pixels wide between the columns. While we’re at it, let’s go ahead and trim down the column gap to 2em since 3em feels a bit excessive.

.cols_ex {     -webkit-columns: 3 150px;     -moz-columns: 3 150px;     columns: 3 150px;     -webkit-column-gap: 2em;     -moz-column-gap: 2em;     column-gap: 2em;     -webkit-column-rule: 2px dashed gray;     -moz-column-rule: 2px dashed gray;     column-rule: 2px dashed gray; } 

Here’s how our columns now render with the rule added.

.cols_ex_7 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px; -webkit-column-gap: 2em; -moz-column-gap: 2em; column-gap: 2em; -webkit-column-rule: 2px dashed gray; -moz-column-rule: 2px dashed gray; column-rule: 2px dashed gray;}

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Adding Column-Spanning Section Headings

While there are no section headings in our text, in cases where a column layout is used “in-the-wild” it is probable that the columned content will include a heading and several subheadings. Let’s add a subheading to our text, so we can see how it is displayed in the columns.

.cols_ex_7 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px; -webkit-column-gap: 2em; -moz-column-gap: 2em; column-gap: 2em; -webkit-column-rule: 2px dashed gray; -moz-column-rule: 2px dashed gray; column-rule: 2px dashed gray;} .cols_heading_ex_1 p { font-size: 1.5em; font-weight: bold; margin: 20px 0; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

Alice Has a Good Cry

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Our columns would look a lot better if our heading spanned across the columns, and if the column layout resumed after the heading. The column-span property will let us do exactly that. Here’s the syntax for the column-span property.

.cols_heading_ex {     -webkit-column-span: all;     column-span: all; } 

You may notice that we left the -moz- prefix out. Unfortunately, Firefox does not currently support the column-span attribute. To achieve the same effect in Firefox we would have to only apply the CSS columns to our paragraphs and break the heading out of the flow of the columns. All other browsers will render column-spanning elements. The only accepted values for column-span are none or all. In our HTML, we’ll assign the class .cols_heading_ex to our heading, and when we drop that bit of CSS into our document we get a nice complete column-spanning break where our heading appears (unless you’re viewing this tutorial in Firefox).

.cols_ex_8 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px; -webkit-column-gap: 2em; -moz-column-gap: 2em; column-gap: 2em; -webkit-column-rule: 2px dashed gray; -moz-column-rule: 2px dashed gray; column-rule: 2px dashed gray;} .cols_heading_ex_2 p { font-size: 1.5em; font-weight: bold; margin: 20px 0; } .cols_heading_ex_2 { -webkit-column-span: all; column-span: all; margin: 0; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.

Alice Has a Good Cry

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Force Firefox to Fill Fixed-Height Columns Sequentially

The final property to talk about is the column-fill property. This one is unique to Firefox, and column-fill only needs to be applied if the column content has been assigned a fixed height. When columns are assigned a fixed height every browser other than Firefox will fill the columns sequentially. That means that the first column will be completely filled before any content spills into the second column and so forth. In Firefox, the content is shared evenly between all columns regardless of how much empty space is left at the bottom of the columns. To force Firefox to behave the same way as all other major browsers we would add the column-fill property to our CSS using this syntax:

column_content_selector {     height: some value;     -moz-column-fill: auto;     column-fill: auto; } 

In our case, we haven’t assigned a fixed height to our columns, so we don’t need to worry about this property. It’s important to remember not to include the column-fill property unless a fixed height has been set. Otherwise, when rendered in Firefox, all column content will be pushed into the left-most column. That’s it! Our content will now render beautifully across a range of devices. However, in cases where the column content is longer than the content used in our example there two issues that may need to be addressed.

Potential Problems Created by CSS Columns

There are two potential problems that can be created when working with CSS columns.

  1. When the height of the column content is been specified, and the content overflows the height of the container, additional columns will be added off-screen horizontally, and a scrollbar will appear at the bottom of the browser.
  2. When columns are taller than the browser window, website visitors have to scroll down to read the content in one column and then back up to start the next column.

Both of these issues can be addressed by embedding height and columns properties in @media queries so that only take effect once minimum width and height values have been met.

Preventing Horizontal Overflows of Fixed-Height Columns

To prevent the creation of off-screen horizontal columns when the column content overflows the available height, use a media query to apply the height value once the window is wide enough to avoid creating an overflow issue. For example, let’s imagine that we land on fixing the height of our columns at 400 pixels. However, in order to fit all of our column content into 400-pixel tall columns, we also determine that we need at least 450 pixels of width for all of the content to fit without overflowing. In that case, we could use the following CSS to only apply the height value to the columns once the browser width reaches the minimum of 450 pixels.

@media (min-width: 450px) {     column_content_selector {         height: 400px;         } } 

Preventing Columns Taller than the Browser Window

A column layout that requires a website visitor to scroll down to read column content and then back up to start the next column is a broken layout that needs to be allowed to degrade back to a single-column layout. To do this, simply determine the minimum height required to fully display all column content, and then use a @media query to apply column-creating CSS once that minimum height is met. For example, let’s imagine that our columns require 500 pixels vertical height to display all column content. If so, we would add our columns CSS to a @media query based on that minimum height value.

@media (min-height: 500px) {     column_content_selector {         -webkit-columns: 3 150px;         -moz-columns: 3 150px;         columns: 3 150px;     } } 

That query will cause our content to render in a single column until the minimum height of 500 pixels is reached, at which point our columns CSS will kick in and generate the column layout we designed.

Controlling Column Breaks

We can identify column contents that we don’t want to see spill from one column to the next by using the break-inside property. They way the property works is that we select the element that we don’t want to spill from one column to the next, and then use the property to tell it to keep that element contained within a single column. For example, if we had a short list of items contained within our column content, we could use this element to force the list to hold together. For the sake of example, let’s turn one of the paragraphs of our text into a list and force it to hold together by adding the following CSS:

ul {     -webkit-column-break-inside: avoid;     page-break-inside: avoid;     break-inside: avoid; } 

It’s worth pointing out that the use of the webkit prefix is necessary for Chrome browsers, and that Firefox calls this property page-break-inside rather than break-inside for the time being. With that CSS in place, and the second paragraph of our content partially turned into a list, we get the following behavior. If you resize your browser window you’ll see that list always appears together in a column. It will not break between columns.

.cols_ex_8 { -webkit-columns: 3 150px; -moz-columns: 3 150px; columns: 3 150px; -webkit-column-gap: 2em; -moz-column-gap: 2em; column-gap: 2em; -webkit-column-rule: 2px dashed gray; -moz-column-rule: 2px dashed gray; column-rule: 2px dashed gray;} .cols_heading_ex_2 p { font-size: 1.5em; font-weight: bold; margin: 20px 0; } .cols_heading_ex_2 { -webkit-column-span: all; column-span: all; margin: 0; } .list_ex { -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid; list-style-type: disc; padding-left: 32px; }

Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.

Poor Alice! It was as much as she could do,

  • lying down on one side,
  • to look through into the garden with one eye;

but to get through was more hopeless than ever: she sat down and began to cry again.

Alice Has a Good Cry

“You ought to be ashamed of yourself,” said Alice, “a great girl like you” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!”

But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep, and reaching half down the hall.

Use the Right Tool for the Job

CSS columns provide a novel way to present text content. When properly implemented, they provide a very good reading experience, and are particularly well-suited to articles and blog posts that are entirely or nearly entirely textual. If your goal is to convert web page content into columns, this tutorial provides the tools you need to get started. However, if your goal is to create an entire web page layout that includes column-like sidebars, there are other CSS tools better suited to that task. Take a look at our introduction to CSS and the other CSS tutorials we offer to learn about other strategies and techniques for creating web page layouts with CSS.