0

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:

Test Case

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?

Community
  • 1
  • 1
TheFooProgrammer
  • 2,439
  • 5
  • 28
  • 43

1 Answers1

0

Your margin-left is causing the inner div to cross the borders...

margin-left: -20px;
Stuart
  • 1,544
  • 5
  • 29
  • 45
  • Of course :) But as the negative-margin element is inside a "box formatting context", by definition, it was supposed not to cross its containing block's left edge. – TheFooProgrammer Feb 27 '13 at 13:28
  • The negative margin will still position the inner `div` where you tell it to... if you want it to cut off then you need to use `overflow:hidden;` on your table-cell class. – Stuart Feb 27 '13 at 13:34
  • "9.1.2 Containing blocks ... **Each box is given a position with respect to its containing block, but it is not confined by this containing block**; it may overflow." [link](http://www.w3.org/TR/CSS2/visuren.html) – Stuart Feb 27 '13 at 13:35
  • see my extra comment above (link at the end), sorry it took me a while to get the edit right... – Stuart Feb 27 '13 at 13:40
  • I assume then the explanation/interpretation on that stackoverflow link is incorrect. I am referring to this part: **The inner, child boxes can only extend as far as to touch their parents left (or right in RTL) edge.** – TheFooProgrammer Feb 27 '13 at 14:14
  • must be, the link gave comes from w3.org... they know best, and it states there that the child is not confined by the containing block. If you increased the width of the child, then yes, it would only touch the sides of the containing block, but as you've given it a negative margin, you've altered it's **position**. – Stuart Feb 27 '13 at 14:26
  • Thanks Stuart. If you update your answer to contain our comment thread, I will mark it as accepted. Otherwise I already knew that a negative `margin-left` will replace the element and move it toward the left, but I was confused, because that was contradicting with the answer to that other stackoverflow question, which surprisingly was marked as accepted. – TheFooProgrammer Feb 27 '13 at 15:00