How to have the footer remain at the bottom of the page?

Dear All,
I have sample page below. My problem now how can I control the location of the <div id=“header”> and <div id=“footer”>. The problem each time my list of elements differ the footer location will be different and remain just below my submit button. So I want to fix it to a location to be at the bottom of the page but not influence by the amount of field I have in different forms. Any idea how to achieve that.


<html> 
<head> 
<link rel="stylesheet" type="text/css" href="my1.css" media="all">  
</head> 
<body> 

<div id="main" >
<div id=logo>
<table width=1000>
<tr>
<td width=300>
<img src="images/logo.jpg">
</td>
<td width=350 align=center>
	<label class=description for=element_1></label>  
</td>
<td width=350 align=right>
</td>	
</tr>
</table>
</div>

<div id="header"> 
<ul>
<li><a href="">Home</a></li>
<li><a href="">Solutions</a></li>
<li><a href="">Customer</a></li>
</ul>
</div> 

<div >
	<h2 class="form_desicription">Add Item(Draft)<?=$status?></h2>
</div>

<table> 
<tr>
<td valign="top">
	<table>
		
		<tr>
			<td>				
			  <label class=description for=element_1>Name<font color="red">*</font></label> 
			</td>
			<td>
			  <input class="text"  id="driverName" name="itemName" value=""> 
			  <script>document.getElementById('itemName').focus()</script>			  
			</td>
		</tr>
		
		<tr>
			<td>				
			  <label class="description">Date of Birth<font color="red">*</font></label>
			</td>
			<td>
			  <input class="text" id="itemDateOfBirth" name="itemDateOfBirth" value=""> 
			  <script>document.getElementById('itemDateOfBirth').focus()</script><label class="description">(DD/MM/YYYY)</label>		
			</td>
		</tr>	
			
		
				
		<tr>
			<td>				
			  <label class=description for=element_1>Tel No(Home)<span 
			  class=required id=required_1></span></label> 
			</td>
			<td>
			  <input class="element text medium" id="itemTelHome" name="itemTelHome" value=""> 
			  <script>document.getElementById('itemTelHome').focus()</script>			  
			</td>
		</tr>
		
		<tr>
			<td>				
			  <label class=description for=element_1>Tel No(Mobile)<span 
			  class=required id=required_1></span></label> 
			</td>
			<td>
			  <input class="element text medium" id="itemTelMobile" name="itemTelMobile" value=""> 
			  <script>document.getElementById('itemTelMobile').focus()</script>			  
			</td>
		</tr>
				
		
	</table>
</td>

	
</tr>


         
</table>

<div id="footer"> 
<ul>
<li><a href="">Main Page</a></li>
<li><a href="">Print Page</a></li>
<li><a href="">Log Out</a></li>
</ul>
</div> 

</div>

</body> 
</html>

having designed a lot of input forms in my time, starting from dos days, in order to ensure a safe way for the user to get correct processing results, the best way is to show less not more.

yes, you can cram all the info in one screen, but that will be tiring and overwhelming.

if scrolling is what scares you, you can make tabs or screens. it’s easier for the user to follow a vertical logic and it’s easier for him to overlook horizontally strung info.

trust me, less is more in this case.

in this case, to provide a better user experience, i would not resort to having 3cols. one column is more than enough to confuse the user, let alone three :slight_smile:

Not entirely sure I follow what you mean for the third columns content, though I’d probably just make it another inline-block or wrap a inline-block span around the input (since you can’t trust ‘width’ on input) and just put the third column element after.

On to the CSS.

First thing I do in every CSS file is a reset. As I already said the reset you were using, the so called “universal reset” of:

  • { margin:0; padding:0; }

Completely screws up form elements cross browser. Because all the browsers accept margins, borders, width and height DIFFERENTLY (UHG) your best bet is to leave them alone when it comes to padding.

The reset I use only turns off margins, paddings and borders on the elements that are inconsistent cross-browser. There are larger resets (like Eric Meyer’s reset reloaded) that frankly are too big for their own britches and border on being frameworks (and CSS frameworks defeat the point of using CSS) while smaller ones cause too many problems. I call this one the “mama bear” reset.

hr - As mentioned I hide all the HR for screen.

body - I set up my typical default font size for sans-serif fonts and fix the line-height to 140%. I like a taller line-height for legibility, and you can’t trust the default line-height to be the same across browsers anyways.

#pageWrapper – most of my layouts do a lot more with this element… here we’re just padding the bottom to make room for the fixed footer.

h1 – the position:relative and holly hack allow us to absolute position the span over the text as our ‘logo’. This is called ‘gilder levin image replacement’ and is an ideal technique fo having a proper structural h1 with text for the search engines and no-images users. I use a px font - which is usually bad accessibility - because we are interacting with a px height image. I avoid declaring a fixed height because of the old IE quirks box model and that frankly, it’s a waste of CSS too. 24px line-height + 8px top/bottom padding makes it 40px tall. Adjust to fit your image.

h1 span – the image replacement. I put a background color and opacity on it so you can see where it would end up… You’d want to strip the color and opacity when you put your logo image here as a background.

.menu – since both our footer and header menus are the same style, we use this one class. Turn off bullets, wrap floats, set up a fixed metric font since we need the fixed footer to have a fixed height. (thanks to Gecko for being a retard on what %/em means). From there it’s just colors. Again you’ll notice I avoid declaring heights here and let the flow handle that for me.

.menu li – setting this to display:inline avoids the “IE7 staircase bug” – unless you are going to add dropdown menus I really suggest NOT trying to do anything more with the LI.

.menu a – float 'em, pad 'em, style’em.

.menu a:psuedostates – Just added some hovers for fun.

#footer – I was going to add a expression to make ‘fixed’ work in IE6-, but frankly why bother at this point. It will just fall into place as if it was a normal element on the legacy browsers, so good enough. I’m retracting my previous statement and willing now to use position:fixed in designs where it can degrade gracefully like it is here.

#addDriver – I put the form last because it’s content. Stuff that’s common to every page, followed by stuff unique to each. The position:relative is so absolute children treat the upper corner of the form as 0:0, and the padding makes it pretty and makes room for the absolute positioned “legend span”

#addDriver legend span – speak of the devil. Move it, style it… Nothing fancy.

#addDriver label – Setting inline-block lets us put a width on these… poof, instant columns. You can even add text-align to push the text up against he inputs if desired. The two -moz declarations are for legacy gecko support (Firefox 2-) – a lot of your obscure *nix forks of FF and other gecko based browsers still need this to make it work… and it’s not like 60 bytes is going to kill us. I use a EM width since I’m using EM text, that way the layout doesn’t break on large font/120 dpi systems (like mine!). Amazingly a top margin will push both this and the inputs down giving us a nice spacing. I do margin top so the DIV for the ‘description’ is closer to the input.

#addDriver label span – your ‘required’ stars. Color 'em, done.

#addDriver fieldset input – by putting all our non-submit inputs in fieldsets we can target them without screwing with classes. I give them a nice big width and the font declaration makes sure they are using our desired fonts. (inputs do NOT usually inherit fonts).

#addDriver fieldset div – that little ‘description’ of the date format. Same margin as your label width, same width as our inputs, a bit of padding and text-align to make it pretty.

#addDriver .submitsAndHiddens – same total width as our inputs+labels (not exact, but close enough) padding and text align… Nothing fancy…

… and that’s it. How I’d handle that form and layout.

Hope this helps, and maybe you’ll be able to glean some useful bits from it.

You failed to close the first div’s tag… you also appear to be using tables for layout for no good reason, uppercase on values that aren’t supposed to have uppercase, missing double quotes in a strict doctype, a lack of proper form structure as you have no fieldsets and are using a h2 to do LEGEND’s job, using presentational classes, and are using the same ID’s more than once.

CSS is only as good as the markup it’s applied to, and you’ve got a LOT wrong in the markup.

I’d probably also NOT use position:fixed since it doesn’t work right cross-browser in most cases. I’d either use the overflow/100% height trick, or just live with a 100% min-height layout.

When I’m back at my workstation I’ll toss together an example of how I’d approach what you’re trying to do.

Dear Shadow,
First I have thank you a lot for so much time spend on for me really touched and appreciate. The main reason why I am using table was that some times the form will have 3 column where two columns is all text input and combo box etc. The reason is if I put all just on one column it will be too long for the user. Then the third column I put a datagrid of what what have been just added into the database. So what is the best design option? Thank you.

Do you have a full doctype otherwise IE will party like its 1999?

Without a doctype IE will go into quirks mode and not understand anything made in this century (I’m exaggerating a bit there but you get the picture).

The padding-bottom is required on whatever element is last in your page (apart from the fixed footer) because the fixed footer will occupy the bottom part of the viewport and if you have content behind it you won’t be able to see it. You need to add some padding-bottom to the last element on the page so that the padding matches the height of the footer and will allow you to scroll the content into view. Otherwise you will have content always hidden behind the footer.

-blink blink-

Wow… I’m glad Paul is here to the super obvious stuff that I completely overlooked. Thanks Paul. =p

Dear Samanime,
Below is 2 links for your view http://183.78.169.56/test/test1.html and http://183.78.169.56/test/test2.html. You will notice the bottom footer always appear just below the submit button. Thank you.

If you want a fixed position fetter then you would need to specify bottom :0;


#footer{
    position:fixed;
    bottom:0;
    left:0;
}

That means that it will always stick to the bottom of the viewport and that the rest of the layout will go underneath and you will need to add some padding bottom to the last piece of content so that it can scroll above the fixed positioned footer. (It won’t work in IE6 though as it doesn’t understand position:fixed)

If that isn’t working, it’s likely there is some other problem in your CSS.

Dear All,
I have tried the position:fixed still the same is sticking together the last form element. Any other I must do is it? Thank you.

With the position fixed the footer is fixed at the bottom of the viewport or whatever position you have declared for this fixed position and will not scroll along with the other content. I think the Sticky Footer would maybe be a better option.

Ok, let’s review the markup I posted above.

Starting out I use XHTML Strict – I just like it for the better syntax rules. Big deal, no real difference. I always start with this basic header on every page I write since it’s a nice clean baseline that includes all the values you should always have on the page like language encodings, etc.

You’ll notice that I use a meaningful name for the stylesheet (screen.css) and use targeted media types. For screen layouts rarely print well, so I usually either like to print with no extra styling/presentation, or customize specifically for print. (doing things like removing menus – why waste the visitor’s ink?). Targeting your screen layout for ‘all’ is most always a disaster, so I wouldn’t use it.

You’ll notice my strict formatting – I just like to keep it clean and clear.

Moving on to the contents of the body, first I have a pageWrapper. If I were to make it fixed width or semi-fluid this container makes a nice hook, as it does for 100% min-height layouts – but for what we’re doing here I just pad the bottom of it to make room for the fixed footer.

You’ll notice I got rid of the logo div and pointless table. I’m not sure exactly what your final page is doing there, but I’m pretty sure whatever it is probably shouldn’t need the extra DIV or the table. Using this as the site H1 with an image replacement technique also keeps the document structure working how it’s supposed to work.

You can also see I took an axe to the wrapping DIV on the menu. It too served no real purpose as there’s nothing you were doing you couldn’t apply directly to the UL. I used a class here so we can share the same styling on the footer menu with minimum hassles.

Horizontal rules in my markup are there for print and CSS off. We’ll hide those using the screen.css

Now, I got rid of the h2 since that should likely have been the LEGEND for the form… The FORM I use to apply the styling since all those inputs and labels, well… should be in the form. No double nesting table nonsense, throws away a bunch of pointless markup.

Inside the legend you can see I have a span, this span is so that I can absolute position the contents of the LEGEND. We want LEGEND for semantic and accessibility reasons, but it’s NOT the most predictable element cross-browser. It sucks to do this, but your best bet with them is to pad the top of the form or fieldset then absolute position the text in that padding. It’s ugly, but it works and preserves semantics.

You’ll notice I have a fieldset – which I like to use around fields the user fills out… Down below that you’ll notice the submit and reset is in a DIV… I don’t consider those fields so usually I put those along with any hiddens in a div. It also makes it easier to target for different styling from the fieldsets.

For the fields we have just the label, the input, and a break. The equal width formatting we can handle in the CSS.

Since the only reason to have spans inside the labels is the ‘required’ star, we really don’t need classes on that either since we can target that in the CSS by it’s inheritance – “#addDriver label span”

I fixed all the ‘for’ to actually point at the correct ID’s, and a number of ID’s came out of the markup.

Because FF ignores width on input[file] I use the size attribute which it does obey. It’s not exact, never will be… You can thank the W3C for being absurdly vague on how or even if form elements should recieve styling for this particular headache. Whenever they don’t say, the browser makers all just go their own directions leaving us developers all to sit there scratching our heads. You WILL NOT be able to get these to appear consistently cross-browser, it’s just one of the things we have to learn to live with.

Close the form, close the pagewrapper, and the footer didn’t get any real changes from your example.

Alright, I’ll stop here and post this. Next post will be the CSS breakdown.

… and here’s the CSS I would use:
http://www.cutcodedown.com/for_others/newToMySQL/screen.css

Which I put a live demo of here:
http://www.cutcodedown.com/for_others/newToMySQL/template.html

Valid XHTML 1.0 Strict, would be valid CSS 2.1 if not for the use of -moz for inline block (big deal), tested working 100% IE7, 8 and 9, Opera 10.63, Firefox 2 and 3, and the latest flavors each of Safari and Chrome… The position:fixed is ignored in IE6 or lower, but the everything else works all the way back to IE 5.01

I’ll write up a line-by-line breakdown to explain who/what/why so hopefully you can learn from it.

Ok, looking deeper at it, I can see why you might be having alignment issues and cross browser problems – you’re using the universal reset ( * { margin:0; padding:0; } ) which completely SHTUPS form elements. It’s why if you are going to use a reset I advocate using a targeted reset instead.

First order of business is cleaning up the 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>
	Add Driver - Site Title
</title>

</head><body>

<div id="pageWrapper">
	<h1>
		Site Title
		<span><!-- image replacement --></span>
	</h1>

	<ul class="menu">
		<li><a href="">Home</a></li>
		<li><a href="">Solutions</a></li>
		<li><a href="">Customer</a></li>
	</ul>

	<hr />

	<form action="#" method="post" id="addDriver">
		<fieldset>
			<legend><span>Add Driver(Draft)</span></legend>

			<label for="driverName">Name<span>*</span></label>
			<input
				id="driverName"
				name="driverName"
				value=""
			/><br />

			<label for="driverDateOfBirth">Date of Birth<span>*</span></label>
			<input
				id="driverDateOfBirth"
				name="driverDateOfBirth" value=""
			/><br />
			<div>(DD/MM/YYYY)</div>

			<label for="driverICImage">IC Image</label>
			<input
				type="file"
				name="driverICImage"
				id="driverICImage"
			/><br />

			<label for="driverTelHome">Tel No(Home)</label>
			<input
				id="driverTelHome"
				name="driverTelHome"
				value=""
			/><br />

			<label for="driverTelMobile">Tel No(Mobile)</label>
			<input
				id="driverTelMobile"
				name="driverTelMobile"
				value=""
			/><br />

		</fieldset>

		<div class="submitsAndHiddens">
			<input
				type="submit"
				value="submit"
			/>
			<input
				type="reset"
				value="Reset"
			/>
		</div>

	</form>

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

<hr />

<div id="footer">
	<ul class="menu">
		<li><a href="">Main Page</a></li>
		<li><a href="">Print Page</a></li>
		<li><a href="">Log Out</a></li>
	</ul>
</div>

</body></html>

That’s a PROPER form. Fieldset around the inputs, no extra/wasteful markup like that table for nothing, etc. The #pageWrapper div also makes it easy to make sure that the footer doesn’t ride over the content. Throws away about a third of your markup while at the same time adding some bits you really should have.

Gimme like five minutes and I’ll toss together working CSS for that.

Oh, as to the calibri font issue… type=“file” is well known for ignoring font declarations in Firefox and IE… just like it also ignores trying to set a width on it with javascript.

Dear Noon,
Why I resort to 3 column is because the user wants it that way if the form is too length with many input to be done. So they dont want to keep scrolling up and down. Well you know different users have different taste.

i’d be happy too :slight_smile:

the basic concept behind it is the use of anchors paired up with other elements’ id attribute.

it can be done only by css or combined with js also.

i’m a at work now, but in a few hours i will use your page http://183.78.169.56/test/addClient.php and make an example with tabs.

Dear Paul,
I got one more problem here is that when I run http://183.78.169.56/test/test2.html on firefox for the image file uploading the text is not calibri but in IE it works fine. What else must I adjust into my .css? Thank you.