Order of HTML affects CSS - help!

This is causing me to pull out my nose hair!

In an effort to replace tables with table-less CSS & HTML, I’ve tried to come up with some simple code for a two-column snippet.

This is not necessarily for a page layout, just for one or more sections within a web application. As I’ve said, I need to replace old HTML tables with CSS.

Basically, this is what it looks like:

The problem is, it actually works, but I’m afraid it won’t hold up. As soon as I switch some of the HTML around, the layout falls apart, like so:

Basically, I wanted to place the HTML in the order in which it appears in the document. The layout works when I have the following code (it is bare-bones minimal, stripped down, just to show what happens):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Simple XHTML Example </title>


<style type="text/css">

#container{
	width: 90%;
	margin: 10px auto;
	background-color: #fff;
	color: #333;
	border: 1px dotted #363636;
	line-height: 130%;
}

#top{
	padding: .5em;
	background-color: #ddd;
	border-bottom: 1px solid gray;
}

#top h1{
	padding: 0;
	margin: 0;
}

#fsTable{
	background-color: #eee;
	float: right;
	width: 500px;
	margin: 0;
	padding: 10px;
}

#content{
	margin-right: 520px;
	border-right: 1px solid gray;
	padding: 1em;
	max-width: 36em;
}

#footer{
	clear: both;
	margin: 0;
	padding: .5em;
	color: #333;
	background-color: #ddd;
	border-top: 1px solid gray;
}

#fsTable p { margin: 0 0 1em 0; }
#content h2 { margin: 0 0 .5em 0; }


 /*
 	FLOAT CONTAINERS FIX:
 	http://www.csscreator.com/attributes/containedfloat.php
*/

.clearfix:after {
	content: ".";
	display: block;
	height: 0;
	clear: both;
	visibility: hidden;
}

.clearfix{display: inline-block;}

/* Hides from IE-mac \\*/
* html .clearfix{height: 1%;}
.clearfix{display: block;}
/* End hide from IE-mac */

</style>
</head>
<body>

	<div id="container">

		<div id="fsTable">Aggregate Teller Balancing Record</div>

		<div id="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>

	</div>

	<div class="clearfix"></div>

</body>
</html>


Then I make a minor change in the HTML, and it stops working (see what it looks like in the second screenshot):

<body>

	<div id="container">


		<div id="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>

		<div id="fsTable">Aggregate Teller Balancing Record</div>

	</div>

	<div class="clearfix"></div>

</body>

All I did was move the floating “fsTable” DIV below the DIV that holds the content for the left column.

Am I missing something? Is there a document flow issue that I need to be aware of?

Seriously, I thought that CSS would be able to affect the layout, regardless of the HTML markup . . . but somewhere I went wrong.

Can anyone point me to the solution to this problem?

Please.

Hi,
As you noticed floats should always come first in the html source if they are to sit beside a non-floated div.

To get your content first you can float both of the inner divs. You will need to set widths on the floats so they don’t shrinkwrap though. Things get trickier when using percentage widths though, browsers will give rounding errors and you can’t set their combined widths to total 100%. Then borders and paddings start throwing things of as well when they are set in pixels.

Here is a rough version that assumes the left column will always have more content. Equal height columns will require a different approach.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Simple HTML/CSS Float Example </title>
 
<style type="text/css">
 
#container{
    width:90%;
    max-width: 60em;
    margin:10px auto;
    background: #eee;/*right column BG color*/
    color:#333;
    border:1px dotted #363636;
    line-height:130%;
    overflow:hidden;/*contain floats*/
}
#content{
    float:left;
    width:60%;
    border-right: 1px solid gray;
    background: #fff;
    /*padding: 1em;*/
}
 #fsTable{
    float:right;
    width: 38%;
    /*padding: 10px;*/
    background: #eee;
}
#container p { margin: 0 1em 1em; }
 
</style>
</head>
<body>
 
<div id="container">
    <div id="content">
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the 
        industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and 
        scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap 
        into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the 
        release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing 
        software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    </div>
    <div id="fsTable">
        <p>Aggregate Teller Balancing Record</p>
    </div>
</div>

</body>
</html>

Try this to learn more about float theory.

THat’s because floated elements must come first in the document (which makes sense otherwise flots would rise to the top of the screen ;))

As the content is not floated it will not allow the sidebar to be raised up there :slight_smile:

Rayzur
Thank you very much. Your explanations make perfect sense. Thank you so much for taking the time to help me out with this. You rock!

optimus203
Greatly appreciate the link to SmashingMagazine’s in-depth discussion of FLOATs. Thank you for he;ping me out.

RyanReese
Good point. Thank you. Obviously, I didn’t know that, so thank you for pointing that out to me.

Floats display these kinds of tricky behaviors. Usually I begin by using position: for that reason, because it tends to be more stable. I prefer to use float: when I want an element to display the “flow” behavior so that an elements wraps neatly around another. So practically, I’m really only using float: as a behavior while I use position: to create and place elements in my layout.

Chroniclemaster1
Thank you for your interesting comment.

By and large, I think I understand what you’re saying, but would you happen to have a simple example, perhaps with multiple “rows” of two-column DIVs…to illustrate your point?

I’m not sure if this is what you mean, but try copying this into an HTML file. First, note that this sucks, the CSS should be in a linked stylesheet not embedded, but it should make the test easier for you to run for right now. Just don’t use this technique in production code. :wink:

Also, I’ll throw in a couple caveats. Note that I’m using a valid !DOCTYPE element as part of all the HTML which validates perfectly on the W3C validator. All the CSS also validates perfectly on the Jigsaw validator (I think also run by the W3C). This is so important to making all this work out, I find that even IE6 only balks at some of the newest CSS styles as long as all your code validates. I generally do not have more than a couple cross-browser compatibility issues with my designs, and those I patch with an IE6 and below specific stylesheet (usually by ripping stuff that’s too advanced for it out, but it will blow you away, how much it can actually handle reliably).

I’m also using the star selector to reset all margins and padding to 0, another big cross-browser sanity saver. Then so you can see what’s going on, I’ve implemented my big CSS test technique when I’m getting my layout put together; I’ve applied borders to everything so I can see exactly where everything is and what size. Along with a little body padding, that’s all there is to the base stylesheet. Now take a look, the rest is pretty much handling the layout.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    
    <head>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            body {
                padding: 1em 1em;
            }
            
            div {
                border: solid red 2px;
            }
            
            #main div, 
            #secondaryContent div {
                border-color: blue;
            }
            
            #main, 
            #secondaryContent {
                width: 47%;
                border-color: cyan;
            }
            
            #secondaryContent {
                position: absolute;
                top: 0;
                right: 0;
            }
/*            
            #contentWrapper {
                position: relative;
            }
*/            
        </style>
        <title>Earth Chronicle Home</title>
    </head>


    
    <body id="default">
        <div id="contentWrapper">
            <div id="main">
                <h2>Main Content</h2>
                <div>
                    Main content for the first row
                </div>
                <div>
                    Main content for the second row
                </div>
                <div>
                    Main content for the third row
                </div>
            </div>
            <div id="secondaryContent">
                <h2>Secondary Content</h2>
                <div>
                    Secondary content for the first row
                </div>
                <div>
                    Secondary content for the second row
                </div>
                <div>
                    Secondary content for the third row
                </div>
            </div>
        </div>
    </body>
</html>

To facilitate two columns, I’m setting the main and secondaryContent divs to a width of 47%. Also note I’ve attached this style declaration to the id selectors. If I’d applied this to a div, you’d see each div collapse to 47% of the width of its parent div, sort of an interesting look, but not usually what you’re going for.

Next I change the secondaryContent div using position:absolute. The div no longer cares where it is in the flow of the document, nor does any other content. I can now use the top and right properties to stick the secondaryContent section in the top right corner of the page. This is a layout for a sidebar. You can see how you can adjust the width of the secondaryContent section to taste and adjust the margins and width of the main content section to provide as much or as little whitespace between them as you like.

The thing I really like about position, is that the two sections will STAY where you put them. I find that to be unlike float which is fundamentally slippery (that’s why you use it, for that liquidity, no property is so “smart” in terms of sensing where it is, and moving to what it considers to be the best possible location (whether you think so is another matter :wink: but when used correctly float can do things nothing else can do. It’s a killer tool to have in your toolbox.)

The last thing you’ll see here is that I’ve included a “superfluous” wrapper div, contentWrapper, around the whole thing. There is a style rule for it, but at the moment it is commented out. Here’s why…

When you look at the code “as is”, you’ll note that the secondary column is NOT behaving itself. When we applied the top:0; and right:0; declarations, this div didn’t fall into line with the main content, it’s flown all the way up to the corner of the viewport. While it’s nice to know that you can do that, this is almost never what we really want. We want the sidebar to respect the padding we’ve set on the body element. This is something to be aware of and it explains why this page looks like it does. All other things being equal, absolute positioning fits things relative to the page.

Here is how to make positioning work for you. Any element that you position is moved relative to it’s nearest positioned ancestor. The ancestor element of the secondaryContent column is the contentWrapper div. However, it is not currently positioned. Therefore, secondaryContent ignores it and looks for the next closest ancestor. If that ancestor is positioned, then secondaryContent will be positioned with respect to that ancestor, but if not we keep going. This continues until we reach the body element (ie the page). If there is no positioned ancestor of the positioned element, then it takes effect with respect to the body tag. This is why I apply my visual page margin to the body element using padding so I can play with this exact look if I need to (ie if I want to move the sidebar or another element into the visual page margin, I have the ability to do so easily). Now uncomment the style rule for contentWrapper. Now that I’m positioning the div, IT becomes the element which secondaryContent is positioned with respect to. Now secondaryContent moves to the top right corner of the contentWrapper div and everything looks nice and clean. This is usually what you want, but unless you break things down like this it’s hard to understand positioned ancestors, etc. and really use them effectively. This may be why people fall back to float, because at first glance it seems to make what you want just happen… usually. However, it’s so tricky to manage in some ways, that I’ve been completely won over to positioning.

Well, at least once I understood how it worked. :wink:

The thing I really like about position, is that the two sections will STAY where you put them. I find that to be unlike float which is fundamentally slippery (that’s why you use it, for that liquidity, no property is so “smart” in terms of sensing where it is, and moving to what it considers to be the best possible location (whether you think so is another matter :wink: but when used correctly float can do things nothing else can do. It’s a killer tool to have in your toolbox.)

Absolute positioning is fine for small chunks of the page that need to be removed from the page flow intentionally but it is a bad way to set up your main divisions.

I never really considered floats to be slippery as you described them, I find them to be more like magnets. They stick hard and fast to the left or the right and then you fine tune them with margins. The other advantage is that text will flow around them when needed.

On your example you needed to set the main wrapping div as the containing block for the AP right column. Now here is the problem with it being removed from the flow, the main wrapping div does not see it there and it will not expand when the right column is greater. A background color on the #contentWrapper shows it stopping with the left column and the right column hanging out. That would not work in a page that depends on the parent to expand.


#contentWrapper {
background:#CDF;
position:relative; /*establish containing block*/
}

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    
    <head>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            body {
                padding: 1em 1em;
            }
            #contentWrapper {
                background:#CDF;
                position:relative;
            }
            
            div {
                border: solid red 2px;
            }
            
            #main div, 
            #secondaryContent div {
                border-color: blue;
            }
            
            #main, 
            #secondaryContent {
                width: 47%;
                border-color: cyan;
            }
            
            #secondaryContent {
                position: absolute;
                top: 0;
                right: 0;
            }
/*            
            #contentWrapper {
                position: relative;
            }
*/            
        </style>
        <title>Earth Chronicle Home</title>
    </head>


    
    <body id="default">
        <div id="contentWrapper">
            <div id="main">
                <h2>Main Content</h2>
                <div>
                    Main content for the first row
                </div>
                <div>
                    Main content for the second row
                </div>
                <div>
                    Main content for the third row
                </div>
            </div>
            <div id="secondaryContent">
                <h2>Secondary Content</h2>
                <div>
                    [B]Secondary content for the first row[/B]
                </div>
                <div>
                    [B]Secondary content for the second row[/B]
                </div>
                <div>
                    [B]Secondary content for the third row[/B]
                </div>
                <div>
                   [B] Secondary content for the fourth row[/B]
                </div>
                <div>
                    [B]Secondary content for the fifth row[/B]
                </div>
                <div>
                    [B]Secondary content for the sixth row[/B]
                </div>
            </div>
        </div>
    </body>
</html>

On your example you needed to set the main wrapping div as the containing block for the AP right column.

Never mind, I see where you had it commented out at the bottom of your css.

I guess I missed part of your post. :wink:

:smiley: No, it’s not your fault. I set this up to demonstrate positioning context because that was the thing Andy Clarke explained so well in Trascending CSS. I did NOT get positioning before reading that book, and it wasn’t until he went step by step like this, that I got it. So yes, the example explicitly doesn’t work and you have to uncomment the style rule to reset the positioning context… and hopefully get your “positioning epiphany”. :wink: Or at least that was my idea. Sorry for the confusion.

you have to uncomment the style rule to reset the positioning context… and hopefully get your “positioning epiphany”. :wink: Or at least that was my idea. Sorry for the confusion.

Right, we have to set position:relative on the parent to establish it as the containing block.

I had also mentioned another problem in my previous post and it is the BIG problem.

Now here is the problem with it being removed from the flow, the main wrapping div does not see it there and it will not expand when the right column is greater. A background color on the #contentWrapper shows it stopping with the left column and the right column hanging out. That would not work in a page that depends on the parent to expand.

You will see that I added more content to the AP’d right column and then I set a BG color on the main wrapping div. If you run the code I posted above you will see the problem and that is the main reason not to use AP for layout methods. Absolute positioning can be very helpful and in fact we would be at a loss without it, just use with caution is the point I am trying to make. :slight_smile:

            <div id="secondaryContent">
                <h2>Secondary Content</h2>
                <div>
                    Secondary content for the first row
                </div>
                <div>
                    Secondary content for the second row
                </div>
                <div>
                    Secondary content for the third row
                </div>
                <div>
[B]                    Secondary content for the fourth row
                </div>
                <div>
                    Secondary content for the fifth row
                </div>
                <div>
                    Secondary content for the sixth row[/B]
                </div>
            </div>

#contentWrapper {
[B]background:#CDF;[/B]
position:relative; /*establish containing block*/
}

True, you can see why typically don’t put a background on that container. I like the stability and flexibility though. I’ve been able to get it to work consistently and elastically for screen resolutions from mobile to 2000+ px width HD displays. That’s the up side and you make sure that it looks like everything is clean.

How do you approach a layout like this? RP? Float? Other? Combination of techniques?

I know that I approach the layouts with floats/margins. For small design segments I’ll put some RP/AP in there just to get aesthetics although for the actual structure, floats and margins is what I use.

It’s the best way :slight_smile:

Hi Chronicle,
I work exclusively with floats when setting blocks beside each other. Even though floats are removed from the flow like AP elements, they behave differently. You can force the parent to see them and then the parent will expand with them. Depending on the circumstances I may use a small bit of RP to line things up exactly. That is usually the case when crossing over a border or if I have maxed out a negative margin.

The degrees of complexity depend on whether it is an equal height columns or non equal. One thing I do different with 50-50 layouts than most people is go ahead and set the widths to 50%. Most people will set their widths at 48-49% to avoid rounding errors. There is a little trick though when using floats to get around those errors. All it takes is a 1-2px negative margin on one of the floats to allow the other one to slide under it.

Things can get difficult when setting pixel width borders on percentage width floats also. There is a trick for that too, I will set a left/right padding on the main wrapper to soak up my border widths. Then I drag the floats into that parent padding and the problem is solved. :wink:

Here are some live examples of the various methods -
(The css has been commented to explain the layouts)

Without having to deal with borders or equal height columns this code below is about as simple as it gets.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>50-50 Floats: Non-Equal Columns</title>

<style type="text/css">
body {
    margin:20px;
    padding:0;
}

/*=== Layout Structure ===*/
#wrapper {
    overflow:hidden;/*contain floats (IE7 haslayout)*/
    padding-bottom:10px;
    background:#AAA;
    border:2px solid #000;
    height:1%;/*IE6/7 haslayout (safe to use in this case) */
}
#left, #right { /* grouped together to share common rules*/
    float:left;
    width:50%;
    margin:0 -2px 0 0;/* -2px right allows left column to soak up rounding errors (all browsers)*/
    background:#0F0;
    overflow:hidden;/*kill IE6 expanding box bug*/
}
#right { /*reset specific #right rules*/
    float:right;
    margin:0;
    background:#BDF;
}

h1 {text-align:center;}
h2,p {margin:0;padding:.5em;}

</style>

</head>
<body>

<h1>50-50 Floats: Non-Equal Columns</h1>
<div id="wrapper">
    <div id="left">
        <h2>Left Heading</h2>
        <p>Left content in the first paragraph.</p>
        <p>Left content in the second paragraph.</p>
        <p>Left content in the third paragraph.</p>
    </div>
    <div id="right">
        <h2>Right Heading</h2>
        <p>Right content in the first paragraph.</p>
        <p>Right content in the second paragraph.</p>
        <p>Right content in the third paragraph.</p>
        <p>Right content in the fourth paragraph.</p>
        <p>Right content in the fifth paragraph.</p>
        <p>Right content in the sixth paragraph.</p>
    </div>
</div>

</body>
</html>

Chroniclemaster1
Wow! You are awesome. THANK YOU so much for taking the time to put something together and document it as thoroughly as you have. You have gone way beyond the call of duty here. I appreciate you!

Rayzur
Good Gravy! This is fantastic stuff and helps me understand floats a lot better. You have really impressed me with your explanations, and I wanted to thank you for every comment and example.

No problem webgyver. :slight_smile: Except for the last couple style rules, everything was either base or testing rules. In my book, simpler is better. There’s the one #secondaryContent style rule which positions the sidebar. Then there’s the commented style rule that gives a positioning context to the parent container, #contentWrapper, so that the sidebar is positioned with respect to that container. As Rayzur notes, this can create some issues depending on the length of the sidebar content and the layout of the rest of your page, but this is the core technique I traditionally start with to manage the macro layout and then get as creative as necessary to micromanage the details.

Hi Rayzur - WOW!

I remember how much help you were a couple years ago to my web designer for sunrisemanagement.com, and this is similarly fantastic. The other forum I visit has a “thanks” button to highlight especially helpful posts, and I find myself clicking around for it. Too bad it’s not there.

I have never seen or even heard anyone talk about forcing containers to expand with their floated elements. I will be studying that for sure over the next couple days, as it’s given me trouble with a number of my OO-CSS components. If I can integrate this behavior into the content area and the components it will give me a lot more freedom to use floats in components.

:o I have never seen anyone get decent behavior out of 50% widths before. Maybe I have on sites that I haven’t investigated the CSS, but your negative margin with 50% technique was a new one for me. What are the strengths and weaknesses compare to using a reduced percentage?

I’m not sure if you need to take these pages down at some point, so I used the Firefox, “save all files” for each of these pages and am printing out items for my “highlights” morgue folder. I really appreciate the effort you put into these. I’m sure I’ll be posting other threads about them as I begin to play with them and have questions.

I have never seen anyone get decent behavior out of 50% widths before. Maybe I have on sites that I haven’t investigated the CSS, but your negative margin with 50% technique was a new one for me. What are the strengths and weaknesses compare to using a reduced percentage?
Hi,
I did not discover anything new there, that is just some beneficial side effects of floats. In my eyes credit for the method would go to Paul O’B, it was with his “Fixed Center - Fluid Sides” layout that I learned about the negative margins on the inner sides of the floats.

I can’t find the link to his demo right now but I have a version of it that shows the basic mechanics of it.

Fixed Width Center Column - Fluid sides

When viewing that page you will see the pink and palegreen 50% width floats when you drag your browser window around. Those two floats have large negative margins on their inner edges to make room for the fixed width center column.

I have not found any weaknesses with it since -1px will usually take care of any rounding errors. I have set it at -2px just for added insurance but you won’t notice any difference.

The strengths are that I am able to keep the widths at a true 50% which will completely close the gap between them. Even though 48-49% would stay consistent it leaves you with an undesirable gap.

I’m not sure if you need to take these pages down at some point, so I used the Firefox, “save all files” for each of these pages and am printing out items for my “highlights” morgue folder. I really appreciate the effort you put into these. I’m sure I’ll be posting other threads about them as I begin to play with them and have questions.
No problem, they will remain on my site and they are in the “Two-Column Fluid & Elastic” section.

@Chroniclemaster1
You mentioned floats being slippery in one of your previous posts. Then I had compared them to being like magnets.

Actually what I was doing with those negative margins in the opposite direction of the float was forcing them to become slippery.

Unlike that 3-col example I just linked to, here is a very minimal test case to make the principle much easier to understand.

Sliding Floats

By setting a negative right margin on the left float that is the same as the floats width we can make other elements slide on top of it completely. :slight_smile: