Help with 3 column template

hi there,

I am doing some work for a client which needs quite a specific (and seeing as the last 3 hours has left me knowwhere) seemingly impossible layout.

On the outside it appears to be simple…a three column layout with a centered main content, the left and right columns are a fixed 190px width and the central section needs to be 100% height.

below is a mockup of what im trying to get.

Uploaded with ImageShack.us

The kicker is that one of the requirements is to have the central section (white) to have a liquid layout with a max and min widths to be set.

Below is a rough guideline (from the client)

  •      a three-column layout, auto-centred on screen and auto-padded to left-and-right (with the cream background)
    
  •      the centre column should expand to accommodate content, with fixed minimum and maximum widths (height should be full browser height at least).
    
  •      (the center column needs a minimum width so the page doesn’t collapse in on itself, and a maximum so it does explode too wide)
    
  •      the flanking columns would be fixed width (190px on left and right, cream in colour again).
    
  •      the layout (each column) needs to extend to the full browser height.
    
  •      needs to render in IE7 and IE8.
    

I know this is alot but i am at the end of my tether at this one and i need some assistance…

Thank you in advance ;(

Column is what it IS, float is what it DOES. There’s a difference. CSS is about making the element DO things. Like Float, like have margins, like be displayed as inline or block… This has NOTHING to do with what an element IS – heading, paragraph, division – that’s markup’s job.

That arguement holds no weight as ‘inline-block’ doesn’t mean ‘column’ either. That’s just nonsensical.

That doesn’t even make sense.

It’s a waste of code and bad practice – and reducting waste in the markup is one of the cornerstone reasons to use CSS in the first place.

Usually it is, along with a UL and maybe a P – of those only the UL and P need ID’s and you almost NEVER need a wrapping DIV… But people insist on throwing presentational classes and DIV’s around everything.

If set on the PARENT element. Setting it on the element itself only effects the elements CONTENT, not the element itself! This is evident in your having to wrap all the content in span – yeah, that’s SUCH an improvement; NOT.

Try it at 800 wide where 0.5% is rounded to 4px, where on opera the minimum font size results in a 5px space character. Oopsy, drop.

Though if you WANT to waste markup putting spans around every line of code without being able to use floats or block level tags EVER inside it, go right ahead and use 30k of code to deliver 3k of content.

Inline-blocks are very handy, but that’s just not what they are for – and calling floats floats for columns a hack is some of the most absurd, nonsensical and outright idiotic things I’ve EVER heard online – and I’ve heard some doozies!

Only if you screw up your math or do something stupid like declare width on all THREE columns or try to use percentages for width – percentages for width on a narrow column is ALWAYS a disaster.

Yet what was asked for in this thread was a 100% min-height layout - that’s the POINT!

Of course that your latest code requires 1k of markup (after moving the CSS external), five unneccessary classes, eight unneccessary tags… all to do 700 bytes or less’s job – not encouraging. (and it’s likely to only get worse if you tried to put real content into it! – good luck adding P or H2)

Oh, and you have a typo on line 66 :stuck_out_tongue:

Though if you want to know why inline-block never got any traction, it’s mostly Mozilla’s fault for not officially supporting it until a year and half ago and making you use more of that -moz ********.

NOT that the ‘official’ implementation in 3.5/newer actually works right either – start playing with word-spacing, letter-spacing and text-align to see what I mean. NOT that webkit is any better in that regard (IGNORING word spacing between inline-level elements altogether!)

BTW, your last example ONLY works in FF here. No go in Opera or Saffy/Chrome… In firefux it’s fun watching that right 1px appear and dissapear based on width though (rounding errors) but your third column is dropping here everywhere else.

Especially Safari and Chrome, but of course part of that is word-spacing being ignored and that the font renderer is calculating that extra space as more than 4px. (usually 0.4em is used, since the font-size completely shtups the number so far as px are concerned)

kinda…the middle column needed to be 100% height.

How about you provide an example which you feel is correct rather than criticising his contribution? I am very happy with what has been provided to me and if you have something to add please do so

Rodent

Ach, laddy, that’s easy.

The technique I use puts a double div around the content. This simplifies the CSS requiring less ‘hacks’ to work. The big trick on these types of layouts is using a negative margins to make the fixed width columns 0 width, riding them up next to the 100% width floated outer wrapper. The first one (right) drops into place with a negative left margin, the second one (left) you have to give a negative relative position of 100%.

Basically this for markup:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<link
	type="text/css"
	rel="stylesheet"
	href="screen.css"
	media="screen,projection,tv"
/>

<title>
	Template Design CSS
</title>

</head><body>

<div id="pageWrapper">

	<h1>
		Site Title
		<span></span>
	</h1>

	<div id="contentWrapper"><div id="content">
		<h2>Page Content Here</h2>
		<p>Some text</p>
		<p>Some text</p>
		<p>Some text</p>
		<p>Some text</p>
	<!-- #content, #contentWrapper --></div></div>

	<div id="firstSideBar">
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
		<p>First SideBar Test</p>
	<!-- #sideBar --></div>

	<div id="secondSideBar">
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
		<p>Second SideBar Test</p>
	</div>

	<div id="footer"><hr />
		Footer Content Here
	<!-- #footer --></div>

<!-- #pageWrapper --></div>


</body></html>

and this for CSS:

/* null margins and padding to give good cross-browser baseline */
html,body,address,blockquote,div,
form,fieldset,caption,
h1,h2,h3,h4,h5,h6,
hr,ul,li,ol,ul,
table,tr,td,th,p,img {
	margin:0;
	padding:0;
}

img,fieldset {
	border:none;
}

body {
	text-align:center; /* center #pageWrapper IE 5.x */
	font:normal 85%/140% arial,helvetica,sans-serif;
	background:#FED;
}

h1 {
	padding:16px 0;
	font:bold 140%/120% arial,helvetica,sans-serif;
	color:#FFF;
	background:#080;
}

#pageWrapper {
	position:relative; /* make IE report width for second columns relative position */
	min-width:752px;
	max-width:1104px;
	margin:0 auto;
}

* html #pageWrapper {
	/*
		IE has no min/max width, but we can fake it
		with an expression. First we set a fixed width
		as a lowest common denominator for when jscript
		is disabled, then we run the expression to overload
		it if jscript is present.
	*/
	width:752px;
	width:expression(
		(document.body.clientWidth>1152) ? "1104px"
			: ((document.body.clientWidth>800) ? "auto" : "752px")
	);
}

#contentWrapper {
	width:100%;
	float:left;
}

#content {
	margin:0 200px;
	padding:0 1em;
	background:#FFF;
}

#firstSideBar,
#secondSideBar {
	position:relative;
	float:left;
	width:190px;
	background:#FFF;
}

#firstSideBar {
	margin-left:-190px;
}

#secondSideBar {
	left:-100%;
	margin-right:-190px;
}

#footer {
	clear:both;
	background:#EDC;
}

Will get that job done for you. I tossed a copy up on my server to show it in action.

http://www.cutcodedown.com/for_others/enormousRodent/template.html

… and that should work in everything all the way back to IE 5.0

Though even that’s nowhere near as bad as the “let’s slap position:absolute and position:fixed on everything” you’ll often see people trying.

ds60 did a pretty good job.

but the use of negative margins, floats, fixes for browsers other than ie (op) makes it look more like the work of a fireman than a developer :lol:

i mean, what’s the use of being a developer if you are not coding by clear rules but you are forced to improvise (wrong) solutions for all the wrong things browsers do, because you want things done in a particular way using particular techniques.

at the very least, the negative margins are a big question mark.

using floats it’s a question of taste, but floats are not meant to be used for this kind of job.

the fixes… well, these are not the developer’s fault, so, those i agree with. but i prefer CC for ie fixes :slight_smile:

I have to agree that there is nothing wrong with using negative margins (and indeed I wrote about this some years ago).

I think the misconception arose historically when some older browsers did not behave properly but that hasn’t been the case for many years now.

There is something wrong with using negative margins if you are applying them to every element just to make a horizontal layout as I have seen attempted in the forums :).

i, on the other hand (or not?), i have set the tab size at two spaces, with the “Replace by space” option checked, and i use the tab key to get that two-by-two spaces indentation.

have you tested the latest layout i’ve posted: #21 ?

I only use tabs, which I have set to display AS two spaces. Yours seems to just use spaces and not actual tab characters.

Ah, the joys of different editors in the mix too :wink:

the only tab i use is “two spaces”. your editor must interpret “four spaces” as a tab. slap him! :wink:

Odd, I thought you had something set on .pagesection – not seeing it now.

Hard to tell with the jumbled mess of all on one line CSS declarations and willy-nilly nonsensical indenting that switches between tabs and spaces almost at random.

NOT that any of those should be sharing values.

wow…thats amazing…would it be fairly trivial to turn that into a 100% height?

where did you see that? setting their background color IS the only thing (apart from inherited text align) i play them for.

It was more that you called how 99.99% of CSS layouts are built as a ‘hack’.

FLOATS FOR COLUMNS is not a hack, no matter how you color it – that’s part of what floats are FOR. The negative margins might seem hack-ish if you don’t understand margins or the relationship between flow and render – they’re not a hack either though if you read the specification. That statement ALONE should get you laughed clean off every internet development website in existance – it’s THAT incorrect! This is what they are for according to the CSS specification! You know – the rules that say HOW we’re supposed to do all this stuff?

Well, first you might want to add inline-block to that… get rid of all the redundant classes when you have perfectly good ID’s on everything, and lose the #header div that should probably be a h1. Likewise the unique ‘welcome’ ID seems pointless, and ‘page’ is just a little vague since every ‘page’ is a page. What is it DOING would be the question.

It also appears you fail to grasp how text-align works since that only effects the CONTENT of a div, not it’s core, so unless you are planning on putting inline-blocks inside your div… and of course you can’t set inline-block on DIV’s in IE. (under IE inline-block only works on inline-level elements, so unless you are planning on restricting yourself to the use of SPAN instead of DIV, H#, P and UL in the entire document…)

Also you’re stating widths that may or may not cover the white-space between the inline-elements being treated as a single space character.

Oh, and your width declarations would be ignord since display:inline elements can’t have widths or heights on them in anything other than IE. (and in standards mode the only reason in works is that it trips haslayout)

So really I don’t see how anything you have there could ever work in any browser. I think you have text-align confused with FLOAT.

Though it might actually work in IE 5.x - since it INCORRECTLY treats text-align in all sorts of weird ways, though again as a rule of thumb usually it only handles the CONTENT’s behavior, not itself… so targeting #nav1 as text-align:right isn’t going to move #nav1, only the stuff IN nav1.

Set ‘outline:1px solid #F00’ on .contentsection to see the problems

I don’t know where you got it in your head floats are a ‘hack’ or shouldn’t be used for building columns… much less that display:inline without a single inline-block or text-align is EVER going to do the job.

That’s not how CSS works.

MAYBE if you set inline-block on the three, got rid of the text aligns, it MIGHT line up in some and drop on others (like large fonts/120dpi) depending on the screen width. (since % width !== % character size). Part of why all three columns as percentage width is a miserable /FAIL/ at design that breaks 99% of the time people try and use it. (especially since you can’t declare % margins as % of width – that’s based on % of font size)

Much less you’re not going to get 100% min-height layout out of that… ever. That ALONE is enough to make me think you don’t know enough CSS to be saying much of anything on the subject.

I mentioned doing it without caring about source order… I think this is what you are THINKING on doing.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<title>
	Template Design CSS
</title>

<style type="text/css">

/* null margins and padding to give good cross-browser baseline */
html,body,address,blockquote,div,
form,fieldset,caption,
h1,h2,h3,h4,h5,h6,
hr,ul,li,ol,ul,
table,tr,td,th,p,img {
	margin:0;
	padding:0;
}

img,fieldset {
	border:none;
}

body {
	background:#ddd;
}

#nav1 {
	float:left;
	width:190px;
}

#nav2 { 
	float:right;
	width:190px;
}

#content {
	margin:0 200px;
	background:#DEF;
}

#footer { 
	clear:both;
	background:#FDE;
}
		
</style>

</head><body>

	<h1>Float Demo</h1>
	
	<div id="firstSideBar">
		a nav here<br \\>
		another line<br \\>
	</div>

	<div id="secondSideBar">
		another nav here
	</div>
	
	<div id="content">
		main content here
	</div>

	<div id="footer">
		footer
	</div>
	
</body></html>

It’s certainly simpler, it also puts content last, it also lacks the min-height code.

Kinda funny, your statements and code almost say “I learned CSS on Netscape 4” and never bothered to join us over the past decade.

Oh, I’m also trying to figure out what you are doing wasting your time setting inline and the span on the two elements that can remain block… #header and #footer. You shouldn’t even need to be playing with those apart from setting their background color… though that could just be a side effect of your slapping classes on everything for no good reason.

Oh, and it’s “* html”, not “*html”

ok.

my latest attempt.

i have removed al text alignment declarations. i’ve also put a test div inside inline-block div.

it appears whitespace appearing when making a block element inline-block was caused by the whitespace in the actual markup between the elements. so i made the ending tag for an inline-block be on the same line with the start tag for then next inline-block element, w/o any other whitespace in between.

i’ve tested it and it’s fine in ch6, ff3.6, saf5, op10.6, ie8. ie6-7 need a little more work, but for now i just don’t care about them.

here it is, tell me what you think. and be honest, don’t think about spearing me :wink:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en" dir="ltr"><head>

  <meta	http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta	http-equiv="Content-Language" content="en">

  <style type="text/css">
    
    /* 
     * one can put a css reset here
     * if indeed justifiable
     * but not just by habbit
    */    
 
    .page { background:#ddd; }
      
        .mainsection { display:inline-block; vertical-align:top; }
        
        /*
         * the following two ie fix/hacks could be 
         * place in a different css file, w/o the hacks,
         * and then make use of CC for IE 
         */
        *html .mainsection { display:inline; }
        *+html .mainsection { display:inline; }
            
        #header { background:#dfe; }
        #ms1, #ms3 { width:25&#37;; background:#fed; }
        #ms2 { width:50%; background:#def; }
        #ms1 div { width:100px; background:#dee; float:right; }
        #footer { background:#fde; }
    
  </style>

</head><body id="inlinetest" class="page">

    <div id="header" class="pagesection">
      <span>header div</span>
    </div>

    
    <div id="main" class="pagesection">
    
      <div id="ms1" class="mainsection">
        div displayed <br>inline-block
        <div>
          a floated div in<br>
          a inline-block div here<br>
        </div>
      </div><div id="ms2" class="mainsection">
        main div inline-block
      </div><div id="ms3" class="mainsection">
        another inline-block div
      </div>
      
    </div>

    
    <div id="footer" class="pagesection">
      <span>footer</span>
    </div>
  
</body></html>

the only problem is the one pixel gap that appears on the right when the browser widow is resized (the thing that doesn’t make sense :wink: ). i’m interested how it goes on your 120dpi. :slight_smile:

thank you…:slight_smile: i know im not doing much…but im learning…thx for the commented code :slight_smile:

You can’t actually reliably make the center column 100% height in these types of layouts without using a table (which is cheating/bad coding practice), though you can fake the appearance using images and an extra div.

I’m out for the next couple hours, but when I get back I’ll show you how that’s done. On a three column fluid layout it’s a wee bit trickier than others, but nothing too complex.

I actually found deathshadow60’s way pretty straightforward, nothing wrong there I.M.O.

About the 100% height for the content div. One of the ways I sometimes use, to give a div which I would like to have 100% height a large bottom padding and an equal negative bottom margin:


#content {
	margin:0 200px -1000px;
	padding:0 1em 1000px;
    background:#FFF;
}

For that to work you need to add overflow: hidden to your content wrapper:


#contentWrapper {
	width:100%;
	float:left;
       overflow: hidden;
}

maybe not everyone will agree with me in this but it works for me okay.