Float: left. How does it work?

Hi everyone,
I wanted a page with a red square, sizes: 100px X 100px and a blue square, size:
80px X 80px on top of the red square, at the middle of it, 10px far from each side of
the red square. I coded:


<style type="text/css">
  #bg_red {width:100px; height:100px; background-color: red; float: left;  }
  #blue 
    {
     width:80px; 
     height:80px;
     background-color: blue; 
     float:left; 
     margin-top:10px; 
     margin-left:-80px;}
</style>
</head>
<body>
  <div id="bg_red"></div>
  <div id="blue"></div>
</body>

But i got the red square on top of the blue ! How can i change it to make the blue square
on top of the red ?
Thanks !

If it takes you some time, that’s normal.

I’m goin’ on 4 years now.

Thanks Stomme,
I’ll try to understand the examples your post includes

Hi Paul,
Thanks a lot for your efforts ! I’ll put double the efforts to assimilate what you wrote…
Thanks again

I also missed a lot of stuff.

Here’s a quick run-down of the basics of floating:

A floated element will allow following content to wrap around it. It will not affect any block boxes above it in the html. A floated element produces a block box so that if you float a span then it behaves as a block box and can have dimensions applied (unlike inline elements) but the box is also floated acts in the same way that floating a div would behave. There would be no difference.

(As an aside a floated element at the end of inline content like text should move any text on that same line out of the way and allows the float to move left or right (only very modern browsers get this right - not ie7 and below or ff3 and below)).

So the main thing to remember is that basically floats must come first in the html when you want something to wrap around them.

The second thing to remember is that floats are removed from the flow in much the same way that absolute elements are and an element that holds only floats will in fact contain nothing and have zero height. However you have the possibility of regaining the flow of the document by clearing the float and thus regaining control of the page. Hence the saying " Clear your floats" can be heard echoing all through css land.

When a float follows a block level box then it is floated from the position that it already finds itself in (which means it always starts on a new line (or on the same single line as preceding inline content - assuming room is available and a good browser is used as already mentioned) because a float is a block box). It will then float as far left or as far right as it possibly can until it meets something solid.

A float cannot rise up above any html above it unless that element is also a float (otherwise the float would keep rising up and float out of the top of the monitor).

Floats make room for themselves by repelling the foreground content such as text and images by increasing their margins until they are clear of the float. However backgrounds and borders of the moved element will still slide under the float and not be repelled (unless the element has overflow other than visible or is itself floated).

When a float occupies a space the containing block of the content following the float does not change and that is why the borders and backgrounds appear to slide under the float just as if the float wasn’t there (which in essence it isn’t).

Summary:

  • Floats are removed from the flow
  • You need to clear a float to make a parent encompass the float otherwise the parent has no height.
  • Floats must come first in the html when you want content to wrap (ignoring the inline behaviour already mentioned).
  • Floats only repel foreground content such as text and images but not borders and backgrounds which slide under the float.
Edit:

Stomme beat me to it lol :slight_smile:

and couldn’t get along with the first 10 words saying: “When you float an element it becomes a block box”…

…Since “blue” is floated left, it is a “block” so i expected “red” to start in a new line but that didn’t happen !!! Red is placed at the right side of “blue” !
Either i dont understand what “block” means or i’m unable to understand what “float” does…

One problem is that HTML elements are, by default, either represented as blocks or inlines (or sometimes inline-block like form inputs) in browsers before you actually use any CSS.

A div is a block, be default. If you don’t add any CSS styling, then in a browser it is represented as a static block element (static basically meaning “not positioned”, equivalent to “position: static”). Static blocks have certain default properties, which you were looking for in your code:

-they try to be 100% width of their container
-their heights are determined by their (non-floated) content inside them
-their containers (if static blocks) will grow in height to contain them, just as they grow to contain their own content
-they start on a new line
-they can have vertical margins (inlines can’t)
-vertical margins are susceptible to margin-collapse
-can be centered within their containers with “auto” side margins (so long as they are less than 100% wide)
-they try to have their top left corner as close as possible to the top left corner of their container, or the page
-they will bump each other around in 2-d space on the page; that is, if a block above another block grows in height due to an increase in content (say you added more text), the block underneath gets bumped further down. This is a sign that they are within the “flow” of the document. They “see” each other and react to each other, and normally two blocks cannot share the same space (otherwise the universe will divide by zero and implode).

So, because you started your boxes as “div”, they would have started a new line just as you expected, because that’s what they normally do. And you could set heights and widths on them, and vertical margins, because they were blocks to start out with.

Floating a block doesn’t stop it from being a block, but floating an inline can make that inline have “block context” (likely what that sentence you quote is talking about). If you float an anchor (who is an inline by default), that anchor does not need the “display: block” statement because being floated puts it in block context already.

Floats are a special type of block, though, so they do not act the same as static blocks!
Floats
-do NOT try to be 100% width of their containers. Instead, their default width: auto means “width of content inside”, similar to an inline (“shrinkwrapping”)
-do NOT have to start a new line (setting “clear” on a float is one way to force it to a new line). Instead, floats can stack up alongside each other the way inline elements do. This is useful when you want two blocks next to each other on one line
-like static blocks, they CAN have user-set heights and widths
-like static blocks, they CAN have vertical margins
-vertical margins are not supposed to be able to collapse (except they sometimes do in IE, but… that’s IE for you)
-cannot use “auto” side margins for centering

So, when you floated a box, you changed some of its properties, and you also changed how the other elements on the page “see” it.

Floats are partially out of the document flow. Inline sibling elements can see them, but normally static blocks who are siblings don’t: they slide behind floats (big IE exception here, lawlz), and containers who have floats as children do not normally “see” those children. Sometimes this is not what a web developer wants to have! Sometimes you want your containers to enclose your floats.

IE’s Haslayout property makes IE act differently, so it’s good to be aware of it as a web developer.

You can see visually what floats do here if you look in a modern browser and then in IE7 (or IE6). IE8 doesn’t have Haslayout so it should look the same as a modern browser.

After playing with floats (just give them ugly background colours as you have been doing so you can see them) to get the basic idea down, read Paul’s Floats and bugs sticky.

Z-index, if someone didn’t say this earlier (I might have missed it) cannot be manually set on a box unless it is a positioned box (position: relative, absolute or fixed).

The property name is z-index. Index on its own will not do anything. Furthermore, you must apply a position property of absolute, relative or fixed on order for z-index to apply. Using it on a statically positioned element will have no effect.
Also, it’s worth knowing that position: absolute and position: fixed remove objects from the content flow, and other objects will be placed as though these objects don’t exist. Position relative keeps the content in the flow while still allowing the use of positioning and z-index.

Thanks Stevie,
I never used “index” before so i’ll try it now.
Thank you very much !

Hi Paul,
I recognized that too, later, after i had sent my post. it was “Dreamweaver” i was working with and it showed the 2 squares as i initially described it.
Thanks a lot.

Thanks stomme,
My problem is not how to manage “blue” and “red”. It is: How to understand “float” style :slight_smile:
Thanks again

Hmmm, in every browser I tested the blue square is on top of the red square. You needed to adjust the negative margin to -90px for it to be central though. As Stevie said above you could force the issue anyway by applying position:relative to the blue float and ensure the z-index is higher.

Hi Zarin, i’m so confused by that “float” thing so i’m making all kinds of mistakes…
I started reading “Hoatutorial” through the link you suggested and couldn’t get along with the first 10 words saying: “When you float an element it becomes a block box” I tried this code:


<style type="text/css">
  #bg_red {width:100px; height:100px; background-color: red;}
  #blue 
    {
     width:80px; 
     height:80px;
     background-color: blue;float:left;}
    }
</style>
</head>
<body>
  <span id="bg_red">aaa</span>
  <span id="blue">bbb</span>
</body>

Since “blue” is floated left, it is a “block” so i expected “red” to start in a new line but that didn’t happen !!! Red is placed at the right side of “blue” !
Either i dont understand what “block” means or i’m unable to understand what “float” does… Maybe you can still help me…
Thanks a lot !

Floating makes other content flow around block objects. If you test the code I posted earlier, you will see how text wraps around the block. That is the main function of float. It’s commonly used to style list based navigation bars. You can have html code like this:


<ul id='nav'>
  <li><a>Link 1</a></li>
  <li><a>Link 2</a></li>
  <li><a>Link 3</a></li>
  <li><a>Link 4</a></li>
</ul>

When styled properly using floats, this code can produce a horizontal menu that is semantically correct and incredibly easy to read and edit.

As I would have, but I’d rather not upset the structure of the elements. I assumed there was a reason for them to be separated, so I looked for another solution. The container is being used as a bounding box to make content flow around the contents without messing with the structure of those elements on the chance that blue has a reason not to be a descendant of the red. If you remove the container element, you’ll see the text doesn’t flow around the block, which is why it’s there.

It’s Zarin, and it’s no problem. If you need any more help, feel free to PM me.

Thank a lot Zanin.
There’s much to learn for me from your post.

If you need these elements to occupy the same space you can contain them and position them absolutely. This removes them from the content flow, hence the need for the container.

The absolutely-positioned element is completely ignoring the container right now, meaning, why have it at all? (if #container had been a positioned ancestor then it might have mattered, but it’s not)

Me, I would have put the blue square inside the red (unless there was a content reason not to) and just use padding on red (or margin on blue + anti-collapse code) to make an even amount of space around blue.

You can change which items sit on top of or beneath other items using the z-index property - setting a positive z-index moves something on top of the default layer (and a higher number brings it on top of lower numbers), and a negative z-index moves it behind other elements.

Ah, I see what you’re doing there.

I assumed there was a reason for them to be separated, so I looked for another solution.

True, it’s hard to tell what this will be, as right now it’s a drawing, not a web site.

But there is so much other stuff we don’t know: if these red and blue squares are somewhere else on the page, your code also needs to be modified. You could make it portable all over the page if you make #container a positioned ancestor and then red square will go wherever it goes.