In the answer to How does the CSS Block Formatting Context work? the author mentions that:
In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch)
What the above line means:
Because a box can only be rectangular and not irregular shaped this means a new block formatting context between two floats (or even beside one) will not wrap around neighbouring side floats. The inner, child boxes can only extend as far as to touch their parents left (or right in RTL) edge.
I wanted to verify this, so I created this JS Bin test case:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="table-cell">
<div class="negative-margin">
</div>
</div>
</body>
</html>
CSS
body {
padding: 50px;
}
.table-cell {
display: table-cell;
border: 1px solid black;
width: 200px;
height: 200px;
}
.negative-margin {
border: 1px solid blue;
width: 100px;
height: 100px;
background: #666;
margin-left: -20px;
}
However as it can be seen, the contained element is crossing the left edge of its container:
Can someone please explain what am I missing here?
Update 1
Some people have mentioned that this is happening because of the negative margin. By following the answer to the aforementioned question, I was expecting the negative-margin not to move the contained element outside its container. To reference:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
And the .table-cell
element satisfies this definition. So why is the .negative-margin
crossing its parent's border?