Hopp til innholdet

cjohansen.no

Stiling med tabeller

Forrige uke avsluttet jeg med et lengre innlegg om tabeller. Når den semantiske HTML-en er på plass i bunnen er det rom for å relativt enkelt lage pene design med CSS.

Aktuelle elementer

Som i det opprinnelige tabell-innlegget er det alle elementer tilknyttet tabeller som er aktuelle: <table>, <thead>, <tbody>, <tr>, <th>, <td>, <caption>, <colgroup>, <col>.

For de utålmodige: ferdig stilet tabell. Denne siden inneholder alle tabellene fra det opprinnelige innlegget, samt CSS-en presentert i dette innlegget.

Stiling med CSS

Når vi tagger tabellene våre med såppass rik markup som vi endte opp med i det opprinnelige innlegget har vi et mangfold med kroker til stiling tilgjengelig. Dette er bra fordi vi slipper å klasse absolutt alle elementene for å oppnå ønsket visuell effekt. I mange virkelig-liv-situasjoner vil vi ha behov utover det den "rene HTML-en" gir oss, men en semantisk tabell er alltid et godt utgangspunkt for stiling.

Nå er ikke jeg noen designer, så noe fancy tabell-design skal jeg ikke legge meg ut på. Noe fantasiløst har jeg valgt å duplisere tabellen fra iTunes, til tross for at jeg ikke er Apple-fan på nivå med mange andre utviklere og web-folk. Tabellen har nok interessante detaljer til at vi kan lage et interessant eksempel.

Grunnoppsett

Tabellen vår skal ha rammer rundt alle celler. En grei måte å gjøre dette på er å ramme inn to sider av hver celle, eksempelvis venstre- og undersiden. For å dekke toppen og høyrekanten av tabellen må vi da legge en ramme på toppen og høyresiden av selve tabellen:

table {
    margin: 0 0 1em;
    border-collapse: collapse;
    border-right: 1px solid #555;
    border-bottom: 1px solid #555;
    font-family: verdana, arial, sans-serif;
    font-size: 11px;
}

I tillegg setter jeg fonten til å matche iTunes-tabellen. Merk min skamløse bruk av piksler her, noe jeg sannsynligvis ikke ville gjort i jobbsammenheng ettersom IE6 ikke skalerer piksel-fonter. Ellers er det verdt å merke seg border-collapse-settingen. Denne sier at rammene skal sammenfalle til en mellom cellene, ikke være adskilt slik de er når du tar en vanlig tabell og setter border="1".

Cellene

Neste skritt er å gi rammer og litt luft i cellene:

td, th {
    padding: 4px 6px;
    border-left: 1px solid #d9d9d9;
    border-top: 1px solid #d9d9d9;
    text-align: left;
}

Enter Javascript

Vi ønsker såkalt zebra-striping av radene slik det er i iTunes, og da har vi to reélle valg. Det ideélle valget er å bruke CSS3s nth-child-velger, men støtten for denne er så å si ikke-eksistere (såvidt jeg vet er det bare Safari og Konqueror og muligens Opera som støtter den). Dette ville sett ut som:

body tr:nth-child(odd) { background: #f1f5fa; }

Lekkert, men desverre ikke mulig enda. De to mulighetene våre dreier seg derfor begge om å sette class="alt" eller lignende på annenhver rad og bruke dette på samme måte som over. Den første varianten er å gjøre dette i HTML-fila, eller programmet som genererer denne - dette vil fungere for alle brukere - eller å gjøre det i Javascript. I de aller fleste tilfeller vil jeg anbefale å gjøre dette rett i HTML-en slik at det fungerer for alle.

Mitt eksempel bruker Javascript fordi koden min er håndskrevet og jeg er for lat til å manuelt vedlikeholde klassenavnene kun for eksempelets skyld. Scriptet henter alle tabeller, og sjekker om tabellen har tbody-element. Deretter looper scriptet alle radene i tabellen (eller tbody, alt ettersom) og setter class="alt" på annenhver rad. Merk at siden jeg vet at ingen av mine rader har andre klassenavn så settes className direkte uten å sjekke om det er en verdi der fra før. Dette er ikke å anbefale i "den virkelige verden".

for (var i = 0, table = null; (table = document.getElementsByTagName('table')[i]); i++) {
    var tbodies = table.getElementsByTagName('tbody');
    var tbody = tbodies.length > 0 ? tbodies[0] : table;

    for (var j = 0, row = null; (row = tbody.getElementsByTagName('tr')[j]); j++) {
        if (j % 2 == 0) {
            row.className = 'alt';
            console.log(row.className);
        }
    }
}

Med dette scriptet på plass kan vi stile annenhver rad med en lys blå bakgrunnsfarge:

tr.alt td, tr.alt th { background: #f1f5fa; }

Tall, headeren og fotlinja

Det er ganske vanlig å høyrejustere tall i tabeller. I dette tilfellet ønsker jeg derimot ikke å høyrejustere lablene/headingene, så jeg trenger å sikte inn kun elementene som inneholder tall. Vel, strukturen i tabellen min er med meg, og jeg noterer meg at alle tallene står i <td>-elementer i tbody eller tfoot:

tbody td, tfoot td { text-align: right; }

Videre ønsker jeg å ha en tyngre grå gradient i headeren og footeren for å ramme inn tabellen litt. Alle elementene jeg nå ønsker å fange inn står også i sin unike kontekst; det er enten <th>-elementer i <thead>, eller <th>- og <td>-elementer i <tfoot>. Gradienten er lagt inn som en bitteliten repeterende gif.

thead th, tfoot th, tfoot td {
    border-color: #555;
    border-bottom: 1px solid #555;
    background: url(thbg.gif) top left repeat-x #bbb;
    font-weight: bold;
}

th { border-left-color: #555; }

Den siste linja sørger for at jeg får den skarpe grå rammen rundt utsiden av tabellen. Siden alle cellene til venstre i tabellen er <th>-elementer kan jeg farge venstrerammen til å matche rammen som går på toppen og høyresiden av selve tabellelementet. I tillegg skal cellene i headeren ha den samme gråfargen på rammene mellom seg så jeg kan bruke en bred velger.

Det eneste som gjenstår er å stramme opp <caption> litt. Til mitt begrensede bruk her går det greit, men ofte vil nettleserbegrensningene lede deg bort fra å bruke <caption>.

caption {
    text-align: left;
    padding: 0 0 0.5em;
    font-size: 1.8em;
    font-family: arial, sans-serif;
}

Voila, det var det! Resultatet kan sees her.

Body-scrolling

Når vi deler tabellen opp i tre logiske deler; headeren, body og footer så kan vi også stile dem forskjellig. Dette har jeg jo illustrert ovenfor, men det er mer som kan gjøres. Ved å sette en fast høyde på body kan vi tvinge nettleseren til å scrolle denne (med overflow: scroll;) slik at headeren og footeren til enhver tid er synlige. Å gjøre dette kun med CSS er derimot ikke trivielt, så jeg overlater til Richard Cornfold og vise hvordan.

Hvorvidt scrollende tabell-bodyer er interessant er en annen diskusjon, ta den gjerne i kommentarene ;)

Muligens relatert

2006 - 2010 Christian Johansen Creative Commons Lisens