floating elements behavior

I'm facing problem with floating elements inside div only , here is the problem:

.main{	
    border-style:solid;
    border-color:yellow;
    overflow:auto;	
}

.first {
    width:200px;
    height:100px;
    float: left;
    border: 10px solid green;
}
.second {
width:200px;
    height: 50px;
    border: 10px solid blue;
}
<div class="main">
<div class="first">test1</div>
<div class="second" >test2</div>
</div>

I need an explanation about the border of second DIV and its content position. Why the border is behind but the content is under the first div?


Also according to : https://css-tricks.com/all-about-floats/#article-header-id-3

One of the more bewildering things about working with floats is how they can affect the element that contains them (their "parent" element). If this parent element contained nothing but floated elements, the height of it would literally collapse to nothing. This isn't always obvious if the parent doesn't contain any visually noticeable background, but it is important to be aware of.

I need clarification why this happening.

EDIT: I'm asking for explanation for it's behavior for both questions , NOT how to solve it .


Solution 1:

This is the logical behavior of how the elements should be painted but you are having an overflow issue combined with how float works that is making things strange.

Let's remove some properties and follow the code step by step. Let's start by removing overflow:auto from main and the fixed height from .second

.main {
  border-style: solid;
  border-color: yellow;
 /* overflow: auto;*/
}

.first {
  width: 200px;
  height: 100px;
  float: left;
  border: 10px solid green;
}

.second {
  width: 200px;
  /*height: 50px;*/
  border: 10px solid blue;
}
<div class="main">
  <div class="first">test1</div>
  <div class="second">test2</div>
</div>

As you can see, the floating element green is above the the blue div and floating only around its content which is text. Like you can read here:

The float CSS property specifies that an element should be placed along the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the web page, though still remaining a part of the flow (in contrast to absolute positioning).

And since both div have the same width the text will be at the bottom and not the right. You can change the width of the blue div to see the difference:

.main {
  border-style: solid;
  border-color: yellow;
 /* overflow: auto;*/
}

.first {
  width: 200px;
  height: 100px;
  float: left;
  border: 10px solid green;
}

.second {
  width: 200px;
  /*height: 50px;*/
  border: 10px solid blue;
  animation:change 1s infinite alternate linear;
}

@keyframes change{
 from{width:200px}
 to{width:400px}
}
<div class="main">
  <div class="first">test1</div>
  <div class="second">test2</div>
</div>

Now if you check the painting order you will see that we first print the border/background of block non-floating element in the step (4) then we print the floating element in the step (5) then we print the content of the non-floating element in the step (7) which explain why you see the blue under the green


Now if we add a fixed height to the blue element you will face an overflow issue so the content of the blue will stay outside (like in the previous code) BUT the border that define the limit of the element will be behind the green element (like described in the paiting order)

Here is a code with animation to better understand what is happening:

.main {
  border-style: solid;
  border-color: yellow;
 /* overflow: auto;*/
}

.first {
  width: 200px;
  height: 100px;
  float: left;
  border: 10px solid green;
}

.second {
  width: 200px;
  border: 10px solid blue;
  animation:change 2s infinite alternate linear;
}

@keyframes change {
  from{height:300px;}
  to{height:50px;}
}
<div class="main">
  <div class="first">test1</div>
  <div class="second">test2</div>
</div>

You can also clearly see that the height of main yellow element is following the height of the blue one because it's the only in-flow element which explain your second question about float not being considered in the height of their parent element BUT by adding overflow:auto you will create a block formatting context thus the element will behave differently and will consider the height of floating elements inside:

.main {
  border-style: solid;
  border-color: yellow;
  overflow: auto;
}

.first {
  width: 200px;
  height: 100px;
  float: left;
  border: 10px solid green;
}

.second {
  width: 200px;
  border: 10px solid blue;
  animation:change 2s infinite alternate linear;
}

@keyframes change {
  from{height:300px;}
  to{height:50px;}
}
<div class="main">
  <div class="first">test1</div>
  <div class="second">test2</div>
</div>

In this last you can clearly see the overflow issue that is making the text to be outside the blue div because oveflow:auto is adding a scroll bar.