Een flexibele layout van 3 kolommen.
Bron: http://www.sceneone.nl/tips_tricks/3_kolommen_layout.php
Titel: HTML en CSS tutorials
Auteur: Wybe Weysters
Alle tutorials op deze website gaan uit van het structureren van een html pagina zonder daarvoor
tabellen te gebruiken. En da's heel mooi, maar af en toe ook verrekte onhandig. Dat werken met die tabellen ging op sommige gebieden toch wel
erg lekker...........Nou ja, op het eerste gezicht in ieder geval.
Bijvoorbeeld als het ging om een flexibele opzet van je website in een aantal kolommen, of om het netjes onderaan de
pagina uitlijnen van een footer.
Flexibel....inderdaad en zelfs met een footer.
Nou, don't worry want al het bovenstaande is ook mogelijk met div's en met in acht neming van een scheiding van
structuur en presentatie. En dat is dus wat we nu gaan doen.
We gaan een pagina structuur opzetten met daarin een header, 3 kolommen waarvan de middelste felxibel is en last but
not least een footer die altijd onderaan je pagina uitlijnt. Het geheel zal altijd 100% van de breedte van de viewport in
beslag nemen.
Ik ga er in deze tutorial van uit dat je al enige ervaring hebt met de manier van werken die ik op deze website beschrijf. Als je dadelijk denkt, waar heeft die gozer het over, ik snap er helemaal niets van. Dan moet je misschien eens een kijkje bij het hoofdstuk over positionering gaan nemen.
Zo, enough allready. Aan de slag.
We beginnen op een punt wat je misschien niet direct als beginpunt zou herkennen: de positionering van de footer.
Als je wilt dat je footer altijd onderaan de pagina uitlijnt (ook als je weinig content hebt) dan moet je dat in de
basisstructuur van de pagina al vastleggen. Daarom beginnen we hier:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
min-height: 100%;
margin: -30px 0 0 0;
}
#footer_container{
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
HTML:
<div id="main_container"></div>
<div id="footer_container">footer</div>
Dat gaat makkelijk genoeg nietwaar. Je ziet dat de zwarte footer keurig onderaan de pagina uitlgelijnd is ook al is er geen content.
Als je nou denkt: "Man, ik zie helemaal niets. Ik zie helemaal geen zwarte footer!" Dan doe je het dus nog steeds
niet helemaal goed.
Je bent de pagina aan het bekijken in Internet Explorer 6. En IE6 begrijpt het bovenstaande niet.
Het minste wat je kunt doen is updaten naar IE 7, die begrijpt het wel, maar beter nog:
ga een behoorlijke browser gaan gebruiken!
Dat neemt niet weg dat we wel wat aan dat IE6 probleem (hij snapt min-height niet) moeten doen en dat doen we ook. Dadelijk.
Nu eerst even wat uitleg over wat hier gebeurt.
- Met de declaratie van 100% hoogte voor de body en html elementen vertellen we de browser dat hij altijd de volledige hoogte van de viewport moet benutten.
- Met de declaratie van de minimale hoogte van 100% voor main_container zeggen we dat die container altijd minimaal 100% hoog moet zijn. Dat is dus 100% van de viewport. Als de inhoud van deze container hoger wordt dan 100% van de viewport moet de container mee bewegen en dus hoger worden.
- Met de negatieve marge van 30px voor main_container maken we plaats voor de footer, main_container schuift namelijk 30px omhoog waardoor er aan de onderkant 30px vrijkomen.
- Als laatste declareren we de footer en deze maken we 30px hoog: height is 25px en top padding is 5px.
Op deze manier vullen main_container en footer bij elkaar opgeteld altijd minimaal 100% van de viewport.
Oh ja, IE6 nog.
Die begrijpt dus die min-height niet, die begrijpt alleen height. Dus we moeten apart voor IE6 nog een keer zeggen dat de height 100%
moet zijn. Andere browsers mogen dit niet zien want die zetten dan de height hard op 100% en wijken daar niet meer van af, ook
niet als de content hoger wordt dan die 100%.
Als het gaat om height en width hebben we een eenvoudig trucje om een declaratie alleen voor IE6 zichtbaar te maken. Namelijk zo:
_height: 100%;. Met die underscore ervoor laten andere browsers het links liggen en da's mooi. We krijgen nu dus dit:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
min-height: 100%;
_height: 100%;
margin: -30px 0 0 0;
}
#footer_container{
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
HTML:
<div id="main_container"></div>
<div id="footer_container">footer</div>
bekijk het resultaat (ook in IE6)
Voorwaarts!
De basis staat zullen we maar zeggen.
Nu de header erin:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
min-height: 100%;
_height: 100%;
margin: -30px 0 0 0;
}
#header_container{
width: 100%;
height: 75px;
padding: 30px 0 0 0;
background: #666;
color: #FFF;
text-align: center;
}
#footer_container{
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
HTML:
<div id="main_container">
<div id="header_container">header</div>
</div>
<div id="footer_container">footer</div>
Zoals je ziet komt de header_container box in de main_container te staan. Dat gaan we met alle elementen doen. Als dadelijk
content in de pagina wordt toegevoegd dan moet ook de content kunnen bepalen waar de footer komt te staan. Namelijk als de
content langer wordt dan de hoogte van de viewport, dan moet dus die footer mee naar beneden bewegen.
Dat lukt alleen als de main_container box ook 'mee groeit' met de content. Vandaar dat alles in main_container komt, behalve de footer
zelf natuurlijk.
Die main_container had een top marge van -30px. Om er nu voor te zorgen dat de content van de header_container binnen de viewport
valt geef ik die header weer een top padding van 30px. Die twee waarden van 30px heffen elkaar op.
Verder gebeuren er weinig spannende dingen en kunnen we door met de kolommen.
Eerst de linker en rechter kolom. Die twee gaan we floaten:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
float: left;
width: 100%;
min-height: 100%;
_height: 100%;
margin: -30px 0 0 0;
}
#header_container{
width: 100%;
height: 75px;
padding: 30px 0 0 0;
background: #666;
color: #FFF;
text-align: center;
}
#links_container{
float: left;
width: 150px;
height: 200px;
background-color: #ECECEC;
}
#rechts_container{
float: right;
width: 250px;
height: 200px;
background-color: #ECECEC;
}
#footer_container{
clear: both;
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
HTML:
<div id="main_container">
<div id="header_container">header</div>
<div id="links_container">links</div>
<div id="rechts_container">rechts</div>
</div>
<div id="footer_container">footer</div>
Oke, dat begint ergens op te lijken.
Ik heb twee floatende boxen toegevoegd. Ik heb ze even een harde hoogte van 200px gegeven zodat je ze wat beter ziet. Die harde hoogte halen
we later weer weg
De oplettenden en wakkeren onder jullie hebben gezien dat met de introductie van die floatende elementen ook andere boxen een paar extra eigenschappen gekregen hebben:
- Ik heb aan de main_container box een eigenschap toegevoegd: 'float: left'. Zoals we al gezien hebben moet de content bepalend kunnen zijn voor de positie van de footer. Als we nu de main_container box willen laten 'mee groeien' met de twee floatende boxen dan moet main_container die twee floatende boxen wel herkennen. Dat doet main_container alleen als hij zelf ook float.
- Verder heb ik aan de main_container box een width van 100% gegeven. Het lijkt erop dat IE7 dit nodig heeft. Zonder die expliciete width gaat het in ieder geval fout.
- Ik heb aan de footer box de eigenschap 'clear: both;' gegeven. Op die manier behandelt de footer box de bovenliggende floatende elementen alsof ze onderdeel van de normale flow van de pagina zijn. De positie van de footer kan nu bepaald worden door de hoeveelheid content in een van de floatende elementen óf door de minimale hoogte van de main_container box (100% van de viewport).
Nu het midden gedeelte. Zeg maar het content gedeelte. Dat moet nu natuurlijk mooi tussen die twee floatende boxen invallen:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
float: left;
width: 100%;
min-height: 100%;
_height: 100%;
margin: -30px 0 0 0;
}
#header_container{
width: 100%;
height: 75px;
padding: 30px 0 0 0;
background: #666;
color: #FFF;
text-align: center;
}
#links_container{
float: left;
width: 150px;
height: 200px;
background-color: #ECECEC;
}
#content_container{
background-color: #999;
height: 200px;
margin: 0 250px 0 150px;
}
#rechts_container{
float: right;
width: 250px;
height: 200px;
background-color: #ECECEC;
}
#footer_container{
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
HTML:
<div id="main_container">
<div id="header_container">header</div>
<div id="links_container">links</div>
<div id="rechts_container">rechts</div>
<div id="content_container">content</div>
</div>
<div id="footer_container">footer</div>
Bijna..........
In feite zijn we er nu bijna. We hebben alles wat we willen hebben.
Ik wil alleen nog even controleren of die footer doet wat ik wil. Ik wil dat hij zichzelf aanpast aan de content van de langste
kolom. Het mag niet uitmaken welke kolom dat is, die footer moet meebewegen.
Ik weet nu al dat ik daar nog een paar dingen voor nodig heb:
- Ik moet die harde hoogte maten die ik aan de containers gegeven heb weghalen. Als zo'n container een hoogte van 200px heeft kan het wel zijn dat de inhoud meer is dan dat, maar die hoogte blijft gewoon hetzelfde: 200px. De inhoud loopt dan uit de box (in IE6 niet, maar en alle andere browsers wel).
- Daarnaast zal ik ervoor moeten zorgen dat die footer de floatende elementen herkend. Dat doe ik met eigenschap 'clear'. In dit geval 'clear: both'. Zowel de linker als de rechter box.
De uiteindelijke css wordt dus:
CSS:
body, html{
margin: 0;
height: 100%;
}
#main_container{
float: left;
width: 100%;
min-height: 100%;
_height: 100%;
margin: -30px 0 0 0;
}
#header_container{
width: 100%;
height: 75px;
padding: 30px 0 0 0;
background: #666;
color: #FFF;
text-align: center;
}
#links_container{
float: left;
width: 150px;
background-color: #ECECEC;
}
#content_container{
background-color: #999;
margin: 0 250px 0 150px;
}
#rechts_container{
float: right;
width: 250px;
background-color: #ECECEC;
}
#footer_container{
clear: both;
height: 25px;
padding: 5px 0 0 0;
background: #000;
width: 100%;
text-align: center;
color: #FFF;
}
De html blijft hetzelfde. Alleen voeg ik een hele lap lorum ipsum toe aan de linker kolom om te kijken wat er gebeurt.
Dus even testen.
Dat gaat goed. De footer doet wat ik wil. Je kunt het op dezelfde manier testen voor de andere kolommen.
Eén nadeel
Er zit wel een nadeel aan de bovenstaande methode. Misschien is 'nadeel' een groot woord, maar het zit mij in ieder geval
toch niet helemaal lekker. Het gaat om de volgorde van de boxen in de html. Die is niet logisch. Het zou logisch zijn als na de box
links_container de box content_container zou komen.
Het heeft weinig zin er al te lang bij stil te staan want er valt niets aan te doen. Vanwege die floatende boxen moet die
niet floatende box content_container als laatste komen. Evengoed toch jammer.......
Tot slot
Als laatste wil ik nog een aardigheidje aan deze tutorial toevoegen: de boel een beetje leuk opmaken.
Dan kan ik je mooi laten zien hoe je door middel van het slim gebruiken van de middelen die je hebt een heel eind komt met de
opmaak van je 3-koloms layout. We hebben daar wel nog wat extra zaken voor nodig.
Ik begin maar gewoon met de alle css en html die hiervoor nodig is. Dan leg ik daarna nog wel een paar opmerkelijke zaken uit.
Hier gaat ie:
CSS:
body, html{
margin: 0;
height: 100%;
}
body{
background: url(3_kolommen_layout/left_bg.gif) repeat-y 0 0;
}
#main_container{
float: left;
width: 100%;
min-height: 100%;
_height: 100%;
margin: -46px 0 0 0;
background: url(3_kolommen_layout/right_bg.gif) repeat-y top right;
}
/* container boxen */
#header_container{
width: 100%;
height: 81px;
padding: 46px 0 0 0;
text-align: center;
background: url(3_kolommen_layout/header_bg.gif) repeat-x 0 46px;
}
#links_container{
float: left;
min-height: 100%;
width: 164px;
}
#content_container{
margin: 0 259px 0 164px;
}
#rechts_container{
float: right;
width: 259px;
}
#footer_container{
clear: both;
height: 46px;
background: url(3_kolommen_layout/bottom_right.gif) no-repeat top right;
width: 100%;
text-align: center;
}
/* content boxen */
#header{
width: 100%;
height: 81px;
padding: 10px 0;
}
#rechts, #links, #content{
padding: 10px 10px 0 20px;
}
#footer{
padding: 20px 163px 0 0;
}
/* background image boxen */
#top_left{
position: absolute;
width: 163px;
height: 89px;
top: 0;
left: 0;
background: url(3_kolommen_layout/top_left.gif) no-repeat 0 0;
}
#top_right{
position: absolute;
width: 264px;
height: 89px;
top: 0;
right: 1px;
background: url(3_kolommen_layout/top_right.gif) no-repeat 0 0;
}
#footer_left{
height: 46px;
width: 163px;
float: left;
background: url(3_kolommen_layout/bottom_left.gif) no-repeat 0 0;
}
HTML:
<div id="main_container">
<div id="header_container">
<div id="header">header</div>
</div> <!-- sluit header_container -->
<div id="links_container">
<div id="links">links</div>
</div> <!-- sluit links_container -->
<div id="rechts_container">
<div id="rechts">rechts</div>
</div> <!-- sluit rechts_container -->
<div id="content_container">
<div id="content">content</div>
</div> <!-- sluit content_container -->
</div> <!-- sluit main_container -->
<div id="footer_container">
<div id="footer_left"></div>
<div id="footer">footer</div>
</div> <!-- sluit footer_container -->
<div id="top_left"></div>
<div id="top_right"></div>
Je ziet dat je op deze manier echt een 3-kolommen layout hebt, ook visueel. Ik laat het voor het grootste deel aan jou over om uit
te vogelen wat er in dit laatste voorbeeld allemaal gebeurd. Het is niet moeilijk, wel een precies werkje.
Er zijn een aantal absoluut gepositioneerde divs bij gekomen. Deze hebben we alleen nodig om een paar background images listig
te positioneren. Verder doen we er niets mee. Datzelfde geldt voor de box 'footer_left' in de footer container.
Verder zijn er in de container divs nog een aantal nieuwe divs geplaatst. Bijvoorbeeld de box 'links' in de box 'links_container'. Dat heb ik gedaan om bewegingsvrijheid te hebben met betrekking tot de inhoud. Je wilt dadelijk je teksten gaan positioneren. Dat ga je doen met margins en paddings. Als je dat direct in die container divs gaat doen heb je kans dat je de boel uit elkaar drukt. Op deze manier heb je wat meer speling.
Je ziet dat ik hier en daar wat margins/paddings en andere maten heb aangepast.
Dat is het volgens mij wel zo'n beetje.
Oh ja, ik heb hem getest in Firefox 2.0 (Windows), Opera 9.02 (Windows), Internet Explorer 6, Internet Explorer 7 en Safari.
Succes ermee!