I'm trying to use floating divs inside the element with the display:table-cell
property, but I have encountered unexpected behavior.
Why are the elements in the first column affected by the elements in the second column (a
in the first column is suddenly moved down)? Is there any way to prevent that behavior?
.table {
display: table;
}
.cell {
display: table-cell;
}
.cell a {
padding: .5em;
border: .1em solid black;
}
.cell+.cell a {
float: left;
}
<div class='table'>
<div class='cell'>
<a>cell1</a>
</div>
<div class='cell'>
<a>cell2</a>
<a>cell2</a>
</div>
</div>
Note: Elements next to a floating element will flow around it. To avoid this, use the clear property or the clearfix hack (see example at the bottom of this page).
The float CSS property places an element on the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the page, though still remaining a part of the flow (in contrast to absolute positioning).
Clearing Floats # Layout issues with floats are commonly fixed using the CSS clear property, which lets you "clear" floated elements from the left or right side, or both sides, of an element.
Floating everything can make for a great deal of inconsistency; depending on how wide a screen is and how tall certain elements are rendered, you can end up with a hodgepodge of screen jag. For example, widening the screen would cause more elements to fit on the top line, so they would jump up.
Fascinating behavior. I have several theories. Although I agree that using display: table-cell
seems random, there are occasional uses for it so I'll leave that in there for my answer. I'm sorry if my answer is overtly complex; I'll try to simplify it:
First of all
To understand why the element is pushed down is a matter of understanding how vertical-alignment works for table-cell
s:
The only vertical-align
property values that should be used for table-cell
s are top
, middle
, and bottom
(see this excellent css-tricks article). Anything else is undefined behavior--meaning browsers may do whatever they want with them, and different browsers will probably do different things. This is probably not [ever...] what we want.
By default, browsers will give all td
elements vertical-align: middle
. So when you're creating a normal HTML table
, you never necessarily have to worry about the vertical-align
property.
On the other hand, all normal elements, by default, have vertical-align: baseline
. This value on elements with display: table-cell
causes our dreaded undefined behavior.
You are manually constructing a table using elements that won't, by default, behave like a table (this is why you probably shouldn't be using display: table-cell
when you're not completely sure what you're doing). You therefore have to put all the default styles of a table on by yourself. This includes specifying a vertical-align: top|middle|bottom
property for your .cell
s.
So why is it only pushed down when I float the elements in one cell?
Again, it's undefined behavior. When you don't float, this doesn't seem to cause a problem; the elements are still able to intelligently find the baseline of the inner text and vertically align themselves so they appear where you'd expect them. When you float here, there are two things to note:
1) Remember that floating removes an element from the normal flow of the DOM. This means other elements, including the element's parent, can't interact with that element like they normally would.
2) Remember that
table-cell
s are intelligent; they can dynamically, vertically position their children.
Combining these two leads me to think that when you float those elements:
1) Their .cell
parent is losing track of where the text is inside them.
2) It can't properly communicate to its neighbor cell where the baseline is--it just uses its bottom edge.
3) The neighbor cell correctly vertically aligns its content to that baseline, resulting in the shift downward.
The fix?
Put vertical-align: middle
responsibly on your .cell
s:
.cell {
display: table-cell;
vertical-align: middle;
}
(And the a
tags should probably be display: inline-block
too). Here's an updated JSFiddle. Regards.
You have a plus sign (i.e.: adjacent siblings selector) in that rule .cell+.cell a
, removing it works as expected:
.cell a {
float: left;
}
http://jsfiddle.net/vg5j7xgc/5/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With