Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using float property inside table-cell element slides previous content down

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>
like image 902
Razial Avatar asked Dec 19 '15 18:12

Razial


People also ask

Which property is used to prevent an element's content from floating around a floated element?

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).

What does floating an element do in CSS How do you float an element?

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).

What property did we use to fix the float problem?

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.

What is the drawback of the CSS float property?

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.


2 Answers

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-cells:

The only vertical-align property values that should be used for table-cells 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 .cells.

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-cells 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 .cells:

.cell {
    display: table-cell;
    vertical-align: middle;
}

(And the a tags should probably be display: inline-block too). Here's an updated JSFiddle. Regards.

like image 140
bowheart Avatar answered Sep 22 '22 14:09

bowheart


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/

like image 32
marcanuy Avatar answered Sep 20 '22 14:09

marcanuy