Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

CSS

huckleberry
huckleberry
14,636 Points

CSS pros... Something about box model properties are leaving me with a headache. Come flaunt your skills and school me!

Ok, so first, it's been a little while since I've covered all the stuff in CSS foundations such as the box model and whatnot. I'm here now working my way through the CSS Layout Techniques and as per usual I decided to veer off course to mess around with things for a bit and see what happens.

I've learned one thing that was a great hallelujah moment involving the whole collapsing margins phenomenon, but in my messing around I came across two things that have me wondering what's going on and what the rules or specs are.

Ok so... I took the code from the actual lesson within the lesson for floats and started modifying it to see what happened.

Where I hit my initial snag was with this...

I first set the .extra-content div to have another class of .col2 instead of sharing the .col class-name. I wanted to make that normal.. sans float.

So I had

.col2 {
    width: 60%;
}

This gave me this...

The issue being the space between the header and the floated div.

I finally realized that it was the margin of the <code><h3></code> that contains the text Extra Content, spilling out over the .col2 div and merging with the bottom margin of the header (which was actually 0) to collapse and form some semblance of a bottom-margin on the header which the primary-content div was obeying.

Ok, so I remove the top margin of the h3

.col2 {
    width: 60%; 
}

h3 {
    margin-top: 0;
}

bam, it fixes it...

Ok...fantastic. But, a couple of things.

  1. Why does the margin from an element within a div spill out over it? Why isn't the margin applied only inside of the div and contained therein? I plan on covering all the stuff from CSS foundations again AND going through the new CSS courses but please refresh my memory here.
  2. In the course of messing around I discovered two unique little quirks that I was either unaware of or had forgotten if it had been covered in the lessons but here they are...
  • 2.a Without having the <code>margin-top: ;</code> of the <code><h3></code> set to 0, I tried applying a border to the div in order to see things a little cleared. That old trick. But what happen was that the space that was there from the margin collapse thingy was now gone.
/* h3 is default settings, no margin-top: 0; */

.col2 {
    width: 60%;
    border: 1px solid red;
}

So what about adding the border all of a sudden eliminates the margin? Can margin not spill out past a defined border? Like, if the border is undefined then margin just has a field day but once a border is applied then margin gets all pouty and stays inside?

  • 2.b When messing around with some other stuffs, I noticed that if the same problem of the margin collapse creating that spaced would disappear if I gave the .col2 div even a slightest hint of padding. Just 1px got rid of the margin issue.
.col2 {
    padding: 1px;
}

or even

.col2 {
    padding-top: 1px;
}

turned this...

into this...

Why? What does padding have to do with anything regarding the margin spilling over? Please explain how one affects the other! lol. Does padding negate the margin collapsing effect like the border property seems to?

Thanks in advance for any and all help!!

2 Answers

Hey,

I played with the project files and did the same changes you did. Form my experience I noticed that having a block level element intertwined like that with floated elements causes issues sometimes with the document flow. Because you removed the float property the div went form inline to block level. This is causing the margins to collapse. The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance. If you make all your columns inline or inline-block you wouldn't have this problem. Block elements don't really like flowing with different elements.

Now as to why adding a border and padding fixed the problem is because borders and padding in this case separate the margin.

Also while playing I noticed that the margin that is causing the layout to break is client specific style. Chrome in my case was adding this to the h3.

-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;

It's probably the same case across browsers with some differences. This was resolved with css reset. But this wouldn't break the flow normally.

Hope this helps

huckleberry
huckleberry
14,636 Points

Thank you so much dude! Really appreciate you taking the time to knuckle down on the code and work with what I did.

A couple of things I just want to add.

I realize the things that I was messing around with aren't exactly recommended and wouldn't really be done that way but I was just exploring and being silly trying to see what would happen in different situations. Just, you know, so you don't think I'm herp-derp or anything lol

I knew about the margin collapse issue but I did not realize there were very specific criteria for it as you stated it here...

The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.

That, wow who comes up with this stuff? lol

But there's something that's confusing me here. I thought it was the top margin that collapsed with the bottom margin. The way I'm reading what you said is top margin collapsing with top margin... aaaand I don't get it lol.

wait... ok so... just thought about it a little harder, what you're saying -- in more layman's terms lol -- is that the top margin of a parent's element(if it's a block level element) will collapse with the top margin of the first child element inside of it -- if it's also a block element -- if said parent has no margin.

In this case, the h3 element, which is block level, was inside a div, which had no margin, therefore, the h3's default top margin collapses with the non-existent div top margin and poof, the div now has a margin.

Ok, so that's slightly different than what I thought. Here's what I thought.

I thought that top margins of block level elements merged(collapsed) with the bottom margins of block level elements above them and vice versa... and that the larger of the two margins is what gets rendered. So... for example, my understanding was that say, a header has a margin-bottom: 30px; and an H1 under that header has a margin-top: 15px;

<style>
    header {
    margin-bottom: 30px;
}
    h1 {
    margin-top: 15px;
}

<header>
    <stuff>
        <nested class="stuff">
        <img src="http://stuff.com/stuffing.png" alt="not stuff">
    </stuff>
</header>
<h1>Heading About Stuff</h1>

so, the margins meet, there's chemistry, sparks fly and they get together, however, the larger one wins out and the total space between the bottom of the header and the top of the h1 is now 30px, not 45px like one might think.

I didn't realize what you're talking about with the whole first child block level flow element thingamahoozitz.

So, was my previous assumption wrong? Or are they both correct and simply two sides of the same collapsing coin?

With my prior assumption -- the scenario I just described -- along with what you described with the child and parent collapsing, then the float from my initial post (.primary-content) getting pushed down a bit and creating that bit of space...

Makes sense because as you're describing it the h3 margin-top collapses with the margin-top of its containing div because that div had no margin, NOW the div has margin and since that div is right under the header, which had no bottom-margin in the first place, the margins collapse once again and that gives the header a slight bottom margin which then pushed the float down.

Is that right? Please say that's right.

And thanks for pointing out the padding/border separating the margins thing. So padding and or borders are like the annoying friend that gets inbetween two folks trying to hook up at a party... it's a 'collapse blocker' lol.

Also, as to what you found your browser was adding to the elements... the styling.

  1. How did you find that? Is that something within the dev tools in the browser? Like... once you inspect the elements and look at the stylings over to the left where it shows the Rules, Computed, Fonts, Box Model? I never really dug into it too much to notice the browser stylings listed there lol.

  2. I did fail to mention that I was actually using the normalize.css file that was include with the project files. Ooopsies.

Anyway, thanks a ton for getting back to me with a great post. Sorry that it brought up even more questions for me lol... but I do look forward to your reply!

Cheers!

Huck-:sunglasses:

Hey Huck,

I am like you I like to pick things apart in order to understand them better, so I understand the drive you have. Please feel free to send more of these quirks my way, I am always interested.

As to who writes this stuff you should consult w3c and their contributors list. But some of css is pretty quirky under the hood. And we have to work around it.

Now the collapsing is happening with the two top margins of the two block level elements -div and h3 in your case. Addressing either one of those would solve the collapsing issue, as you would see if you gave the h3 an inline display property.

h3 {
    display: inline; 
}

or you can change the display on the div

.col2{
    display: inline-block; 
}

"So, was my previous assumption wrong? Or are they both correct and simply two sides of the same collapsing coin?"

You're not wrong at all, margin collapsing happens more often than we think, it's just more apparent sometimes because it misses with alignment or breaks the layout in a major way. But there are three sides to this coin, and we saw two just by missing around for a bit. look at MDN Margin collapsing

I found the collapsing margins in chromes dev tools

collapsing margin debugging

You should dig into the dev tools and see how your styles are computed and applied by the browser. If you like getting under the hood and seeing css do it's thing the dev tools are awesome. Firefox has some nice features but chrome is fine.

As for client specific styles. I always worked around them by resetting all client styles, but I learned that sometimes you have to use client specific styles when needed to insure consistency. So it doesn't hurt to do some light reading there. Check out BrowserHacks

Hope this helps

Ali M