CSS CSS Layout Basics Page Layout with the Float Property The Float Challenge Solution

Michael Lambert
Michael Lambert
6,283 Points

Odd behaviour with floats

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">  
  <link rel="stylesheet" href="test.css">
</head>

<body>
  <!-- wrap1 has floated elements -->
  <div class="wrap1 clearfix">
    <div class="prim1 col">
      <p>first paragraaph</p>
    </div>
    <div class="sec1 col">
      <p>second paragraph</p>
    </div>
  </div> 

  <!-- wrap2 has no floated elements -->
  <div class="wrap2">
    <div class="prim2">
      <p>first paragraaph</p>
    </div>
    <div class="sec2">
      <p>second paragraph</p>
    </div>
  </div>  
</body>
</html>
* {
  box-sizing: border-box;
}

.wrap1 {
  border: 1px dashed green;
}

.col {
  float: left;
}
.prim1 {
  background-color: red;
  width: 30%;
}

.sec1 {
  background-color: blue;
  width: 50%;
}

.wrap2 {
  border: 1px dashed green;
}

.prim2 {
  background-color: red;
  width: 30%;
}

.sec2 {
  background-color: blue;
  width: 50%;
}

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

This might make more sense if you run the above code. The floated elements in 'wrap1', seems to make the 'p' elements background colour extend to fill the parent div. I know it's the size of the p elements margin but why doesn't the same apply to the 'p' tags in the 'wrap2' container? Afterall, the 'p' elements in 'wrap2' are contained within it but the 'p' elements background colour just surrounds the text?

2 Answers

Hi Michael,

A small clarification, you mentioned in your question that the paragraph has the background color but you actually applied it to the div's containing the paragraphs. You would see something different if it was applied to the paragraphs themselves.

The difference in the 2 has to do with how vertical margins collapse. Normally, when 2 vertical margins are touching each other then they will join together and form a single margin. If there isn't any border, padding, or content to separate the margins then this collapsing will occur.

However, margins of floated and absolutely positioned elements do not collapse and this is why you get the different behavior between the two.

The following mdn page has more information on this: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

The first wrapper div -

Because the .prim1 and .sec1 div's are floated, their margins will not collapse with other margins. This means that the top margins of the paragraphs will not collapse with the top margins of the .prim1 and .sec1 div's. The same for bottom margins. Therefore those div's will fully contain the paragraph element including it's default top and bottom margins. This is why you see the background of the div's in the margin area of the paragraphs.

The second wrapper div -

Since nothing is floated here, we'll get the normal collapsing behavior. For one example, the top margin of the "first paragraph" will collapse with the top margin of the .prim2 div, forming a single margin. In this way, the margins of the paragraph are able to reach outside of the parent div. The div's don't contain the margins. They only contain the content of the paragraph which is just the single line of text.

In both cases, the top margins of the .prim1 and .prim2 div's don't combine with the top margins of the wrapper div's because you applied a dashed green border to the wrapper div's. This acts to physically separate those margins and prevent them from collapsing.

You experienced this when you added the border to the .prim2 div. This acts to physically separate the paragraph margins from the div's margins and prevents collapsing.

Michael Lambert
Michael Lambert
6,283 Points

Hi Jason,

Thanks for the detailed explanation. I've been pulling my hair out trying to understand the behaviour since my initial post. Now I'll be able to push on with the course. Kinda stopped me in my tracks not advancing through the course till I got everything taught so far, clear in my head and your explanation certainly did that :)

Yea, the whole background colour of the paragraph was my mistake. I used the literal text of the paragraph as a descriptor to highlight the floated elements rather than directly mention the element that had the colour assigned to the actual DIV.

Elizabeth Martinsen
Elizabeth Martinsen
8,024 Points

Now you've got me stuck on this too! The best answer I could come up with was to add some global resets for margin and padding to override the browser defaults. It got set 1 to look like set 2, while in two columns. Hope you weren't looking to make it the other way around - got nothing for that :D

I still can't figure out know why adding the float caused the issue, though. I'd assume it's got to do with defaults again, but I keep coming up with the same ten Stack Exchange articles on clearing floats. My Google-fu has failed me. Let me know if you find anything!

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
Michael Lambert
Michael Lambert
6,283 Points

I was able to get the 'p' elements to look the same by making them inline but that only works because inline doesn't support margins. I'm still completely stumped though as to the explanation for what is really going on when they are floated as block level element. So bizarre. Been thinking about it all day lol

Michael Lambert
Michael Lambert
6,283 Points

Now I'm adding to my own confusion.

If I add either a border around '.prim2' or set it to overflow: hidden its background colour fills its entire container like the ones that are floated and as I would expect it to do without having to add those so I'm still not sure why without that fix the background color shrinks to only contain the 'p' element.