floating elements behavior
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>
Basic CSS floating elements behavior
Both of your questions can be answered by referring to section 9 of the CSS2.1 spec.
Why are those two floating elements (div.regular and p) aligned to the left edge of the floated div.base element? I would expect they will be aligned to the right edge so they will be next to the base div element.
From section 9.5:
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.
The line boxes refer to the boxes that actually contain the text. In your example, the p element contains one or more line boxes with the words "Some text". Those line boxes are made to reflow around the float. The block box that is generated by the p itself (which in turn contains those line boxes) is laid out as described in the first sentence, simply because block boxes obey different layout rules from line boxes.
Why is the div.base element above all other elements? I would expect it at the bottom since it is before them in the HTML flow.
From section 9.9, emphasis mine:
Within each stacking context, the following layers are painted in back-to-front order:
- the background and borders of the element forming the stacking context.
- the child stacking contexts with negative stack levels (most negative first).
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats.
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
- the child stacking contexts with positive stack levels (least positive first).
Item #3 refers to div.regular and p, since they are in the normal flow, they are block-level, and they are non-positioned. #4 refers to div.base, which is floating.
Elements are painted in source order when
- you have multiple elements belonging to the same category, for example when you have two floating elements, or
- otherwise not mentioned in this list.
Weird behaviors of css floating element
The spec says:
2. If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.
And:
8. A floating box must be placed as high as possible.
Since all of your elements are floating to the left, the 4th element cannot float to the left of the 2nd element because the 2nd element comes before it in the source. The highest it can go while still remaining within the constraints of your container and its preceding floats is underneath the 3rd element because it's shorter than the 2nd element in terms of height. Therefore the 4th element floats underneath the 3rd element.
Unexpected behavior of Floating elements with uneven height
You could create two separate classes, one which will float your element to the left, and another which will float your element to the right:
<html>
<head> <style> span { width: 50%; text-align: center; } .float-left { float: left; clear: left; } .float-right { float: right; } </style> <meta name="viewport" content="width=device-width"></head>
<body> <div> <span class="float-left">I am long text so i may take long space vbjkhkj hkjhjkhjkh jkghkjgk gjhfgjhykf yjf kfgkuyrfkyfkrf ytgk tygy kry kr ykut kutuktuy ruykt kutkuyykut yufkytrky utkt r tykutg kyuyuktykytr ktykuyt,ytktytg kyutukyrtyryrrryryu ryuryuryryu ryuryurtyukrerrukrkr r67rtr87</span> <span class="float-right">Hello2</span> <span class="float-left">Hello3</span> <span class="float-right">Hello4</span> <span class="float-left">Hello5</span> </div></body></html>
Make two elements behave like floating elements without using css property float
I'm not aware of a way to make the left and right swap sides based on only a property of a child element like a real float does, without specifying flex-direction:row-reverse;
on the wrapper. See my example for a comparison: http://codepen.io/ijstanley/pen/JWXwOy
<p>pseudo floats in reverse order in markup</p>
<div class="flex wrapper">
<div class="pseudo float right">right</div>
<div class="pseudo float left">left</div>
</div>
<p>pseudo floats in correct order in markup</p>
<div class="flex wrapper">
<div class="pseudo float left">left</div>
<div class="pseudo float right">right</div>
</div>
<p>pseudo floats in reverse order in markup, reverse flex direction</p>
<div class="reverse flex wrapper">
<div class="pseudo float right">right</div>
<div class="pseudo float left">left</div>
</div>
<p>pseudo floats in correct order in markup, reverse flex direction</p>
<div class="reverse flex wrapper">
<div class="pseudo float left">left</div>
<div class="pseudo float right">right</div>
</div>
<p>actual floats</p>
<div class="floater wrapper">
<div class="real float left">left</div>
<div class="real float right">right</div>
</div>
.wrapper {
border:3px solid gray;
}
.wrapper.flex {
display:flex;
flex-direction:row;
flex-wrap:wrap;
justify-content:space-between;
}
.wrapper.flex.reverse {
flex-direction:row-reverse;
}
.wrapper.floater {
width:100%;
}
.wrapper.floater::after {
content:'';
display:block;
clear:both;
}
.float {
min-height:200px;
background:red;
border:3px solid black;
width:300px;
}
.float.pseudo.left {
margin-right:auto;
}
.float.real.left {
float:left;
}
.float.real.right {
float:right;
}
Why do inline elements behave like block level elements when floated?
This behavior is defined in the point 3 of this CSS2.1 section:
9.7 Relationships between
display
,position
, andfloat
The three properties that affect box generation and layout —
display
,position
, andfloat
— interact as follows:
- If
display
has the valuenone
, thenposition
andfloat
do not apply. In this case, the element generates no box.- Otherwise, if
position
has the valueabsolute
orfixed
, the box is absolutely positioned, the computed value offloat
isnone
, and display is set according to the table below. The position of the box will be determined by thetop
,right
,bottom
andleft
properties and the box's containing block.- Otherwise, if
float
has a value other thannone
, the box is floated anddisplay
is set according to the table below.- Otherwise, if the element is the root element,
display
is set according to the table below, except that it is undefined in CSS 2.1 whether a specified value oflist-item
becomes a computed value ofblock
orlist-item
.- Otherwise, the remaining
display
property values apply as specified.┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
┃ #Specified value# ┃ #Computed value# ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
│ inline-table │ table │
├──────────────────────────────────────────────────────────┼──────────────────┤
│ inline, table-row-group, table-column, table-column-group│ block │
│ table-header-group, table-footer-group, table-row │ │
│ table-cell, table-caption, inline-block │ │
├──────────────────────────────────────────────────────────┼──────────────────┤
│ others │ same as specified│
└──────────────────────────────────────────────────────────┴──────────────────┘
In Display Level 3, this process is called blockification:
2.7. Automatic Box Type Transformations
Some layout effects require blockification or inlinification of the box type, which sets the box’s outer display type, if it is not
none
orcontents
, toblock
orinline
(respectively).Some examples of this include:
- Absolute positioning or floating an element blockifies the box’s display type. [CSS2]
CSS floating left weird behavior
Just set:
.short-movie {
height: 275px;
}
To make all movie items be of the same height and stop them being affected by the previous elements height.
Related Topics
Workaround for Href="File://///..." in Firefox
CSS Image Resize Percentage of Itself
Why Does a Filter Gradient on a Pseudo Element Not Work in IE8
How to Make a Line Before and After My H1 Tag
How to Trigger a Phone Call When Clicking a Link in a Web Page on Mobile Phone
Disable Form Autofill in Chrome Without Disabling Autocomplete
White Space Inside Xml/HTML Tags
Bootstrap Print CSS Removes Background Color
How to Make a Div 50Px Less Than 100% in CSS3
CSS Grid - Maximum Number of Columns Without Media Queries
CSS Only Animate Draw Circle with Border-Radius and Transparent Background
Css3 Scale - Prevent from Scalling Text
How to Create a Hidden Div That Doesn't Create a Line Break or Horizontal Space
Style Not Working for Innerhtml in Angular