How to Float an Element Left with Full Height of the Wrapper

How to float an element left with full height of the wrapper?

The display: table solution

Within tables each cell of a row has the same height.

.wrapper {
display: table;
width: 100%;
}
.left, .right {
display: table-cell;
}

This is the best solution in my opinion, but is not compatible before IE8.

Here is the Fiddle for this solution.

Using absolute positioning

Absolute positioned elements respect their relative parents height:

.wrapper {
position: relative;
padding-left: 85px;
}
.left {
position: absolute;
left: 0;
top: 0;
}

Normally I would not recommend absolute positioning in most situations. But as you have a fixed width anyway, maybe it does not matter. But be aware of the fact that this will ignore long contents in .left. The height is just controlled by .right.

Here is an update to your Fiddle.

The flexible solution

This is so new I would not recommend using it right now, but just to be complete. You could use CSS3 flex, but be aware of browser compatibility:

.wrapper {
display: flex;
}

The Fiddle (tested in current Chrome and Firefox).

The grid layout

Even newer than flexbox, CSS grid seams to be the perfect answer for layout questions.

.wrapper {
display: grid;
grid-template-areas: 'left right';
}

.left {
grid-area: left;
}

.right {
grid-area: right;
}

Browser compatibility is rare, if you go back a view versions. Besides, it would be overkill for the OP's scenario in my opinion, but for more complex layout troubles in the future, this is a very powerful thing.

See it in the Fiddle.

How to make a floated div 100% height of its parent?

For #outer height to be based on its content, and have #inner base its height on that, make both elements absolutely positioned.

More details can be found in the spec for the css height property, but essentially, #inner must ignore #outer height if #outer's height is auto, unless #outer is positioned absolutely. Then #inner height will be 0, unless #inner itself is positioned absolutely.

<style>
#outer {
position:absolute;
height:auto; width:200px;
border: 1px solid red;
}
#inner {
position:absolute;
height:100%;
width:20px;
border: 1px solid black;
}
</style>

<div id='outer'>
<div id='inner'>
</div>
text
</div>

However... By positioning #inner absolutely, a float setting will be ignored, so you will need to choose a width for #inner explicitly, and add padding in #outer to fake the text wrapping I suspect you want. For example, below, the padding of #outer is the width of #inner +3. Conveniently (as the whole point was to get #inner height to 100%) there's no need to wrap text beneath #inner, so this will look just like #inner is floated.

<style>
#outer2{
padding-left: 23px;
position:absolute;
height:auto;
width:200px;
border: 1px solid red;
}
#inner2{
left:0;
position:absolute;
height:100%;
width:20px;
border: 1px solid black;
}
</style>

<div id='outer2'>
<div id='inner2'>
</div>
text
</div>

I deleted my previous answer, as it was based on too many wrong assumptions about your goal.

How to fit a div's height to wrap around its floated children

This is a common issue when working with floats. There are several common solutions, which I have ordered by personal preference (best approach first):

  1. Use the ::after CSS pseudo element. This is know as the 'clearfix', and works IE8 and up. If you need compatibility with earlier versions of IE, this answer should help. Example.

    .parentelement::after {
    content: "";
    display: table;
    clear: both;
    }
  2. Add the two floats into a container with the CSS attribute overflow: auto or overflow: hidden. However, this approach can cause issues (e.g. when a tooltip overlaps the edges of the parent element a scrollbar will appear). Example.

    <div style="overflow: auto">
    <div style="float: left"></div>
    <div style="float: left"></div>
    </div>
  3. Add a set height to the parent element. Example.

    <div style="height: 200px">
    <div style="float: left"></div>
    <div style="float: left"></div>
    </div>
  4. Make the parent element a float. Example.

    <div style="float: left">
    <div style="float: left"></div>
    <div style="float: left"></div>
    </div>
  5. Add a div after the floats with clear: both. Example.

    <div style="float: left"></div>
    <div style="float: left"></div>
    <div style="clear: both"></div>

Wrapper div height is 0 with floated elements inside

Set overflow: hidden on the parent.

<div class="outside" style="border:1px solid #555;overflow:hidden;">
<div class="inside" style="float:left; width:40px;">CONTENT</div>
<div class="inside2" style="float:left; width:40px;">CONTENT</div>
</div>

Set floating div to height: 100%?

You could do it by setting up a table-like scructure of <div>s in your HTML and then using display: table, display: table-cell, etc. This will work because table cells in the same row automatically resize to the same height as the tallest cell. However, IE7 and below do not support display: table.

jsFiddle

<div id="wrapper">
<div id="inner-wrapper">
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
</div>
#wrapper       { display: table; }
#inner-wrapper { display: table-row; }
#left { display: table-cell; }
#right { display: table-cell; }

I had to remove float: left and float: right from #left and #right to get the table-cell display to work, since table cells can’t float. However, this has stuck the two divs together. And table cells do not accept margins, only padding. You may need an extra display: table-cell div between left and right to separate them, if you don’t want padding separating them.

Read more about display: table and family on QuirksMode and on MDN.

Cannot fix height 100% of parent using floated elements inside

Here is one way of doing it.

I made a slight modification to your HTML by adding a .main-wrap to wrap the floats.

<div id="page-wrapper">
<div id="header">0</div>
<div id="main-wrap">
<div id="left_sidebar">1</div><!--end left_sidebar -->
<div id="main_contents">2</div>
<div id="right_sidebar">3</div><!--end right_sidebar -->
</div><!-- end main-wrap -->
<div id="footer-wrapper">4</div><!-- end footer -->
</div><!--close page-wrapper-->

and here is the CSS:

html, body {
height: 100%;
}
body {
margin: 0;
}
#page-wrapper {
height: 100%;
min-height: 300px; /* optional */
width: 800px;
margin: 0 auto;
position: relative;
}
#header {
position: relative;
top: 5px;
height: 100px;
background-color: pink;
}
#main-wrap {
position: absolute;
left: 0;
right: 0;
top: 105px;
bottom: 100px;
background-color: yellow;
}

#left_sidebar {
float: left;
width: 20%;
height: 100%;
background-color: green;
}

#main_contents {
float: left;
width: 55%;
height: 100%;
margin-left: 20px;
margin-right: 20px;
background-color: red;
}

#right_sidebar {
float: left;
width: 20%;
height: 100%;
background-color: lightblue;
}

#footer-wrapper {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100px;
background-color: #d8d8d6;
}

See demo fiddle at: http://jsfiddle.net/audetwebdesign/xMNUv/

The trick is to extend the #page-wrapper to the full height of the view port. Set the top and bottom margin to zero to prevent vertical scrolling.

The #header and #footer-wrapper are both 100px in height, so you can now use absolute positioning to stretch the main-wrap to fill up the space between the header and footer elements.

You can use position: relative on the header to open up some white space on top if you need it.

Within the #main-wrap, you can now float your sidebars and content elements to form a 3-column layout. Apply height: 100% to get the floated elements to fill up the #main-wrap height.

You may want to add a minimum height value to #page-wrapper to prevent the columns from collapsing.

Depending on your content, your floated columns may overflow since their height is constrained by the height of the view port. You may want to add overflow: auto to the floated elements as needed.

Why doesn't the height of a container element increase if it contains floated elements?

The floated elements do not add to the height of the container element, and hence if you don't clear them, container height won't increase...

I'll show you visually:

Sample Image

Sample Image

Sample Image

More Explanation:

<div>
<div style="float: left;"></div>
<div style="width: 15px;"></div> <!-- This will shift
besides the top div. Why? Because of the top div
is floated left, making the
rest of the space blank -->

<div style="clear: both;"></div>
<!-- Now in order to prevent the next div from floating beside the top ones,
we use `clear: both;`. This is like a wall, so now none of the div's
will be floated after this point. The container height will now also include the
height of these floated divs -->
<div></div>
</div>

You can also add overflow: hidden; on container elements, but I would suggest you use clear: both; instead.

Also if you might like to self-clear an element you can use

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

How Does CSS Float Work?

What is float exactly and what does it do?

  • The float property is misunderstood by most beginners. Well, what exactly does float do? Initially, the float property was introduced to flow text around images, which are floated left or right. Here's another explanation by @Madara Uchicha.

    So, is it wrong to use the float property for placing boxes side by side? The answer is no; there is no problem if you use the float property in order to set boxes side by side.

  • Floating an inline or block level element will make the element behave like an inline-block element.

    Demo

  • If you float an element left or right, the width of the element will be limited to the content it holds, unless width is defined explicitly ...

  • You cannot float an element center. This is the biggest issue I've always seen with beginners, using float: center;, which is not a valid value for the float property. float is generally used to float/move content to the very left or to the very right. There are only four valid values for float property i.e left, right, none (default) and inherit.

  • Parent element collapses, when it contains floated child elements, in order to prevent this, we use clear: both; property, to clear the floated elements on both the sides, which will prevent the collapsing of the parent element. For more information, you can refer my another answer here.

  • (Important) Think of it where we have a stack of various elements. When we use float: left; or float: right; the element moves above the stack by one. Hence the elements in the normal document flow will hide behind the floated elements because it is on stack level above the normal floated elements. (Please don't relate this to z-index as that is completely different.)


Taking a case as an example to explain how CSS floats work, assuming we need a simple 2 column layout with a header, footer, and 2 columns, so here is what the blueprint looks like...

Sample Image

In the above example, we will be floating only the red boxes, either you can float both to the left, or you can float on to left, and another to right as well, depends on the layout, if it's 3 columns, you may float 2 columns to left where another one to the right so depends, though in this example, we have a simplified 2 column layout so will float one to left and the other to the right.

Markup and styles for creating the layout explained further down...

<div class="main_wrap">
<header>Header</header>
<div class="wrapper clear">
<div class="floated_left">
This<br />
is<br />
just<br />
a<br />
left<br />
floated<br />
column<br />
</div>
<div class="floated_right">
This<br />
is<br />
just<br />
a<br />
right<br />
floated<br />
column<br />
</div>
</div>
<footer>Footer</footer>
</div>

* {
-moz-box-sizing: border-box; /* Just for demo purpose */
-webkkit-box-sizing: border-box; /* Just for demo purpose */
box-sizing: border-box; /* Just for demo purpose */
margin: 0;
padding: 0;
}

.main_wrap {
margin: 20px;
border: 3px solid black;
width: 520px;
}

header, footer {
height: 50px;
border: 3px solid silver;
text-align: center;
line-height: 50px;
}

.wrapper {
border: 3px solid green;
}

.floated_left {
float: left;
width: 200px;
border: 3px solid red;
}

.floated_right {
float: right;
width: 300px;
border: 3px solid red;
}

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

Let's go step by step with the layout and see how float works..

First of all, we use the main wrapper element, you can just assume that it's your viewport, then we use header and assign a height of 50px so nothing fancy there. It's just a normal non floated block level element which will take up 100% horizontal space unless it's floated or we assign inline-block to it.

The first valid value for float is left so in our example, we use float: left; for .floated_left, so we intend to float a block to the left of our container element.

Column floated to the left

And yes, if you see, the parent element, which is .wrapper is collapsed, the one you see with a green border didn't expand, but it should right? Will come back to that in a while, for now, we have got a column floated to left.

Coming to the second column, lets it float this one to the right

Another column floated to the right

Here, we have a 300px wide column which we float to the right, which will sit beside the first column as it's floated to the left, and since it's floated to the left, it created empty gutter to the right, and since there was ample of space on the right, our right floated element sat perfectly beside the left one.

Still, the parent element is collapsed, well, let's fix that now. There are many ways to prevent the parent element from getting collapsed.

  • Add an empty block level element and use clear: both; before the parent element ends, which holds floated elements, now this one is a cheap solution to clear your floating elements which will do the job for you but, I would recommend not to use this.

Add, <div style="clear: both;"></div> before the .wrapper div ends, like

<div class="wrapper clear">
<!-- Floated columns -->
<div style="clear: both;"></div>
</div>

Demo

Well, that fixes very well, no collapsed parent anymore, but it adds unnecessary markup to the DOM, so some suggest, to use overflow: hidden; on the parent element holding floated child elements which work as intended.

Use overflow: hidden; on .wrapper

.wrapper {
border: 3px solid green;
overflow: hidden;
}

Demo

That saves us an element every time we need to clear float but as I tested various cases with this, it failed in one particular one, which uses box-shadow on the child elements.

Demo (Can't see the shadow on all 4 sides, overflow: hidden; causes this issue)

So what now? Save an element, no overflow: hidden; so go for a clear fix hack, use the below snippet in your CSS, and just as you use overflow: hidden; for the parent element, call the class below on the parent element to self-clear.

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

<div class="wrapper clear">
<!-- Floated Elements -->
</div>

Demo

Here, shadow works as intended, also, it self-clears the parent element which prevents to collapse.

And lastly, we use footer after we clear the floated elements.

Demo


When is float: none; used anyways, as it is the default, so any use to declare float: none;?

Well, it depends, if you are going for a responsive design, you will use this value a lot of times, when you want your floated elements to render one below another at a certain resolution. For that float: none; property plays an important role there.


Few real-world examples of how float is useful.

  • The first example we already saw is to create one or more than one column layouts.
  • Using img floated inside p which will enable our content to flow around.

Demo (Without floating img)

Demo 2 (img floated to the left)

  • Using float for creating horizontal menu - Demo

Float second element as well, or use `margin`

Last but not the least, I want to explain this particular case where you float only single element to the left but you do not float the other, so what happens?

Suppose if we remove float: right; from our .floated_right class, the div will be rendered from extreme left as it isn't floated.

Demo

So in this case, either you can float the to the left as well

OR

You can use margin-left which will be equal to the size of the left floated column i.e 200px wide.



Related Topics



Leave a reply



Submit