CSS Fudamentals: Containing Children

CSS Fundamentals: Containing Children

I’ve received multiple requests for simpler CSS tutorials that teach the tricky fundamentals. This will serve as the first entry in a series that will receive new additions sporadically each month. Today, we’ll be reviewing the overflow: hidden, and clearfix tricks to force a parent div to contains its children.

The Overflow: Hidden Trick

Have you ever noticed that when you float all of the children elements within a div, the parent takes up zero space? For example, in your code editor, adding the following within the body tag.

<div id="container">
  <div id="main">

  </div>
  <div id="sidebar">

  </div>
</div>

Now, let’s add a bit of CSS to simulate a typical website.

#container {
	background: red;
	width: 800px;
	padding-bottom: 2em; }

#main {
	background: green;
	height: 500px;
	width: 600px;
	float: right; }

#sidebar {
	background: blue;
	height: 500px;
	width: 200px;
	float: left; }

Above, we’re simply setting background colors and floating the sidebar and main divs to the left and right, respectively. Note the “padding-bottom: 2em;”. This should allow us to see the red background at the very bottom, right? View the page in your browser, and you’ll see:

No Overflow Applied

Where did the red background go? Why isn’t it displaying?

The Solution

When you float all of the children, the parent essentially takes up no space. To better illustrate this fact, let’s set an arbitrary height of 50px to the container, and then reduce the opacity of the children divs so that we can see the red background beneath.

#container {
  .. other styles
  height: 50px; }

#main, #sidebar {
  opacity: .5; }

Refresh your browser, and you’ll see:

Not Contained

How odd. We’ve specified a height of 50px for our container div, yet the main and sidebar divs blatantly overflow its boundaries, like spoiled bratty divs.

Return to your stylesheet, and apply one style:

#container {
  ...other styles
  overflow: hidden;
}

After another refresh, we see:

Not Contained

Well that partially helps. Now, we don’t have to worry about the pubescent children disobeying their parent. Having said that, this really doesn’t help our situation.

“Try to avoid specifying heights as much as possible. There’s usually a smarter method.

The solution is to rip out the height property from our container. Remove the following property.

#container {
  ...other styles
  height: 50px; /* Remove this */
}

One last refresh, and our problem seems to be fixed.

Overflow Applied

You can also remove the opacity properties. They were just for demonstration purposes.

The Rub

The method demonstrated above will work in most cases. However, let’s introduce another variable. What if we want to position an image on the border of our container, so that it overlaps. You’ve seen this effect many times. For the sake of the example, we’ll just use an image of a circle with a transparent background. On a real site, this might represent a “Buy Now” or “Sign Up” button — something cheesy like that.

Circle

Positioning the Circle

Using CSS, let’s position the image in the top right portion of our “website”, overlapping the edges. This is what we want:

Breaking Boundaries

First, we reference the image within our HTML.

<div id="container">
  <img src="circle.png" alt="Buy Now" />
  ...rest of html

Next, return to your stylesheet, and add the following styles.

img {
	position: absolute; 
	right: -100px;
	top: 20px; }

Positioning Context

One might think that this will place the image just over the right edge of the container div. However, he’d be wrong.

Because we have not set a positioning context, the window will be used instead.

No positioning context set

Obviously, this is not what we want. To apply a positioning context to our container div, simply add “position: relative;” to #container. Once we’ve done so, the image will no longer use the window as a reference.

Lost Half

What’s the Problem Now?

But now, we have a new problem! Because we set overflow:hidden to our container div, we’ve somewhat shot ourselves in the foot. How do we break boundaries and take names if overflow is set to hidden? Should we simply accept that this particular website won’t be taking names today? Absolutely not. In these cases, it’s worth using a different method.

The Clearfix Trick

With this method, we’ll use CSS to add content after our container div. This created content will then clear our div, thus forcing it to contain its children. Now obviously we don’t want to see this content, so we need to be sure to hide it from the viewer.

Return to your stylesheet, remove “overflow: hidden;” from your container div, and add the following:

#container {
	... other styles
	_height: 1%; }

#container:after {
	content: ".";
	visibility: hidden;
	display: block;
	clear: both;
	height: 0;
    font-size: 0; }

This might appear complicated, but I assure you that it’s quite simple.

  • _height: Triggers “haslayout” in Internet Explorer, by using the underscore trick to target IE6 directly.
  • content: After the container div, append a period.
  • visibility: We don’t want to see the period, so hide it from the page. (Equal to setting opacity: 0;)
  • display: Forces the period to display as a block-level, rather than inline.
  • clear: The important property. This clears the main and sidebar divs. This is the same as adding an unsemantic <div style=”clear: both;”> to our page.
  • height: Don’t take up any space.
  • font-size: Just a precaution for Firefox. This browser sometimes adds a bit of space after our parent element. Setting the font-size to zero fixes this.
Perfect

Conclusion

Though the overflow:hidden trick is preferable, it’s not always ideal. You need to use the best solution for the task at hand. The important thing is to learn each method, so that you have the tools to solve the puzzle.


Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://expressionindesign.com Rick

    Instead of using :after and applying the clearfix rules to the specific container, I like to give it it’s own reusable class: “.clearfix”. That way when I’m wrapping more elements that contain floats, it’s easy to just put class=”clearfix” and boom, it’s fixed.

    Good tutorial.

  • http://expressionindesign.com Rick

    An example of how the Blueprint CSS does it and fixes some inconsistencies:

    .clearfix:after {
    content: “020″;
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
    overflow:hidden;
    }
    .clearfix {display: block;}

    • http://www.vileworks.com Stefan

      That’s where I first learned the trick from!

  • Jubal

    I can’t wait long enough for a competent GUI tool to hide this needed hackery completely from my virgin eyes.

    That said, excellent tutorial. Thank you!

  • http://www.webhostright.com/ Webhostright

    Thank you it’s well explained Jeffrey, i will look forward to the others in this series.

  • Nikki

    Setting overflow to auto on the parent container of the floats would clear the floats, negating the need to use the clearfix method.

    This isn’t without it’s idiosyncracies though: occasionally you’ll get scrollbars popping up. In my experience, this happens where the floats do not have a fixed height, and is easily remedied.

  • http://ludwik.org Paweł Ludwiczak

    there’s little mistake in code:

    img {
    position: absolute;
    rightright: -100px;
    top: 20px; }

    3rd. line: double “right” :)

  • http://benbankson.com Ben

    excellent tips! Thank you so much!

  • http://www.djinteractive.co.uk/ Dan

    Whilst I wasn’t looking for this fix specifically it certainly helped provide some insight into a minor issue I was having. Cheers Jeff.

  • http://www.apoorvvaidya.com Apoorv Vaidya

    Thanks a lot Jeffrey, those are great! I always look forward to articles/screencasts by you.

  • http://omarabid.com Omar Abid

    For the first problem why all those headaches? Floating always need clearing, so the next div need to be clear.

    So we can simply add another div

    And our problem is solved! No?

    • http://omarabid.com Omar Abid

      This is missing.. delete it…

  • http://omarabid.com Omar Abid

    For the first problem why all those headaches? Floating always need clearing, so the next div need to be clear.

    So we can simply add another div

    And our problem is solved! No?

    “Hey, you have an error in code
    #main {
    background: green;
    height: 500px;
    width: 600px;
    float: rightright; }

    it should be

    #main {
    background: green;
    height: 500px;
    width: 600px;
    float: right; }

    or this won’t work

    Good tut :D

  • PAblo

    Instead of adding a div with clear:both why not adding this:

    is this too unsemantic for you?

  • afaquino

    Nice … learned a lot but pls. correct typ..
    loat: rightright; } might confuse noob like me …

  • http://webtemplateprofessional.com wtp

    nice article thanks
    so the clearfix method is more or less the same as just adding a clear both div at the end of the container div ?

  • http://www.mediacake.net dan

    Really good article..

    didn’t know u could do this :after selector; interesting !

    cheers

  • awake

    Mr Way…

    Ur a good teacher. Can anyone tell me why Opera is not one of the major browsers on the market when they constantly come up with crazy innovations (e.g. face gestures)

    http://www.youtube.com/watch?v=kkNxbyp6thM&feature=player_embedded

    • http://www.jeff-way.com Jeffrey Way
      Author

      Who knows. Not enough marketing….

    • http://omarabid.com Omar Abid

      I tried it lately and it’s going to be my first browser of choice: it’s fast and feature-filled

  • http://axcoto.info/vincent kureikain

    I think we can simply fix that by using clear:both?
    Correct me if i were wrong!

  • http://blog.itwarlocks.com/ Jeffrey Ridout

    As Nikki mentioned in his/her comment, using the clearfix is yesterday’s technique… overflow:auto is a much better solution in that it doesn’t require extra :after css (I’ve even seen them hardcoded into the HTML).

    I’ve blogged about this before:
    http://blog.itwarlocks.com/2009/05/08/float-overflow-can-be-useful-too/

    • http://www.jeff-way.com Jeffrey Way
      Author

      As I mentioned, overflow should be your first choice. However, it’s not always ideal. It’s important to be familiar with this fall-back method.

      • Nikki

        I was just trying to differentiate between overflow: auto and overflow: hidden.

  • floral

    really thank you man:)

  • wayno007

    Great article, Jeff

  • Dante

    Damn children make the parents work harder.

    Thanks JW, great explanation.

  • http://www.khwebdesign.net Kent

    Well, I guess I should go remove all of those fixes out of my code. Thanks for this elegant solution.

  • http://www.demogeek.com DemoGeek

    I would prefer a clear:both and a dummy content of a blank space at the container instead.

  • http://www.larishteriastudio.com rishteria

    good stuff but forget “id” for css, it’s better use “class”

    • Nouman Saleem

      how come?
      Id = one item on the page.
      class = for multiple.

      sometimes it just helps to see what’s using an ID and a Class while coding.

  • http://www.russelluresti.com Kangaroo_Deziner

    Excellent solution. I had to try this out since I was under the impression that both the “after” psuedo-class and the “content” CSS attribute would be completely ignored by IE6, but it worked.

    A clean and semantic way to clear floats across all browsers.

    I had been using the overflow:hidden method when I could, but it didn’t always play nice with IE6.

    Additionally, looking at the comments, there are 2 remarks I feel I must make, because people don’t seem to get it.

    1. He doesn’t put a clearing div in there because an empty clearing div isn’t semantic mark-up.

    2. He used the _height “hack” for simplicity sake. To make it not-hackish, simply put the “height: 1%” into a different external stylesheet and call it inside a conditional statement in your HTML for IE browsers that require hasLayout.

  • http://alistairrossini.com Alistair

    I am fairly versed in HTML and CSS. This is very useful, sometimes you miss the basics when going along.

    Thanks for the tutorial Jeffrey.

  • http://www.impressivewebs.com Louis

    I think this article would have been more fittingly titled “containing floated children” since that is specifically what it addresses.

    But great job on a simple tutorial, much better than some of the really complex stuff on this site, I think.

  • http://www.awmcreative.com Aaron

    It’s really best to have a separate clear fix than saying clearfix:after. “:after” isn’t supported in every browser. My HTML for a clear fix looks like this:

    and the CSS looks like:

    .clear { margin: 0; padding: 0; border: 0; clear: both; height: 0; }

    and that’s it.

  • http://www.awmcreative.com Aaron
  • http://www.umrah-haji.com Mister Ijoi

    for the first time i saw very good article for beginner who to understand how CSS work. Hope i can use this articel to add my knowledge of CSS..

    Keep it up..

  • http://criminalexistence.com/ceforums/ shedh

    keep it up, was going to ask for a new css tut

  • Matt

    Very nice… thanks!

  • Daniel Balfour

    Absolutely outstanding! What a TERRIFIC tutorial! Thank you so much! Tutorials such as theses make NetTuts a resource to be reckoned with! Please keep it up, so many are relying on your guys now

  • carlos

    Nice tuto!! A++++

    but I’ve a problem, I want to do the same thing, but two times. I need to show de circle in the other side, and in the top at the sime time.

    could you help me?

  • PaulG

    After taking removing “overflow: hidden;” from your container div, but without the clearfix trick in the css, I simply added a in my html like so:

    This actually seemed to work for me :)

    When I check it also seems to validate.

    Jeffrey, would adding that tag be considered unsemantic?

  • http://www.dezinebuzz.com/ dezinebuzz

    good css startup

  • http://www.xcellenceit.com Shruti

    excellent tips! Thank you so much!

  • Marcos

    Worked like a charm. I had tried using this technique before but never successfully. Now I got to understand how it works. Cheers, mate.

  • http://www.utahwebdesign.ws/ Sherwin

    Thanks for sharing these wonderful tips. I’ll try theme on my next projects, hope I’ll get them right just like what’s shown above.

  • http://www.quantums.com web hosting

    excellent tips! Thank you so much!!!!!!

  • http://www.module-developer.com drupal development company

    Great post., thank you very much..

  • http://www.lionlilly.com/ web development chennai

    Thanks to author for your well explanation its really good tutorial.Its most superb.keep share cheers!

  • http://arnotinteractive.com bb

    Still relevant 2 years later. Thanks!

  • http://www.dailyinfo.co.uk Miranda

    Spent a day struggling with the bad containing parent and finally found your fabulously simple solution here. Who knew. The sheer awfulness of a day struggling with misbehaving css is almost but not quite balanced by the spacey, stunned exhilaration of having fixed it. Thanks so much!