How to make child divs always fit inside parent div?

Viewed 259422

My question is if there is a way, without using JavaScript, to cause child divs to extend to the borders of their parent, without exceeding those borders, when you cannot know beforehand the size of the parent div?

Below is sample markup/styles demonstrating my issue. If you load it into a browser you will see that #two and #three both extend outside their parent, #one, and cause scrollbars to appear.

My issue is not so much the scrollbars, but that I do not know how to tell the child divs to occupy the width or height remaining to them, rather than the full height or width of the parent.

<html>
    <head>
        <style>
            html, body {width:100%;height:100%;margin:0;padding:0;}
            .border {border:1px solid black;}
            .margin { margin:5px;}
            #one {width:100%;height:100%;}
            #two {width:100%;height:50px;}
            #three {width:100px;height:100%;}
        </style>
    </head>
    <body>
        <div id="one" class="border">
            <div id="two" class="border margin"></div>
            <div id="three" class="border margin"></div>
        </div>
    </body>
</html>
11 Answers

In your example, you can't: the 5px margin is added to the bounding box of div#two and div#three effectively making their width and height 100% of parent + 5px, which will overflow.

You can use padding on the parent Element to ensure there's 5px of space inside its border:

<style>
    html, body {width:100%;height:100%;margin:0;padding:0;}
    .border {border:1px solid black;}
    #one {padding:5px;width:500px;height:300px;}
    #two {width:100%;height:50px;}
    #three {width:100px;height:100%;}
</style>

EDIT: In testing, removing the width:100% from div#two will actually let it work properly as divs are block-level and will always fill their parents' widths by default. That should clear your first case if you'd like to use margin.

For width it's easy, simply remove the width: 100% rule. By default, the div will stretch to fit the parent container.

Height is not quite so simple. You could do something like the equal height column trick.

html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:500px;height:300px; overflow: hidden;}
#two {height:50px;}
#three {width:100px; padding-bottom: 30000px; margin-bottom: -30000px;}

you could use inherit

#one {width:500px;height:300px;}
#two {width:inherit;height:inherit;}
#three {width:inherit;height:inherit;}

I think I have the solution to your question, assuming you can use flexbox in your project. What you want to do is make #one a flexbox using display: flex and use flex-direction: column to make it a column alignment.

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.border {
  border: 1px solid black;
}

.margin {
  margin: 5px;
}

#one {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

#two {
  height: 50px;
}

#three {
  width: 100px;
  height: 100%;
}
<html>

<head>
</head>

<body>
  <div id="one" class="border">
    <div id="two" class="border margin"></div>
    <div id="three" class="border margin"></div>
  </div>
</body>

</html>

If I've understood you correctly, the easiest method is to float the children. For example:

#one { width: 500px; height: 1%; overflow: hidden; background: red; }
#two { float: left; width: 250px; height: 400px; background: aqua; }
#two { float: left; width: 250px; height: 200px; background: lime; }

Setting a dimension (height/width) and overflow to auto or hidden on the parent element causes it to contain any floated child elements.

Note that overflow:hidden; can occasionally cause problems with content getting cut off, in which case you might want to try this alternative method:

http://www.positioniseverything.net/easyclearing.html

For closure, I think the answer to this question is that there is no solution. The only way to get the behavior I want is with javascript.

If you want the child divs to fit the parent size, you should put a margin at least of the size of the child borders on the child divs (child.margin >= child.bordersize).

For this example, just remove the width:100%; and the height:100% in #one and remove the width:100% in #two. It should be something like this:

html, body {width:100%; height:100%; margin:0; padding:0;}    
.border {border:1px solid black;}   
.margin {margin:5px;}  
\#one {}   
\#two {height:50px;}    
\#three {width:100px; height:100%;}
Related