Floating alternate elements to left and right

I have a minor layout query/curiosity regarding floats and clears.

Imagine a bunch of blog-style snippets in chronological order. They are floated alternately to the left and right. Is there any method, other than the clear property, which will keep the layout robust when one or two snippets suffer from an unavoidable variation in height? They are mostly the same height, but the occasional long heading or awkward line-break may make one div longer than the rest.

Example:


.snippet {width: 48%;}
.left {float: left;}
.right {float: right;}

<div class="snippet left"> ...div 1... </div>
<div class="snippet right"> ...div 2... </div>
<div class="snippet left"> ...div 3... </div>
etc.

Say that the 2nd div is a bit shorter than the first. The 3rd div in the mark-up will hop over and sit underneath the shorter div on the right of the page. I fixed this issue by clearing the floats (i.e. float: left; clear: left;). But setting clear on the divs of one column leaves a gap below any shorter div in the opposite column.

This is obviously no big issue: it still looks fairly neat and it’s robust, above all.

But I’m curious about why clearing one set of divs causes the other set to apparently obey the clear, too. Is there another way of keeping a robust layout which would avoid that gap and make the two columns extra tidy?

Yes, there’s a much nicer way that isn’t so well known because of problems that IE6 used to throw up, but which is basically irrelevant now (and there is a fix for it anyway).

Instead of using floats, use display: inline-block; It works beautifully.

All you need is


.snippet {
  width: 48%;
  display: inline block;
}

They will all sit side by side nicely, and can be aligned to each other’s top or bottom. To align them all to the bottom, add vertical-align: bottom; but most likely vertical-align: top will look better.

Thanks for replying, Ralph. But that method will still produce gaps below any short div.

O, I didn’t realize that was a requirement. If you want the divs sitting neatly atop each other in columns, you’ll have to create two separate columns, which will mean you’ll have to organize them manually.

Not a requirement as such, but it was the point of my question. :wink: I can’t reorganise the divs (even if I could, it wouldn’t then work in single column view), so I’ll live with the occasional gap. It’s not what I would have expected from floats, but it’s no biggie.

With floats you’ll also need to use clearing so that you don’t get two columns stacked up against each other on the right.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>untitled</title>
<style>
div {
  letter-spacing: 0;
  display: inline-block;
  vertical-align: top;
  width: 48%;
  background: red;
  margin-bottom: 10px;
}

span {
  float: left;
  width: 48%;
  background: green;
  margin-bottom: 10px;
  /*clear: left;*/
}
span:nth-child(even) {q
  float: right;
  /*clear: none;*/
}
</style>
</head>
<body>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div>2</div>
<div>3</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div>5</div>

<br>
<br>
<br>

<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
<span>2</span>
<span>3</span>
<span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
<span>5</span>
</body>
</html>

With inline-block you have the problem of white-space.
I’ve used floats with min-height if I have some idea over what is a reasonable size content to expect in the blocks.
This gives same height columns, if something is larger than that threshold you’ll still get gaps but it can tidy things up a bit.

The easiest way to achieve equal height columns is to use display: table;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>untitled</title>
<style>
div { display: table-row }
span {
  display: table-cell;
  width: 50%;
  background: purple;
}
</style>
</head>
<body>
<div>
  <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
  <span>2</span>
</div>
<div>
  <span>3</span>
  <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
</div>
<div>
  <span>5</span>
</div>
</body>
</html>

Everyone treats IE6 is as dead these days, but IE7 is about 1% globally and dead to me unless specifically asked for.

Yeah, display: table is probably the way to go here, and just give each cell a background color (even if subtle) to give the impression that there are no gaps.

Ah, no guys. I wouldn’t use display: table and I wouldn’t advise any developer to use it for content that is not tabular in nature. ATs are starting to make use of display: table, depending on what browser API their running on.

I’ll stick with my current workaround of clearing the floats. As I said, it’s not a biggie, but it helps me to understand these little quirks.

That sounds odd to me, do you have more info on it?

My question is, are those select screen readers doing the right thing by interpreting display: table that way?

Second question, do you also never use list-style:none; because some AT’s don’t treat them as lists?

Yes, they are doing the right thing, on balance; as they are by announcing CSS content, which is a similar issue. I would not describe two of the most popular aural ATs as “select”. And no, I do not set list style to none on content lists.

Only a sith deals in absolutes :slight_smile: I personally don’t have any issue with using display:table;

https://twitter.com/jkiss/status/222437096823078912

And no, I do not set list style to none on content lists.

Are you doing a semantic dance? What is a content list? Do you use a list of links for navigation?

You were the one claiming there was a problem with display: table; big enough that it should never be used. That is was it was created for, tabular data(in a <table>) doesn’t need those styles because they are the default.

Ah, no guys. I wouldn’t use display: table and I wouldn’t advise any developer to use it for content that is not tabular in nature.

A list of navigation links is a structural list; not a content list. I am not too sure about your last paragraph, but “big enough that it should never be used” is not in the least a fair interpretation of what I wrote and it is contradicted by the subsequent quote. Display:table is obviously not appropriate for the content with which I am working, as outlined in the first post. That does not mean that it should never be used.

The only reason I am continuing with this is that you are claiming that a CSS property shouldn’t be used for a purpose it was first created.

“Ah, no guys. I wouldn’t use display: table and I wouldn’t advise any developer to use it for content that is not tabular in nature.”
I’m struggling to think of good examples of when you would use display:table; in that case. You seem to be dismissing it entirely for reasons that aren’t really a problem.

Display:table is obviously not appropriate for the content with which I am working, as outlined in the first post. That does not mean that it should never be used.

No, that’s not obvious at all. display:table is for visual formatting.