[css] Floating elements within a div, floats outside of div. Why?

Say you have a div, give it a definite width and put elements in it, in my case an img and another div.

The idea is that the content of the container div will cause the container div to stretch out, and be a background for the content. But when I do this, the containing div shrinks to fit the non-floating objects, and the floating objects will be either all the way out, or half out, half in, and not have any bearing on the size of the big div.

Why is this? Is there something I'm missing, and how can I get floated items to stretch out the height of a containing div?

This question is related to css html css-float

The answer is


As Lucas says, what you are describing is the intended behaviour for the float property. What confuses many people is that float has been pushed well beyond its original intended usage in order to make up for shortcomings in the CSS layout model.

Have a look at Floatutorial if you'd like to get a better understanding of how this property works.


There's nothing missing. Float was designed for the case where you want an image (for example) to sit beside several paragraphs of text, so the text flows around the image. That wouldn't happen if the text "stretched" the container. Your first paragraph would end, and then your next paragraph would begin under the image (possibly several hundred pixels below).

And that's why you're getting the result you are.


Put your floating div(s) in a div and in CSS give it overflow:hidden;
it will work fine.


You can easily do with first you can make the div flex and apply justify content right or left and your problem is solved.

_x000D_
_x000D_
<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">_x000D_
     <button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>_x000D_
    </div>
_x000D_
_x000D_
_x000D_


Reason

The problem is that floating elements are out-of-flow:

An element is called out of flow if it is floated, absolutely positioned, or is the root element.

Therefore, they don't impact surrounding elements as an in-flow element would.

This is explained in 9.5 Floats:

Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.

enter image description here

_x000D_
_x000D_
html {_x000D_
  width: 550px;_x000D_
  border: 1px solid;_x000D_
}_x000D_
body {_x000D_
  font-family: sans-serif;_x000D_
  color: rgba(0,0,0,.15);_x000D_
}_x000D_
body:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  clear: both;_x000D_
}_x000D_
div {_x000D_
  position: relative;_x000D_
}_x000D_
div:after {_x000D_
  font-size: 200%;_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  top: 0;_x000D_
  text-align: center;_x000D_
}_x000D_
.block-sibling {_x000D_
  border: 3px solid green;_x000D_
}_x000D_
.block-sibling:after {_x000D_
  content: 'Block sibling';_x000D_
  color: green;_x000D_
}_x000D_
.float {_x000D_
  float: left;_x000D_
  border: 3px solid red;_x000D_
  height: 90px;_x000D_
  width: 150px;_x000D_
  z-index: 1;_x000D_
}_x000D_
.float:after {_x000D_
  content: 'Float';_x000D_
  color: red;_x000D_
}
_x000D_
<div class="float"></div>_x000D_
<div class="block-sibling">_x000D_
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor._x000D_
</div>
_x000D_
_x000D_
_x000D_

This is also specified in 10.6 Calculating heights and margins. For "normal" blocks,

Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored […])

enter image description here

_x000D_
_x000D_
html {_x000D_
  width: 550px;_x000D_
  border: 1px solid;_x000D_
}_x000D_
body {_x000D_
  font-family: sans-serif;_x000D_
  color: rgba(0,0,0,.15);_x000D_
}_x000D_
body:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  clear: both;_x000D_
}_x000D_
div {_x000D_
  position: relative;_x000D_
}_x000D_
div:after {_x000D_
  font-size: 200%;_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  top: 0;_x000D_
  text-align: center;_x000D_
}_x000D_
.block-parent {_x000D_
  border: 3px solid blue;_x000D_
}_x000D_
.block-parent:after {_x000D_
  content: 'Block parent';_x000D_
  color: blue;_x000D_
}_x000D_
.float {_x000D_
  float: left;_x000D_
  border: 3px solid red;_x000D_
  height: 130px;_x000D_
  width: 150px;_x000D_
}_x000D_
.float:after {_x000D_
  content: 'Float';_x000D_
  color: red;_x000D_
}
_x000D_
<div class="block-parent">_x000D_
  <div class="float"></div>_x000D_
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit._x000D_
</div>
_x000D_
_x000D_
_x000D_

Hacky solution: clearance

A way to solve the problem is forcing some in-flow element to be placed below all floats. Then, the height of the parent will grow to wrap that element (and thus the floats too).

This can be achieved using the clear property:

This property indicates which sides of an element's box(es) may not be adjacent to an earlier floating box.

enter image description here

_x000D_
_x000D_
html {_x000D_
  width: 550px;_x000D_
  border: 1px solid;_x000D_
}_x000D_
body {_x000D_
  font-family: sans-serif;_x000D_
  color: rgba(0,0,0,.15);_x000D_
}_x000D_
body:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  clear: both;_x000D_
}_x000D_
div {_x000D_
  position: relative;_x000D_
}_x000D_
div:after {_x000D_
  font-size: 200%;_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  top: 0;_x000D_
  text-align: center;_x000D_
}_x000D_
.block-parent {_x000D_
  border: 3px solid blue;_x000D_
}_x000D_
.block-parent:after {_x000D_
  content: 'Block parent';_x000D_
  color: blue;_x000D_
}_x000D_
.float {_x000D_
  float: left;_x000D_
  border: 3px solid red;_x000D_
  height: 84px;_x000D_
  width: 150px;_x000D_
}_x000D_
.float:after {_x000D_
  content: 'Float';_x000D_
  color: red;_x000D_
}_x000D_
.clear {_x000D_
  clear: both;_x000D_
  text-align: center;_x000D_
  height: 37px;_x000D_
  border: 3px dashed pink;_x000D_
}_x000D_
.clear:after {_x000D_
  position: static;_x000D_
  content: 'Block sibling with clearance';_x000D_
  color: pink;_x000D_
}
_x000D_
<div class="block-parent">_x000D_
  <div class="float"></div>_x000D_
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra._x000D_
  <div class="clear"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

So a solution is adding an empty element with clear: both as the last sibling of the floats

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

However, that is not semantic. So better generate a pseudo-element at the end of the parent:

.clearfix::after {
  clear: both;
  display: block;
}

There are multiple variants of this approach, e.g. using the deprecated single colon syntax :after to support old browsers, or using other block-level displays like display: table.

Solution: BFC roots

There is an exception to the problematic behavior defined at the beginning: if a block element establishes a Block Formatting Context (is a BFC root), then it will also wrap its floating contents.

According to 10.6.7 'Auto' heights for block formatting context roots,

If the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges.

enter image description here

_x000D_
_x000D_
html {_x000D_
  width: 550px;_x000D_
  border: 1px solid;_x000D_
}_x000D_
body {_x000D_
  font-family: sans-serif;_x000D_
  color: rgba(0,0,0,.15);_x000D_
}_x000D_
body:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  clear: both;_x000D_
}_x000D_
div {_x000D_
  position: relative;_x000D_
}_x000D_
div:after {_x000D_
  font-size: 200%;_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  top: 0;_x000D_
  text-align: center;_x000D_
}_x000D_
.block-parent {_x000D_
  border: 3px solid blue;_x000D_
}_x000D_
.block-parent.bfc-root:after {_x000D_
  content: 'BFC parent';_x000D_
  color: blue;_x000D_
}_x000D_
.float {_x000D_
  float: left;_x000D_
  border: 3px solid red;_x000D_
  height: 127px;_x000D_
  width: 150px;_x000D_
}_x000D_
.float:after {_x000D_
  content: 'Float';_x000D_
  color: red;_x000D_
}_x000D_
.bfc-root {_x000D_
  overflow: hidden;_x000D_
}
_x000D_
<div class="block-parent bfc-root">_x000D_
  <div class="float"></div>_x000D_
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit._x000D_
</div>
_x000D_
_x000D_
_x000D_

Additionally, as explained 9.5 Floats, BFC roots are also useful because of the following:

The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context […] must not overlap the margin box of any floats in the same block formatting context as the element itself.

enter image description here

_x000D_
_x000D_
html {_x000D_
  width: 550px;_x000D_
  border: 1px solid;_x000D_
}_x000D_
body {_x000D_
  font-family: sans-serif;_x000D_
  color: rgba(0,0,0,.15);_x000D_
}_x000D_
body:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  clear: both;_x000D_
}_x000D_
div {_x000D_
  position: relative;_x000D_
}_x000D_
div:after {_x000D_
  font-size: 200%;_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  top: 0;_x000D_
  text-align: center;_x000D_
}_x000D_
.block-sibling {_x000D_
  border: 3px solid green;_x000D_
}_x000D_
.block-sibling.bfc-root:after {_x000D_
  content: 'BFC sibling';_x000D_
  color: green;_x000D_
}_x000D_
.float {_x000D_
  float: left;_x000D_
  border: 3px solid red;_x000D_
  height: 90px;_x000D_
  width: 150px;_x000D_
  z-index: 1;_x000D_
}_x000D_
.float:after {_x000D_
  content: 'Float';_x000D_
  color: red;_x000D_
}_x000D_
.bfc-root {_x000D_
  overflow: hidden;_x000D_
}
_x000D_
<div class="float"></div>_x000D_
<div class="block-sibling bfc-root">_x000D_
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur._x000D_
</div>
_x000D_
_x000D_
_x000D_

A block formatting context is established by

  • Block boxes with overflow other than visible, e.g. hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    
  • Block containers that are not block boxes: when display is set to inline-block, table-cell or table-caption.

    .bfc-root {
      display: inline-block;
    }
    
  • Floating elements: when float is set to left or right.

    .bfc-root {
      float: left;
    }
    
  • Absolutely positioned elements: when position is set to absolute or fixed.

    .bfc-root {
      position: absolute;
    }
    

Note those may have undesired collateral effects, like clipping overflowing content, calculating auto widths with the shrink-to-fit algorithm, or becoming out-of-flow. So the problem is that it's not possible to have an in-flow block-level element with visible overflow that establishes a BFC.

Display L3 addresses these issues:

Created the flow and flow-root inner display types to better express flow layout display types and to create an explicit switch for making an element a BFC root. (This should eliminate the need for hacks like ::after { clear: both; } and overflow: hidden […])

Sadly, there is no browser support yet. Eventually we may be able to use

.bfc-root {
  display: flow-root;
}

W3Schools recommendation:

put overflow: auto on parent element and it will "color" whole background including elements margins. Also floating elements will stay inside of border.

http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix


Here's more modern approach:

.parent {display: flow-root;} 

No more clearfixes.

p.s. Using overflow: hidden; hides the box-shadow so...


In some cases, i.e. when (if) you're just using float to have elements flow on the same "line", you might use

display: inline-block;

instead of

float: left;

Otherwise, using a clear element at the end works, even if it may go against the grain to need an element to do what should be CSS work.


Thank you LSerni you solved it for me.

To achieve this :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

You have to do this :

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css-float

Bootstrap - floating navbar button right Bootstrap change div order with pull-right, pull-left on 3 columns Bootstrap 3 Multi-column within a single ul not floating properly CSS float right not working correctly Floating Div Over An Image CSS force new line Why doesn't the height of a container element increase if it contains floated elements? Advantages of using display:inline-block vs float:left in CSS Floating divs in Bootstrap layout What does the CSS rule "clear: both" do?