CSS Columns

Having a block of text flow into multiple columns can be a little tricky, trying to balance the text in the columns while the screen changes from a phone, to tablet, and up to a +40 inch desktop screen. But using the column CSS property we can let the browser worry about flowing the text into columns. With this property we don’t need to try to break up the text into even columns. Or worry about how many columns will fit. The browser will use the values you provide and adjust for the best fit in each user’s case. This works great when the amount of text is unknown while we create the layout.

And the best part is that if the user is in a browser that doesn’t support this property, the user just gets a single column.


The HTML below shows the basic setup. In this case I’m using a div to contain the two paraph tags. The style could be added as an inline style. Here the ColumnStyle class is being used so we can easily swap out the styling we’ll discuss below. There is a CodePen that will hold this code, but you can create your own. Normally I’d use a placeholder text list Lorem Ipsum, but since we care about how the text is flowing, it’s better (in my opinion) to use text that you’ll be able to tell where it’s flowing. This text is from Wikipedia page on Cats. For the text I used, please visit the Code Pen.

The image may overflow into other columns until we talk about formating images in columns. The image and headers may seem at times out of place but that’s because we are focusing on a single aspect at a time. In your project, you’ll be able to combine the styles to make a great looking site.

<div class="ColumnStyle-#">
  <h2>The Cat article from Wikipedia</h2>
  <p>Paragraph Text.... <img src="http://placekitten.com/300/200"/> Paragrph Text...</p>
  <h3>Here's more information about Cats</h3>
  <p>More Text... </p>
  <p>More Text... </p>
  <p>More Text... </p>

Basic usage

The two properties that will be the starting point is column-count and column-width. column-count sets how many columns would be ideal. The browser will use this as the max number of columns. column-width sets the optimal width of the column. Again this is the max width the browser will use. Both of these values will be used in the browser’s rendering of the page.

.ColumnStyle-1 {
  column-count: 5;
  column-width: 50px;

Image of ColumnStyle-1 Styling columns

Please note that the shorthand uses columns not column. The order doesn’t matter since only the width will have a unit of measure, so it’s easy for the browser to tell them apart.

.ColumnStyle-2 {
  columns: 5 50px;

auto lets the browser do the calculations all be itself. If auto replaces the width, the browser will try to use whatever width it needs to make that number of columns. auto in place of the number of columns, the browser will make as many columns as will fit with the specified width. There may still be a point when the browser can’t render at what is specified but it will do it’s best. auto is assumed if a value is missing.

.ColumnStyle-3 {
  columns: 2 auto;

I’ve been using px but it’s better (in my opinion) to use em. The reason is that em is based on the height of the character while px is fixed. If the user needs a larger font-size using em would adjust the column width but px wouldn’t.

.ColumnStyle-4 {
  column-width: 10em;

column-fill sets how the text fills the columns. With balance each column will get the same amount of text even if there ends up space under the columns.

.ColumnStyle-5 {
  columns: 5 auto;
  column-fill: balance;

Another option is auto, this will fill each column sequentially. The last column may not fill up. Each column will use all the height that is available.

There is also balance-all. In paged media, balance will only balance the last page, where balance-all will balance all the pages.

The Gap

The next very common property will be column-gap. This value is the space between the columns. It cannot be a negitve number. In this example I’m making the gap wider then you’ll most likely use so you can easily see the effect.

.ColumnStyle-6 {
  columns: 3 10em;
  column-gap: 5em;

Image of ColumnStyle-6 Styling columns

To get a little fancier, a rule can be added between the columns in the gap. This property uses the same options as the border style. Examples for the style are thick, dotted, solid.

Just like the border-style, column-rule has column-rule-width, column-rule-style, and column-rule-color. Of course it can also be in a shorthand format as well.

.ColumnStyle-7 {
  columns: 5 50px;
  column-rule-width: 1px;
  column-rule-style: solid;
  column-rule-color: blue;

Image of ColumnStyle-7 Styling columns

And in the shorthand:

.ColumnStyle-8 {
  columns: 5 50px;
  column-rule: 1px solid blue;

Heading (spanning the columns)

While spanning the columns doesn’t have to be a headline, I think the majority will be.

The column-span property is applied to the element that should span the columns. There is two choices all which will span all columns or none which will span none.

.columnStyle-9 {
  columns: 4 auto;
.columnStyle-9 h2 {
  column-span: all;

Image of ColumnStyle-9 Styling columns

If the element that will span the columns is inside the flow of the text, the text above will stay above the spanned element. And likewise, the text below will stay below.

In this example, since the h3 is between paragraph one and two. Paragraph one will flow through each columns, the h3 will span all the columns and paragraph two will flow through the columns below the h3.

.columnStyle-10 {
  columns: 4 50px;
.columnStyle-10 h3 {
  column-span: all;

Image of ColumnStyle-10 Styling columns


Image elements that are placed in the text flow may overflow into the other columns depending on the size of the image. The text in the next column should sit on top of the image. Be aware that some browsers may clip the image instead.

To avoid this we can set the image width to 100% will keep the image in the column.

.columnStyle-11 {
  columns: 5 auto;
.columnStyle-11 img {
  width: 100%;

Image of ColumnStyle-11 Styling columns

Floating an image will still have the image inside the column and the text will flow around the imagine.

.columnStyle-12 {
  columns: 3 auto;
.columnStyle-12 img {
  width: 50%;
  float: left;

Image of ColumnStyle-12 Styling columns

All together now

Keep in mind that through all this, we’ve never changed the HTML. All the changes we’ve made were to a small set of CSS rules. In this final example we’re going to put these rules together and style a little extra to make the HTML look very different.

And the best part is that if the user looks at this on a mobile device it’ll change to a single column and if they go to a wide screen desktop, it’ll go fairly wide using more of the screen.

.ColumnStyle-Final {
  columns: auto 10em;
  column-gap: 2em;
  column-rule: 1px solid blue;
.ColumnStyle-Final h2 {
  column-span: all
.ColumnStyle-Final h3 {
  column-span: all;
  border-top: 1px solid #999;
  padding-top: 5px;
.ColumnStyle-Final img {
  width: 100%;
  border: 1px solid #333;
  margin: 5px 3px;

Image of ColumnStyle-Final Styling columns

Final Thoughts

This isn’t a replacement for a columned layout. This is for sites that have a lot of text content and it can be used inside of a columned layout.

Image a site that has a block of text in the center with a site header across the top and menu along one side and ads down the other.

With the wide monitor the site would either have a very wide block of text; which can be hard to read. Or large white areas on either side. By using columns, the text would flow into multiple columns and the user would have a much easier time enjoying the site without scrolling for miles.


MDN article - Columns

Code Pen - By forking this Pen you can test out the different styles and save them for your own reference.

CSS Master eBook on SitePoint - This is a premium resource. The book can be purchased or there is a monthly subscription to SitePoint that gives access to hundreds of books and courses.