Menu
• Indhold

Fra tabel til div-baseret layout

Resumé

Af John R. Mirland, UNI-C
08/06 2003

Alle, der har arbejdet med udvikling af websites, har på et tidspunkt følt, at de var ved at drukne i table tags og manglende overblik. Ved at følge W3C's anbefaling om at layoute ved hjælp af stylesheets og div letter man arbejdet for sig selv, og vedligeholdet af et site gøres logisk og overskueligt.

 

CSS - adskillelse af indhold fra layout

Hele grundtanken omkring anvendelsen af CSS er at lave en konsekvent adskillelse af design og indhold. En traditionel webside er en sammenblanding af de to, hvor indholdet står i en table, og dens definitioner (bredde, højde, farve osv.) står angivet i selve html-dokumentet. Det betyder i praksis, at skal table have en anden farve eller lignende, skal man ind og rode i det enkelte dokument. Det er hverken overskueligt, praktisk eller smart.

 

Forskellen mellem table og div

Alle, der har lavet et website, har prøvet at skulle lave en table for at holde tingene på plads. Man laver en matrix og fylder cellerne ud - evt. med andre matrixer. Med table flytter man sig altid rundt imellem cellerne i de respektive rækker. Dette betyder i praksis, at skal man lave et design med elementer over hinanden, skal de reelt tastes ind som lå de ved siden af hinanden. På den måde bliver det hurtigt uoverskueligt. Man når meget hurtigt at have lavet tabeller indeni hinanden i 3-5 niveauer. Så er browseren meget langsom til at rendere siden (at regne ud hvordan siden skal sættes op), da den først henter sidens øvrige elementer, når table er renderet og på plads. Derudover skal man huske på, at table aldrig har været beregnet til layout, men til præsentation af struktureret data.

 

Et div tag er ikke noget i sig selv, andet end en container. En boks, der kan indeholde et eller flere elementer, f.eks. andre bokse. En div er rektangulær med fuldstændigt kontrollerbare dimensioner og placering. Med CSS har man kontrol over sin div langs X, Y og Z aksen. Det betyder, at en div kan ligge henover en anden div osv. Browseren renderer div langt hurtigere end table uanset antallet af nestede elementer. Ved at anvende div fornuftigt kommer ens dokument til at få en struktur, der 100% afspejler de logiske sammenhænge i det renderede site. Det kaldes semantisk korrekt.

Om Forskellen mellem table og div

Nyhedsbrev

Tilmeld dig til IT-temaets nyhedsbrev



 

Artikler af

John R. Mirland
 (11/07 2007)

 

Semantik

I Fremmedordbogen defineres semantik som: Studiet af forholdet mellem tegn og betegnede genstande. Det kan også oversættes som forholdet mellem det, der står i koden, og det man ser. I det tabel-baserede site er det praktisk umuligt at finde ud af et sites informationsarkitektur ved blot at se på koden. Med et korrekt defineret div-baseret site er sammenhængen logisk og gennemskuelig, da sammenhængen mellem elementer og den logiske informationsarkitektur afspejles direkte i koden.

 

Designet

Eksempelsitet her er et typisk site uden de store falbelader. Det har et toplogo, hvor et evt. firma- eller institutionsnavnetræk typisk ville blive placeret. Derudover har det en venstremenu og en asymmetrisk inddelt højredel med én eller to spalter til præsentation af selve indholdet. I bunden er der afsat plads til en såkaldt footer.

 

Stylesheetet - bid for bid

For at forstå de enkelte dele af et grundlæggende site designet med div og CSS (stylesheetet kan ses her), gennemgås det her i detaljer. Dog vil jeg undlade styledefinitioner, der ikke behøver yderligere forklaring:

Body

body {
width:100%;
height:100%;
margin:0px;
background:#ffffff;
color:#000000;
font-family:arial,sans-serif;
font-size:11px
}

For at kunne udnytte boksmodellen korrekt skal body-elementets højde og bredde angives til at være 100%. Ellers får man en regnefejl, når man senere vil lave et nestet element med en 100% højde. Ved at angive margin:0px begynder jeg med det samme at tage højde for Internet Explorers konsekvente fejlfortolkning af boksmodellen omkring margin og padding.

Div.site

div.site {
position:relative;
left:50%;
top:50%;
margin:-250px 0px 0px -385px;
width:770px;
height:500px;
background:#333333;
color:#000000;
border:1px solid black
}

For at få selve sitet til at centrere sig horisontalt og / eller vertikalt er jeg nødt til at lave en lidt halsbrækkende manøvre: Jeg angiver først, at sitet er en boks, der skal placere sig relativt i forhold til body. Derefter angiver jeg en placering, der er left: 50% og top: 50%. Jeg kunne også have angivet top: 10px, hvis jeg ønskede sitet kun skulle centrere horisontalt. Dette kan være nødvendigt i mange tilfælde, da det kun kan anbefales at centrere både vertikalt og horisontalt, såfremt sitet ikke er højere end den mindste forventede browserstørrelse. Hvorfor? Det kommer i de næste linjer af stylen:

margin:-250px 0px 0px -385px;
Her anvendes marginangivelserne ekstensivt. Jeg angiver først -250 px til top (i css shorthand, som dette css er skrevet i, læser man værdierne med uret). Derefter angiver jeg 0px til højre og bund. Til sidst angives -385 px til venstre. Det er 50% af sitets fulde bredde og højde. Dette sammen med min relative placering 50% til venstre og fra top, flytter sitets offset og får det til altid at være centreret horisontalt og vertikalt. Såfremt browservinduet var mindre end den angivne højde, ville sitet flytte sig uden for vinduet - uden mulighed for scrolling. Dette skal man overveje kraftigt, før man vælger at centrere sitet fuldt ud. Men man kan jo blot centrere det på én af lederne. Så angives blot den ene af marginerne som negativ værdi, og dens modsvarende 50% indrykning erstattes af X px.
width:770px;
height:500px;
Her står sitets fulde bredde. Vi ønsker et site, der kan være i et 800 x 600 px vindue inkl. scrollbars. Havde dets højde været angivet til at være "auto", ville sitets højde strække sig i forhold til indholdets dimensioner. Af hensyn til IE5 anvender man værdien auto, da IE5 ikke forstår height:X %, der ellers ville være en logisk måde at få indhold til at strække sig i forhold til kontekst og indhold. Værdien "auto" er faktisk browserens standardværdi, men det ved IE5 bare ikke. Ved at angive "auto" strækker browseren div'en, så den passer til indholdet. Nu kan jeg mase et X px højt element ind i div.site uden, at det ødelægger noget. Havde jeg ikke skullet tage hensyn til IE5, havde alle nestede højder været angivet til X %, da det vil være korrekt css: At et nestet element kan være X % af sin "parents" højde. I IE5 resulterer det imidlertid i, at det er 100% af selve browservinduet.
background:#333333;
color:#000000;
Jeg angiver her background til at være en mørk grå. Det er der for så vidt ikke noget i. Men den opmærksomme læser vil opdage, at jeg også angiver forgrundsfarve. Det burde jo ikke være nødvendigt, når jeg har angivet det i body-stylen. Det burde nedarves fra body til div.site. Det gør det også, men hvis man forsøger at validere hos w3c's validator service, vil stylesheetet ikke validere, medmindre både for- og baggrund er angivet. Man kan ikke angive den ene uden den anden. På den måde udhuler w3c deres egen anbefaling. Det betyder i praksis, at det ikke er det mest effektive css, der validerer. Man bryder hele css-idealet på denne måde. Så man må tage stilling til, hvad der er vigtigst: Et 100% validereret css, der ikke er effektivt eller et 100% effektivt css, der ikke validerer.

Div.header

div.header {
position:relative;
left:0px;
top:0px;
width:770px;
height:60px;
background:#ffffff;
color:#000000
} 
Der er ikke så meget at sige om div.header. Den er helt straightforward.

Div.indhold

div.indhold {
position:relative;
left:0px;
top:0px;
width:770px;
height:auto;
background:transparent;
color:#000000
}
Denne div er for så vidt en boks eller container ligesom div.site. Den skal indeholde selve sitets indhold, så det ikke sprænger de ønskede dimensioner. Ved at angive en indholds-container, kan jeg lave kortere og mere enkle styles indeni, da jeg på forhånd har defineret mit "område".

Ved at angive background:transparent benyttes den baggrund, jeg definerede i div.site.

Div.menu

div.menu {
float:left;
width:154px;
height:auto;
background:transparent;
color:#000000;
padding:0px 0px 0px 0px;
margin:0px;
} 
Ved div.menu indføres en ny værdi: float. Float definerer, hvor et element skal placere sig, og hvorledes de omkringliggende elementer skal opføre sig i forhold til det. Float:left betyder, at menuen klistrer sig op ad div.indholds venstrekant, samtidig med at alt efter div.menu vil ligge til højre, indtil andet er angivet. Værdierne for float er left, rightog none. Den sidste angivelse none anvendes til at ophæve et elements float og så at sige "starte forfra" i sidens flow (det samme kan opnås ved at anvende property'en clear ).  

Ul.menuNiv1, ul.menuNiv1 li

ul.menuNiv1 {
margin: 0px 0px 0px 0px;
padding: 10px 0px 0px 10px;
}
ul.menuNiv1 li {
list-style: none;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}

Det her er selve menuens 1. niveau. I stedet for at benytte en tabel, anvendes unordered list og list-item. På den måde får man foræret indrykninger og systematisering fra html-standarden. Man får en menu, der i sin konstruktion direkte afspejler sitets hierarkiske sammenhænge - også hvis stylesheetet skulle forsvinde, eller sitet skal vises i en ikke-css-kompatibel browser. Værdien list-style: none; fjerner den normale "bullet" foran listens punkter.

Ul.menuNiv2, ul.menuNiv2 li

ul.menuNiv2 {
margin:0px 0px 0px 0px;
padding: 0px 0px 15px 20px;
display:none
}
ul.menuNiv2 li {
list-style: none;
padding: 0px 0px 0px 0px;
margin:0px 0px 0px 0px;
font-weight:normal
}

Menuens 2. niveau. Den eneste forskel mellem 1. og 2. niveau er den større indrykning for at afspejle menuens interne hierarki. Derudover står der display:none. Dette er af hensyn til det javascript, der får menuen til at folde sig ind og ud ved at skifte style fra display:none til display:blockul.menuNiv2.

For at få menuen til at folde sig ind og ud anvendes der et simpelt javascript, der skifter style på ul.menuNiv2 fra display:none til display:block. Dette fungerer ikke i ældre browsere, men da de ikke ser stylesheetet, ser de heller ikke menuens andet niveau foldet ind. De gamle browsere ser altså hele menuen udfoldet.

Bemærk! Denne type menu egner sig bedst til tilfælde, hvor indholdet vises i en iframe.

Div.spalteHolder

div.spalteHolder {
float:right;
background:#eeeeee;
width:606px;
height:auto;
margin:0px;
padding:0px 0px 0px 10px
}

Som navnet div.spalteholder antyder holder denne div indholdsspalterne på plads på samme måde som div.indhold. Den har float:right og er angivet til width:606px. Den er reelt 616px bred, da padding:0px 0px 0px 10px skal lægges til. Padding fratrækkes den fulde værdi, da IE pga. en fejlfortolkning af CSS-boksmodel lægger padding'en til den angivne værdi.

Iframe.indholdsframe

iframe.indholdsframe {
padding:0px;
margin:0px;
width:606px;
height:440px;
}

Dette er værdierne for den iframe, som selve indholdet loades i. En iframe kan styles på samme måde som et hvilket som helst andet element.

Div.spaltedel …

div.spaltedel100 {
float:left;
width:100%;
height:auto;
text-align:justify;
background:#eeeeee 
}
div.spaltedel100 p {
float:left;
width:590px;
height:auto;
padding:5px 5px 5px 5px;
margin:0px; 
}
div.spaltedel75 {
float:left;
width:442px;
height:auto;
text-align:justify;
background:#eeeeee
}
div.spaltedel75 p {
float:left;
width:100%;
height:auto;
padding:0px 5px 10px 5px;
margin:0px;
background:#eeeeee 
}
div.spaltedel25 {
float:right;
width:25%;
height:auto;
background:#eeeeee;
}
div.spaltedel25 p {
float:left;
width:148px;
height:auto;
padding:0px 5px 10px 5px;
margin:0px;
text-align:justify;
background:#eeeeee
}

Som det ses, er disse classes kun forskellige i, hvilket float og hvilken bredde de har. Det er spalterne i indholdsdelen. Ved at angive dem således, fungerer de i forhold til deres kontekst. De lægger sig pænt ved siden af - og under hinanden - i præcis den ønskede rækkefølge. Der er ligeledes angivet, hvordan paragraffer skal fungere i forhold til deres omgivende div. Dette kan og bør man gøre for alle elementer i eksempelvis en given div og dermed gøre god brug af CSS' nedarvingsideal.

Hvis man regner efter, så går width og margin værdierne ikke helt op med 616 px, som er den samlede bredde. Det er pga. IE-browserens utallige problemer med boksmodellen, så der skal kompenseres - ofte med "skæve" værdier. Det er ofte noget, man må gøre på "øjemål".

Img.imgLeft, img.imgRight

img.imgLeft {
float:left;
margin:0px 10px 10px 0px;
border:1px solid #888888
}
img.imgRight {
float:right;
margin:0px 0px 10px 10px
}

Alle billeder indsættes med disse classes tilføjet. Dermed flyder teksten omkring billedet, og der holdes en pæn margin mellem tekst og billede. Man kan så selv vælge, om billedet skal være højre- eller venstrejusteret.

 

Hvad med de ældre browsere?

De ældre browsere (Netscape 4-generationen eksempelvis) kan ikke rendere stylesheets særligt godt, og det er meget tilfældigt, hvad de får ud af det. Derfor er CSS-baserede sites oftest nødt til at have parallelle versioner af hensyn til de gamle browsere. Ved at sætte "" omkring url'en til stylesheetet i dokumentets head-del kommer man uden om dette problem:

@import url ("ie5style.css");
De gamle browsere forstår simpelthen ikke, at det er en url og hopper over stylesheetet. Det betyder i praksis, at de kun "ser" selve indholdet. Fordi indholdet nu ligger i div, sker der ikke noget ved, at stylesheetet ikke er med. Den semantiske sammenhæng giver stadig mening. Brugeren får et visuelt "udesignet" site, men med en brugbar indholdsarkitektur.

 

...og de kommende browsere?

Netop det faktum, at vi nu har en total adskillelse mellem indhold og design gør, at vi til enhver tid vil kunne redesigne vores website uden, at det hele falder fra hinanden. Der er ingen tvivl om, at browserne kun kan blive bedre til at forstå CSS. De to førende browsere, IE og Netscape / Mozilla, forstår i dag omkring 90% af CSS 1 og omkring 20% af CSS 2. Det er meget begrænset, hvad de forstår af CSS 3, hvis overhovedet noget. Men når CSS 1 og 2 er fuldt understøttede om et par år, vil vi se stylesheets, der også tager sig af en del af det repetitive indhold, som f.eks. copyright-tekster ved billeder o.l. samt en langt bedre understøttelse af media-type.

Men som det er i dag, skal der stadig bruges en del energi på at omgå nye uforudsete og udokumenterede "features", hver gang der kommer en ny browser. Dette kombineret med W3C's ofte meget tvetydige og selvmodsigende anbefalinger gør, at effektivt CSS ikke blot er noget, der skrives ved at læse dokumentation og tro på browsernes evner. Det er det nok heller ikke i fremtiden.

 

Relevante links

  1. Lynkursus i Cascading Style Sheets (CSS) af John Mirland, UNI-C
  2. A List Apart indeholder en række artikler om webdesign, herunder en del om CSS.
  3. Meyer Web har et afsnit med links til andre gode CSS-kilder.
  4. Index DOT Css har bl.a. en god oversigt over CSS syntaks samt en oversigt over hvilke browsere, der understøtter hvad.