A whole bunch of years ago, we posted on this idea here on CSS-Tricks. We figured it was about time to update that and do the subject justice.
Imagine a scenario where you need to split a layout in half. Content on the left and content on the right. Basically two equal height columns are needed inside of a container. Each side takes up exactly half of the container, creating a distinct break between one. Like many things in CSS, there are a number of ways to go about this and we’re going to go over many of them right now!
Using Background Gradient
One simple way we can create the appearance of a changing background is to use gradients. Half of the background is set to one color and the other half another color. Rather than fade from one color to another, a zero-space color stop is set in the middle.
.container {
background: linear-gradient(
to right,
#ff9e2c 0%,
#ff9e2c 50%,
#b6701e 50%,
#b6701e 100%
);
}
This works with a single container element. However, that also means that it will take working with floats or possibly some other layout method if content needs to fill both sides of the container.
See the Pen Left Half / Right Half with Background Gradient by CSS-Tricks (@css-tricks) on CodePen.
Using Absolute Positioning
Another route might be to set up two containers inside of a parent container, position them absolutely, split them up in halves using percentages, then apply the backgrounds. The benefit here is that now we have two separate containers that can hold their own content.
See the Pen Left Half / Right Half with Absolute Positioning by CSS-Tricks (@css-tricks) on CodePen.
Absolute positioning is sometimes a perfect solution, and sometimes untenable. The parent container here will need to have a set height, and setting heights is often bad news for content (content changes!). Not to mention absolute positioned elements are out of the document flow. So it would be hard to get this to work while, say, pushing down other content below it.
Using (fake) Tables
Yeah, yeah, tables are so old school (not to mention fraught with accessibility issues and layout inflexibility). Well, using the display: table-cell;
property can actually be a handy way to create this layout without writing table markup in HTML. In short, we turn our semantic parent container into a table, then the child containers into cells inside the table — all in CSS!
See the Pen Left Half / Right Half with Display Table by CSS-Tricks (@css-tricks) on CodePen.
You could even change the display properties at breakpoints pretty easily here, making the sides stack on smaller screens. display: table;
(and friends) is supported as far back as IE 8 and even old Android, so it’s pretty safe!
Using Floats
We can use our good friend the float
to arrange the containers beside each other. The benefit here is that it avoids absolute positioning (which as we noted, can be messy).
See the Pen Left Half / Right Half with Floats by CSS-Tricks (@css-tricks) on CodePen.
In this example, we’re explicitly setting heights to get them to be even. But you don’t really get that ability with floats by default. You could use the background gradient trick we already covered so they just look even. Or look at fancy negative margin tricks and the like.
Also remember you may need to clear the floats on the parent element to keep the document flow happy.
Using Inline-Block
If clearing elements after floats seems like a burden, then using display: inline-block
is another option. The trick here is to make sure that the elements for the individual sides have no breaks or whitespace in between them in the HTML. Otherwise, that space will be rendered as a literal space and the second half will break and fall down.
See the Pen Left Half / Right Half with Inline-Block by CSS-Tricks (@css-tricks) on CodePen.
Again there is nothing about inline-block that helps us equalize the heights of the sides, so you’ll have to be explicit about that.
There are also other potential ways to deal with that spacing problem described above.
Using Flexbox
Flexbox is a pretty fantastic way to do this, just note that it’s limited to IE 10 and up and you may need to get fancy with the prefixes and values to get the best support.
Using this method, we turn our parent container into a flexible box with the child containers taking up an equal share of the space. No need to set widths or heights! Flexbox just knows what to do, because the defaults are set up perfectly for this. For instance, flex-direction: row;
and align-items: stretch;
is what we’re after, but those are the defaults so we don’t have to set them. To make sure they are even though, setting flex: 1;
on the sides is a good plan. That forces them to take up equal shares of the space.
See the Pen Left Half / Right Half with Flexbox by CSS-Tricks (@css-tricks) on CodePen.
In this demo we’re making the side flex containers as well, just for fun, to handle the vertical and horizontal centering.
Using Grid Layout
For those living on the bleeding edge, the CSS Grid Layout technique is like the Flexbox and Table methods merged into one. In other words, a container is defined, then split into columns and cells which can be filled flexibly with child elements.
If the cells in the demo below are stacked, then your browser doesn’t support CSS Grid. At the time of this writing, support is limited to Firefox, Chrome, Safari and Opera (except Opera Mini).
See the Pen Left Half / Right Half with Grid Layout by CSS-Tricks (@css-tricks) on CodePen.
Isn’t it cool how many ways there are to do things in CSS?
I use (fake) tables a lot; whenever I have variable sized content and want everything to be the same height; whenever I want horizontal elements with weighted widths (like a nav bar); whenever I want to
vertical-align: [whatevs];
content. Though much of the time, if I have fixed height/width elements I want middle valigned I’ll use inline-blocks. But I think people overthink how to accomplish things thatdisplay: table(-cell);
does quite effectively. I think while we wait for flexbox support to be more ubiquitous, people should keep table-displays handy in their toolkit.This is exactly how I work. I use Harry Roberts ‘Flag object’ extensively. A lot of what flexbox does you can do with display table. I’m happy to continue working in this manner until we drop support for IE9.
You can also use CSS columns. It’s supported by IE 10, Chrome 4+, Firefox 2+, Safari 3.1+, Opera 15+.
@Chris, if you like, add that Pen to your post.
Came down to the comments to post the same thing. If you’re looking to position content into newspaper-like sections, this is a great way to go about doing it!
More info to be had here: https://developer.mozilla.org/en-US/docs/Web/CSS/columns
The columns solution would be nice if it was solid. You need equal height content for it to work properly. In this case you can remove or add some stuff to make a third column to appear – you get third column in both ways, by deleting or by adding. In short you shouldn’t use it to do this layout, because it has side effects that are triggered too easily.
Think any of the solution work fine but the use of vh or vw like illustrated on the grid example works best.
Hood share very usefull knowledge.
The background gradient version leads to a slightly unsharp edge between the two colors in FF37, all the other ones are sharp.
We were going for the same, left-right base layout, we want it to be fixed (left)-fluid (right) column and vice versa. Furthermore, we wanted a responsive solution.
So, we implentend it with a mixed solution, fixed-floated column elements, background gradient, and a solid background for sidebar with negative margin.
[left sidebar: https://www.skroutz.gr/c/40/kinhta-thlefwna.html and
right sidebar https://www.skroutz.gr/c/86/kinhth-thlefwnia.html%5D
I have too followed some of the ways to achieve this effect, but still cannot decided which should one consider in case it is going to be responsive.
All of the above are responsive and can be further responsive by adding media queries to react different on different screen sizes.
I used mixed techniques to create the effect. Mixed can be more powerful and flexible than using a single specific technique.
This should work perfectly in everything since IE8 including Opera Presto and Safari 5 Windows.
And just because… I made it work with IE6 and IE7. I like silly browsers when they behave.
Really liked your technique. I started from there and i implemented a fixed-fluid layout with a max-width and center positioning.
[codepen_embed height=”268″ theme_id=”0″ slug_hash=”Byvdbw” default_tab=”result” user=”katsampu”]See the Pen Left Half and Right Half Layout by Giorgos Katsiampas (@katsampu) on CodePen.[/codepen_embed]
Really liked your technique. I started from there and i implemented a fixed-fluid layout with a max-width and center positioning.
@Katsampu
Fixed the overflowing issue you have, maintaining center and fixed sizes, but sacrificing fluidity in smaller widths. Have to go for a responsive solution. Pure fluid layout doesn’t work that much better with low widths either so I consider getting scrollbars back properly a bigger win than losing fluid.
A simpler version of the fixed fluid can be done quite easily. Ignoring the background color/same height bit.
Just give your static column a width and float left and the fluid right column overflow hidden. Add desired clearfix to container
Nope, this has nothing to do with what is shown here. The entire point is to have something that allows styling of equal height backgrounds or that would give the impression of having two equal height columns.
Your solution is the very basics of first float based layouts and it won’t work if right side content is longer than left side: it will result in right side content flowing under the left side content.
The second column won’t drape around the first even with longer content because of the new bfc that is created via overflow hidden. Nevertheless it is true that this solution doesn’t help much with equal height columns.
Grid Layout is worth a look, more control than Flexbox and easier to work with than some of the other methods. There’s polyfills available such as https://github.com/codler/Grid-Layout-Polyfill
I used to work with float inside a div alot. Can someone show the basic performance over different browsers and different devices ?