4

I don't understand why the div#footer only recognizes the space taken by div#navigation{float:right}.

Since float elements are taken out of the normal flow, div#footer should ignore both float:right and float:left elements.

I am not trying to add clear:both to div#footer. I am just curious how it happened.

body {
    margin: 0;
    padding: 0;
    background: #ccc;
}
#container {
    width: 600px;
    margin: 0 auto;
}
#header {
    padding: 30px;
    background: #bbb;
}
#content {
    float: left;
    width: 460px;
    background: #fff;
}
#navigation {
    float: right;
    width: 140px;
    height: 200px;
    background: #eee;
}
#footer {
    background: #aaa;
    padding: 10px;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>CSS Floats 101</title>

    </head>
    <body>
        <div id="container">
            <div id="header">
                <h1>Header</h1>
            </div>
            <div id="content">
                <p>
                    Proin vel ante a orci tempus eleifend ut et magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus luctus urna sed urna ultricies ac tempor dui sagittis. In condimentum facilisis porta. Sed nec diam eu diam mattis viverra. Nulla fringilla, orci ac euismod semper, magna diam porttitor mauris, quis sollicitudin sapien justo in libero. Vestibulum mollis mauris enim. Morbi euismod magna ac lorem rutrum elementum. Donec viverra auctor lobortis. Pellentesque eu est a nulla placerat dignissim. Morbi a enim in magna semper bibendum.
                </p>
            </div>
            <div id="navigation">
                navigation
            </div>
            <div id="footer">
                Footer
            </div>
        </div>
    </body>
</html>

I dont understand why the div#footer only recognizes the space taken by div#navigation{float:right}.

Since float elements are taken out of the normal flow, div#footer should ignore both float:right and float:left elements.

Makyen
  • 31,849
  • 12
  • 86
  • 121
J.Joe
  • 644
  • 2
  • 7
  • 20
  • You should clear the float using `clear: both`. – Harry May 28 '16 at 04:12
  • @Harry I am not trying to add clear:both to div#footer. I am just curious how it happened. – J.Joe May 28 '16 at 04:13
  • Check this CSS Tricks article - https://css-tricks.com/almanac/properties/c/clear/ – Harry May 28 '16 at 04:14
  • `If the element can fit horizontally in the space next to another element which is floated, it will. ` That sentence is what I am looking for. Maybe a W3 Specification reference is better. – J.Joe May 28 '16 at 04:17
  • 1
    [This](https://www.w3.org/TR/CSS2/visuren.html#floats) is the reference for the specs and per my understanding, this is the line which corresponds to the sentence highlighted above - *If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space* (in the para which starts as *The border box...*). If you find it satisfactory enough then I will post it as answer. – Harry May 28 '16 at 04:28
  • 1
    Feel free to post the answer. But float still confuses me. `if necessary` `should ` `but may ` This sound ambiguous. – J.Joe May 28 '16 at 04:31
  • 1
    Do we still require CSS float model? :) – m4n0 May 30 '16 at 13:06
  • 1
    @J.Joe What do you mean by "recognizes the space of the navigation div"? It's unclear what behavior you're talking about. – TylerH May 30 '16 at 13:49
  • @TylerH I mean `div#footer` should ignore `div#navigation{float:right}`. I thought the text inside `div#footer` should be hidden underneath the floated elements. – J.Joe May 31 '16 at 02:17

2 Answers2

10

When elements are floated, they are removed from the normal flow of the document. To understand it completely, that means you need to think about elements being placed in the normal flow, first, and then you can think about removing them with the float property.

Because the #navigation and #content elements are both floated, they are removed from the normal document flow. This moves the #footer element up to the top of the #container element. It's effectively positioned 'underneath' the two floated elements now.

The reason you're seeing the "footer" text still is that all un-cleared text wraps around floated elements (remember, float was designed to be used for wrapping article text around embedded images, like in a magazine article). In this case, the full width of the text's container is filled from side-to-side with floated elements, so the text is pushed to a new line.

It's hard to intuit from your example, so take a look with this one:

body {
    margin: 0;
    padding: 0;
    background: #ccc;
}
#container {
    width: 600px;
    margin: 0 auto;
}
#header {
    padding: 30px;
    background: #bbb;
}
#content {
    float: left;
    width: 460px;
    height: 190px;
    background: #fff;
}
#navigation {
    float: right;
    width: 140px;
    height: 220px;
    background: #eee;
}
#footer {
    background: #aaa;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>CSS Floats 101</title>

    </head>
    <body>
        <div id="container">
            <div id="header">
                <h1>Header</h1>
            </div>
            <div id="content">  
                Content
            </div>
            <div id="navigation">
                navigation
            </div>
            <div id="footer">
                Curabitur feugiat feugiat purus. Aenean eu metus. Nulla facilisi. Veni quis justo vel massa suscipit sagittis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Quisque mollis, justo vel rhoncus aliquam, urna tortor varius lacus, ut tincidunt metus arcu vel lorem. 
            </div>
        </div>
    </body>
</html>

As you can see, the text still wraps around the bottom of the #navigation element, too.

TylerH
  • 20,799
  • 66
  • 75
  • 101
-1

If you want to avoid floats, go for inline-block. Just make sure to avoid white-space in your html as it takes white-space in browser.

Also use font-size:0 to parent element and give required font-size to it's child element.