<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog &#187; floats</title>
	<atom:link href="http://billauer.se/blog/tag/floats/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>CSS and DIV layout: The main pitfalls</title>
		<link>https://billauer.se/blog/2009/04/css-div-layout-main-pitfalls-cascaded-style-sheets/</link>
		<comments>https://billauer.se/blog/2009/04/css-div-layout-main-pitfalls-cascaded-style-sheets/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 14:49:00 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[absolute]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[div]]></category>
		<category><![CDATA[floats]]></category>
		<category><![CDATA[overflow]]></category>
		<category><![CDATA[overlap]]></category>
		<category><![CDATA[pitfalls]]></category>
		<category><![CDATA[position]]></category>
		<category><![CDATA[relative]]></category>
		<category><![CDATA[rtfm]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[w3c]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=108</guid>
		<description><![CDATA[In the beginning web pages were simple and innocent. Then people started to abuse tables to achieve some layout. And then came CSS and DIV, the winning combination for making a web page oh-so-beautiful but not resizable. Web designers started telling the browser where to put what, and the browser responded with blind obedience, even [...]]]></description>
			<content:encoded><![CDATA[<p>In the beginning web pages were simple and innocent. Then people started to abuse tables to achieve some layout. And then came CSS and DIV, the winning combination for making a web page oh-so-beautiful but not resizable. Web designers started telling the browser where to put what, and the browser responded with blind obedience, even if the result was a rubble of text and graphics. That&#8217;s the deal: Use absolute positioning to get full control, but lose the browser&#8217;s capability of avoiding nasty accidents.</p>
<p>So here is my short list of the main problems you may run into, while attempting to layout a web page using CSS-backed DIVs. If you really have to, that is.</p>
<h2>Pitfall #0: Resize</h2>
<p>If your page is made with CSS, don&#8217;t let the width change. Period. Play with CSS/DIV layout only when you&#8217;re inside a box, whose width is known and fixed to the pixel. This is not very browser tolerant, I know. It may not work well on a tiny screen. Or a very big one.</p>
<p>But trust me on this: If you don&#8217;t set the overall width, you will sooner or later find yourself with spillovers and overlapping graphics. Maybe you can get it to survive a page resize on your browser. You have no chance with the IE version still not out.</p>
<p>If you want to allow a resize, use tables.</p>
<h2>Pitfall #1: Huge CSS file (reference by ID)</h2>
<p>This one is so common, that sometimes I wonder if I missed something.</p>
<p>Anyhow, the original idea of CSS, if I got it right, was to define the format in one place and put the content in another. I suppose someone hoped that people would go on using simple tags such as &lt;h1&gt; and &lt;p&gt; and get beautiful pages with clean HTML.</p>
<p>And to make things nicer, they allowed classes. So if you wanted a special paragraph, you just went &#8216;p.special&#8217; in the style definition, and then &lt;p class=&#8221;special&#8221;&gt; in the HTML, and there you were, the HTML still readable and the format consistent and depending on the content.</p>
<p>But then came style-by-ID, which turned everything into a joke. This made it possible to define the style for a very certain element, pin-pointing it by its ID tag. So if I wanted to format one single paragraph, I&#8217;d go &#8216;#theID&#8217; in the CSS file, and then &lt;p id=&#8221;theID&#8221;&gt; in the HTML. And that makes me wonder: If the styling is going to be used once anyhow, why not put it directly in the HTML? Why not go &lt;p style=&#8221;&#8230;&#8221;&gt; instead? Don&#8217;t tell me that you separate formatting from content, when you can&#8217;t change anything in the CSS file without checking the specific place where it&#8217;s used. If you remember where it was, that is.</p>
<h2>Pitfall #2: The IE &#8216;width&#8217; bug</h2>
<p>The <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">CSS2 spec</a> paragraph 10.2 clearly defines the &#8216;width&#8217; property as &#8220;that of the rendered content within&#8221;. Microsoft probably said &#8220;we are the standard&#8221; and decided to include the padding and the border in the &#8216;width&#8217; property. This is said to be fixed in IE6, so maybe it isn&#8217;t an issue today, after all.</p>
<p>Below is drawing of the box model, and the difference between the two definitions of &#8216;width&#8217;. The sad bottom line is that if you need a consistent width of some element, padding and border have to be zero. If this is not an option, the only safe solution is to put your element in another element (a DIV, I suppose) and define the &#8216;width&#8217; for the enclosing element.</p>
<div id="attachment_127" class="wp-caption alignnone" style="width: 490px"><img class="size-full wp-image-127" title="boxmodel" src="https://billauer.se/blog/wp-content/uploads/2009/04/boxmodel.png" alt="Box model" width="480" height="360" /><p class="wp-caption-text">Box model</p></div>
<h2>Pitfall #3: Getting absolute positioning wrong</h2>
<p>So let&#8217;s go through a few quick facts:</p>
<ul>
<li>Absolute positioning puts your element where it would anyhow, unless you specify otherwise for the X axis (with &#8220;left&#8221; and &#8220;right&#8221; style properties) and/or the Y axis (with &#8220;top&#8221; or  &#8220;bottom&#8221; style properties). The only difference is that no space is allocated on the rendered page. The responsibility to keep the underlying area clean (or intentionally overlapping) is all yours.  Usually, if you don&#8217;t know exactly what you&#8217;re doing, things will get wrong sooner or later.</li>
<li>If you want the element on a fixed position on the screen, no matter how the page is scrolled (logo?), used the &#8220;fixed&#8221; position.</li>
<li>&#8220;relative&#8221; position is not what it appears to be. It will move the block from its original position, but allocate  space for it, as if it was there. Makes sense if you want chemistry-style subscripting, but otherwise I can see only one use: The zero-offset relative positioning, which is a way to set the &#8216;position&#8217; property to something else than static (the default) without actually doing anything, and hence create a &#8220;containing block&#8221; in its natural place (more about that next).</li>
<li>The &#8220;left&#8221;, &#8220;right&#8221;, &#8220;top&#8221; and &#8220;bottom&#8221; properties are related to the &#8220;containing block&#8221;, whose definition is a pitfall in itself. (See the <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">CSS2 spec</a>, paragraph 10.1, item 4). To make a long story short, the browser will climb up the hierarchy of blocks until it finds one, which isn&#8217;t statically positioned. It will then respect that block&#8217;s padding, and there is the zero point.<br />
Now, &#8220;statically positioned&#8221; is the default setting of the &#8220;position&#8221; property, which means that the browser should put the element following the &#8220;old-fashioned&#8221; rules. See the example below for how to use the &#8220;relative&#8221; position to make the enclosing DIV effective.<br />
If the containing block isn&#8217;t explicitly defined, hell breaks loose. The browser will most likely pick the root block, which is the top left corner of the page. Or not, depending on other junk you have on your page. Everything happens.</li>
</ul>
<h2>Pitfall #4: Absolute positioning know-it-all</h2>
<p>I think that the main reason why &#8220;professional&#8221; web designers started talking about replacing &lt;TABLE&gt; formatting with &lt;DIV&gt; and CSS was that they first painted their web page with some graphics tool, and then wanted to copy their graphic design exactly into the web page. Which is a nice concept, if you can assure that the page will be viewed exactly like you expect: The same fonts, the same sizes, the same screen size, and so on. Which you can&#8217;t, but that&#8217;s another story.</p>
<p>No wonder they hated tables. It&#8217;s really a headache to control how the browser displays tables down to the pixel. Tables were, after all, not meant to be used that way. Getting the graphics from one table cell aligned with the next one is not easy. Not to mention more complex relations between graphic elements. And then came CSS and the DIVs.</p>
<p>The real power with DIVs is absolute positioning. Just make yourself a box, decide how large it will be (down to the pixel) and put whatever you want inside, exactly where you want it. Something like this:</p>
<pre>&lt;div style="position: relative; height: 200px; width: 200px; border: dotted red 1px;"&gt;
This is my canvas!
&lt;div style="position: absolute; top: 60px; left: 20px"&gt;And&lt;/div&gt;
&lt;div style="position: absolute; top: 50px; left: 70px"&gt;I&lt;/div&gt;
&lt;div style="position: absolute; top: 55px; left: 90px"&gt;can&lt;/div&gt;
&lt;div style="position: absolute; top: 60px; left: 130px"&gt;put&lt;/div&gt;
&lt;div style="position: absolute; top: 110px; left: 40px"&gt;the&lt;/div&gt;
&lt;div style="position: absolute; top: 105px; left: 70px"&gt;elements&lt;/div&gt;
&lt;div style="position: absolute; top: 112px; left: 140px"&gt;where&lt;/div&gt;
&lt;div style="position: absolute; top: 150px; left: 80px"&gt;I&lt;/div&gt;
&lt;div style="position: absolute; top: 155px; left: 90px"&gt;want!&lt;/div&gt;
&lt;/div&gt;</pre>
<p>And you get this:</p>
<div style="border: 1px dotted red; position: relative; height: 200px; width: 200px;">This is my canvas!&nbsp;</p>
<div style="position: absolute; top: 60px; left: 20px;">And</div>
<div style="position: absolute; top: 50px; left: 70px;">I</div>
<div style="position: absolute; top: 55px; left: 90px;">can</div>
<div style="position: absolute; top: 60px; left: 130px;">put</div>
<div style="position: absolute; top: 110px; left: 40px;">the</div>
<div style="position: absolute; top: 105px; left: 70px;">elements</div>
<div style="position: absolute; top: 112px; left: 140px;">where</div>
<div style="position: absolute; top: 150px; left: 80px;">I</div>
<div style="position: absolute; top: 155px; left: 90px;">want!</div>
</div>
<p>Now I&#8217;m asking, isn&#8217;t this heaven? I say: It is, on your browser, on your computer. But since you&#8217;ve told the browser exactly what to do, you&#8217;ve also crippled its ability to fix things when the page is shown differently from how you expect it. A simple example follows.</p>
<h2>Pitfall #5: Overflow</h2>
<p>The page got resized? The fonts are shown larger than you defined? There was more text than expected? In the old days, the browser used to fix this. With CSS and DIVs you get rubbish.</p>
<p>The CSS spec says, that any block can overflow. What to do with the excessive graphic pulp is up to the browser (or it can be defined) but no matter how it&#8217;s handled, the result is ugly.</p>
<p>Let&#8217;s take a silly menu layout for example:</p>
<pre>&lt;div style="position: relative; width: 120px; height: 70px; border: solid 1px black"&gt;
&lt;div style="position: absolute; top: 10px; left: 20px; background-color: #f8f;"&gt;Take me!&lt;/div&gt;
&lt;div style="position: absolute; top: 40px; left: 20px; background-color: #ff8;"&gt;Or take me!&lt;/div&gt;
&lt;/div&gt;</pre>
<p>That looks like this:</p>
<div style="border: 1px solid black; position: relative; width: 120px; height: 70px;">
<div style="position: absolute; top: 10px; left: 20px; background-color: #ff88ff; font-size: 14px;">Take me!</div>
<div style="position: absolute; top: 40px; left: 20px; background-color: #ffff88; font-size: 14px;">Or take me!</div>
</div>
<p>The truth is, I can&#8217;t be sure that you see this as I do. But I&#8217;ll assume that it looks idiotic, but OK. But what happens if a script puts more text than expected? Or if the user forces a larger font? I&#8217;ll try to simulate this by choosing a larger font here:</p>
<div style="border: 1px solid black; position: relative; width: 120px; height: 70px;">
<div style="position: absolute; top: 10px; left: 20px; background-color: #ff88ff; font-size: 30px;">Take me!</div>
<div style="position: absolute; top: 40px; left: 20px; background-color: #ffff88; font-size: 30px;">Or take me!</div>
</div>
<p>But the truth is that I can&#8217;t know if this example went through OK, because I don&#8217;t know how your browser responded. But that&#8217;s the point, isn&#8217;t it?</p>
<p>If you want to be on the safe side, use the &#8216;overflow&#8217; property. Below is shown what happens when you set &#8216;overflow: hidden;&#8217; (to the left) or &#8216;overflow: scroll;&#8217; (to the right) for the toplevel &lt;div&gt;. At least nothing spills over.</p>
<div style="position: relative; width: 260px; height: 100px;">
<div style="border: 1px solid black; overflow: hidden; position: absolute; width: 120px; height: 70px; top: 0px; left: 0px;">
<div style="position: absolute; top: 10px; left: 20px; background-color: #ff88ff; font-size: 30px;">Take me!</div>
<div style="position: absolute; top: 40px; left: 20px; background-color: #ffff88; font-size: 30px;">Or take me!</div>
</div>
<div style="border: 1px solid black; overflow: scroll; position: absolute; width: 120px; height: 70px; top: 0px; left: 140px;">
<div style="position: absolute; top: 10px; left: 20px; background-color: #ff88ff; font-size: 30px;">Take me!</div>
<div style="position: absolute; top: 40px; left: 20px; background-color: #ffff88; font-size: 30px;">Or take me!</div>
</div>
</div>
<h2>Pitfall #6: Floats</h2>
<p>For some reason, which is beyond me, floats are commonly suggested as a solution for organizing web pages (except for horizontal layout, as shown below). There is only one problem with floats: They were intended to push text, and nothing else.</p>
<div style="border: 1px solid black; margin: 6px; padding: 5px; float: left; width: 4em; height: 4em; background-color: #ffdddd; text-align: center;">Nice image</div>
<p>The whole idea was to allow an image to float to the left or right, and let the text surround it, just like as they do in newspapers. This is why the <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">CSS2 spec </a>says, in paragraph 9.4.1:</p>
<blockquote><p>In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. (&#8230;) In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). <strong>This is true even in the presence of floats</strong> (although a box’s content area may shrink due to the floats).</p></blockquote>
<p>Let me spell this out: Paragraphs, DIVs or whatever, <strong>shouldn&#8217;t</strong> get pushed aside by floats. What should get pushed is <strong>the text they contain</strong> (or more precisely, inline elements). What happens in reality seems to depend on the browser. Firefox and Google Chrome follow the spec, IE plays its own game.</p>
<p>So let&#8217;s look at the following example:</p>
<pre>&lt;div style="border: 1px solid black; margin: 6px; padding: 5px; float: left; width: 4em; height: 4em; background-color: #ffdddd; text-align: center;"&gt;
Nice image&lt;/div&gt;
&lt;div style="background-color: #ff8; width: 12em; border: solid 1px black;"&gt;
This is my DIV, which has melted into the float.
Only the text is pushed aside.
&lt;/div&gt;</pre>
<p>Which looks like this on <strong>your browser</strong>:</p>
<div style="border: 1px solid black; margin: 6px; padding: 5px; float: left; width: 4em; height: 4em; background-color: #ffdddd; text-align: center;">Nice image</div>
<div style="border: 1px solid black; background-color: #ffff88; width: 12em;">This is my DIV, which has melted into the float. Only the text is pushed aside.</div>
<p>Note that the non-floating DIV (in yellow) should surround the float. It should be packed as if the float wasn&#8217;t there. This is what the spec says should happen. In real life I got:</p>
<div id="attachment_144" class="wp-caption alignnone" style="width: 450px"><img class="size-full wp-image-144" title="Float behavior on Firefox and IE" src="https://billauer.se/blog/wp-content/uploads/2009/04/floats-pitfall.png" alt="Float behavior on Firefox and IE" width="440" height="192" /><p class="wp-caption-text">Float behavior on Firefox and IE</p></div>
<p>Not very impressive, is it?</p>
<p>By the way, if you want a rectangle which doesn&#8217;t mix with floats, put a table there. Tables are inline elements, so they won&#8217;t collide with floats. But if you&#8217;re playing with floats, you must be thinking that tables are obsolete&#8230;</p>
<p>Alternatively, you could go for a floats-only region. People who test with IE only are likely to get this wrong, because of the problem mentioned above. Anyhow, the idea is to pack DIVs horizontally to the right and to the left using floats, and avoid collision from top and bottom using the &#8220;clear&#8221; directive. For example:</p>
<pre>&lt;div style="background-color: #ffd; border: solid 1px black; text-align: center;"&gt;Above all&lt;/div&gt;
&lt;div style="float: left; background-color: #fdd; width: 4em; height: 3em; border: solid 1px black; text-align: center;"&gt;
One&lt;/div&gt;
&lt;div style="float: left; background-color: #fdd; width: 4em; height: 2em; border: solid 1px black; text-align: center;"&gt;
Two&lt;/div&gt;
&lt;div style="float: right; background-color: #fdd; width: 4em; height: 4em; border: solid 1px black; text-align: center;"&gt;
Four&lt;/div&gt;
&lt;div style="float: right; background-color: #fdd; width: 4em; height: 3em; border: solid 1px black; text-align: center;"&gt;
Three&lt;/div&gt;
&lt;div style="clear: both; background-color: #ffd; border: solid 1px black; text-align: center;"&gt;And this is below all!&lt;/div&gt;</pre>
<p>Which looks like this:</p>
<div style="background-color: #ffd; border: solid 1px black; text-align: center;">Above all</div>
<div style="border: 1px solid black; float: left; background-color: #ffdddd; width: 4em; height: 3em; text-align: center;">One</div>
<div style="border: 1px solid black; float: left; background-color: #ffdddd; width: 4em; height: 2em; text-align: center;">Two</div>
<div style="border: 1px solid black; float: right; background-color: #ffdddd; width: 4em; height: 4em; text-align: center;">Four</div>
<div style="border: 1px solid black; float: right; background-color: #ffdddd; width: 4em; height: 3em; text-align: center;">Three</div>
<div style="clear: both; background-color: #ffd; border: solid 1px black; text-align: center; margin-bottom: 2em;">And this is below all!</div>
<p>This is great for multiple columns, whose heights are unknown. We want the bottom DIV below all of them, and this is how it&#8217;s done. Note that if we put a non-floating DIV in the middle, we would get different behavior on IE and W3C-compliant browsers.</p>
<p>Note that none of the DIVs in this example contains the other. What makes them avoid each other is the &#8220;clear: both&#8221; attribute at the bottom which tells the browser that floats are not allowed in either side. So we get a clean line, immediately below.</p>
<p>One problem (or feature) of this method, is that if there is not enough horizontal space, floats will be pushed vertically, a bit like inline flow. Paragraph 9.5 of the <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">W3C specification</a> says:</p>
<blockquote><p>If there isn’t enough horizontal room on the current line for the float, it is shifted downward, line by line, until a line has room for it.</p></blockquote>
<p>This can&#8217;t be relied on too much, though. It looks like Firefox prefers to let some of the page go out of view rather than to mess the page up, when the page is resized to very narrow (below 400 pixels?). I don&#8217;t know exactly how it works, but the fact is that at some point the floats don&#8217;t tile vertically (in IE they do). I guess it&#8217;s an interpretation of &#8220;not enough horizontal space&#8221;.</p>
<p>And just a final remark about floats: The <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">W3C specification</a> requires that the width is known, and must therefore be set unless it has an intrinsic value (e.g. an image). But nothing stops us from setting the width in percents. With this simple trick, we can have columns that grow and shrink according to the limiting DIVs width (resizing&#8230;), while controlling the proportions between the columns.</p>
<p>Just a warning, though: Be careful with letting the overall width come near 100%, since the browser may round each float&#8217;s pixel width slightly. And of course, keep in mind that the width doesn&#8217;t include the border, margins nor padding, so these can cause a mess when things get tight. Not to mention mixing percentage width floats with constant width floats.</p>
<h2>Pitfall #7: Getting the selection wrong</h2>
<p>The grammar is in principle simple, but knowing the formalities is important. For example, div.theclass { } means a DIV with class &#8220;theclass&#8221;, but not necessarily a DIV within it. For a DIV within a certain class, the selection is e.g. &#8220;.theclass DIV { }&#8221;. This also goes for IDs, e.g. &#8220;#theID DIV { }&#8221;. The list can be nested, so a link within a list item within a certain ID could look like &#8220;#theID li a:visited { }&#8221;. The same trick goes with classes instead of IDs.</p>
<p>If several cases are desired, start the nesting from the beginning. Exactly like &#8220;a.banner:link, a.banner:visited, a.banner:active { }&#8221; one should also go &#8220;banner a:link, banner a:visited, banner a:active { }&#8221; when a &#8220;within&#8221; relation is desired rather than a direct one.</p>
<h2>Conclusion</h2>
<p>If you want to control your page&#8217;s layout down to the pixel, DIVs and CSS are your screws and screwdriver. Just remember that things may look very different when someone views your page with a cellular phone or some other gadget you wouldn&#8217;t think about.</p>
<p>As they always say, when everything else fails, RTFM (Read the Fine Manual). In the case of CSS, that manual is the <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" target="_blank">W3C specification</a>. This is not to say that browsers really follow it. Firefox does most of the time. At least they consider it a bug when it doesn&#8217;t. Microsoft and their IE live in a world of their own.</p>
<p>Anyhow, if you wonder why your &lt;div&gt;&lt;div&gt;&lt;div&gt;-page is a mess, or why everything goes wrong with patches of page fragments being where they shouldn&#8217;t be, the ultimate answer is to understand how the fine machine works. Or at least, how it was meant to. And that is written in the spec. Boring, but a man has to do what a man has to do.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2009/04/css-div-layout-main-pitfalls-cascaded-style-sheets/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
