Simple Two Column CSS Layout

This is the second in a series of posts detailing how to setup basic responsive page structures using CSS. In this post, I will be covering how to handle two column layouts, first with the content on the left and the sidebar on the right and then the other way around.

As I mentioned at the beginning of the first post in this series:

  1. The HTML structure will be coming from the Solum starter theme I released last week. Solum doesn’t contain any layout markup, so it gives a clean starting point.
  2. I will not be including menus in these tutorials. For examples of how to handle menus in responsive design, I would suggest taking a look at the mo.js project.

HTML Structure

Here is a simplified example of the HTML output of the Solum theme. If you already read the post on single column layouts, you’ll notice that the only addition is the #secondary div which holds the sidebar.

<body>
    <div id="page">
        <div id="header" class="site-header">
            <div class="wrap">

                <div id="branding" role="banner">
                    <p class="site-title"><a href="http://example.com">Site Title</a></p>
                    <p class="site-description">Just another WordPress site...</p>
                </div><!--#branding-->

            </div><!--.wrap-->
        </div><!--#header-->

        <div id="main">
            <div class="wrap">

                <div id="primary">
                    <div id="content" role="main">
                        <p>Article content...</p>
                    </div><!--#content-->
                </div><!--#primary-->

                <div id="secondary">
                    <div class="widget">
                        <p>Sidebar content...</p>
                    </div><!--.widget-->
                </div><!--#secondary-->

            </div><!--.wrap-->
        </div><!--#main-->

        <div id="footer" class="site-footer">
            <div class="wrap">

                <p class="site-credits">© Copyright owner</p>

            </div><!--.wrap-->
        </div><!--#footer-->

    </div><!--#page-->
</body>

The structure is explain in more detail in the single column layout post, so I’ll just continue on to the CSS.

CSS Reset

We’ll use the CSS reset from the single column post as well.

/* =Reset
-------------------------------------------------------------- */

* {
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	box-sizing: border-box;
	margin-top: 0;
}

html,
body,
div{
	margin: 0;
	padding: 0;
}

Single Column Layout for Mobile

We’ll start with just one column for the mobile layout, with the content column coming first and the sidebar below it. Before we get to that, lets add some color so we can tell the different elements apart.

/* =Color
-------------------------------------------------------------- */

#header{
	background: #cccccc;
}

#main{
	background: #dddddd;	
}

#secondary {
	border: 1px solid #bbbbbb;
}

Just like the single column layout, the #header is gray and the #main section is lighter gray. However, this time we’ve added a border around the #secondary div that hold the sidebar. Now let’s move on to the actual structure.

/* =Structure
-------------------------------------------------------------- */

.wrap{
	max-width: 1140px;
	margin: 0 auto;
	padding: 1em;
}

.wrap:after {
	content: "";
	display: table;
	clear: both;
}

#primary{
	max-width: 720px;
	margin: 0 auto;
}

#secondary{
	max-width: 400px;
	margin: 0 auto;
	padding: 1em;
}

Starting at the beginning, the .wrap divs have a maximum width of 1140px and are centered on larger devices by the setting the margin to “0 auto”. The padding is to keep the text from touching the borders of the browser on smaller screens.

The code in the .wrap:after section is to make sure each .wrap div contains all floated elements inside it, rather than letting the floated elements overlap the edges. This is often called a “clearfix” hack. For a brief history of clearfix hacks over the years, check out Chris Coyier’s article, Force Element To Self-Clear its Children.

The #primary section sets a maximum width for the main content column. We don’t ever want a content column getting really wide because wide columns are more difficult to read. Here we’re limiting this column to 720px and centering it using “margin: 0 auto;” for when the screen is larger than 720px.

The #secondary section limits the sidebar width to 400px. Sidebar content is rarely intended to be displayed in a wide area. Since the sidebar will not be wider than 400px in the full two column layout, we limit it here also. This way the sidebar will appear in a consistent manner regardless of the screen size. Just like the other elements, we center it using “margin: 0 auto” and then give it a padding of 1em so the content doesn’t touch the border we gave it earlier. Here’s what it should look like on mobile.

Two column mobile screenshot

Two Column CSS Layout

Here’s where we finally get to use CSS media queries. This is what it looks like:

/* =Media Queries
-------------------------------------------------------------- */

@media screen and (min-width : 900px) {
	#primary{
		float: left;
		width: 65%;
		padding-right: 1em;
	}

	#secondary{
		float: right;
		width: 35%;
	}
}

First let’s look at the @media screen line. This line determines when the enclosed CSS is applied. In this case, it is applied when the website is being displayed on a screen that has a width of 900px or more.

The #primary section is floated to the left and given a width of 65%. Then 1em of padding is added on the right to prevent the enclosed content from touching the sidebar that will be positioned next to the right of the main content.

The #secondary section is floated to the right and given a width of 35%, so that it sits next to the #primary section.

Here’s what it looks like on the desktop.

Two column desktop screenshot

Finally, if we wanted the sidebar to be on the left and the content on the right, we would only need to change the float directions of the #primary and #secondary columns in the media query section of the stylesheet and change “padding-right” to “padding-left” on the #primary div.

/* =Media Queries
-------------------------------------------------------------- */

@media screen and (min-width : 900px) {
	#primary{
		float: right;
		width: 65%;
		padding-left: 1em;
	}

	#secondary{
		float: left;
		width: 35%;
	}
}

That’s all for today. The next post will cover three column layouts. If you have any questions or comments, feel free to let me know via the contact page. Thanks!