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 ;)
Kommentarer
Marius Vikene
13. desember, 09:00
Kudos for denne og forrige post om tabeller :)
Christian
13. desember, 10:16
Marius Vikene
13. desember, 12:49
Jeg har kikket litt mer på dette med tabeller, og ønsker nå å komme med en utfordring til deg.
I mange tilfeller kan det være ønskelig at kolonnene i tabellen er sorterbare, og dette kan løses med et javascript.
Utfordringen er å få til å lage en tabell hvor kolonnene er sorterbare men at også "sebrastripe"-scriptet ditt fungerer samtidig som man kan sortere.
hansken er kastet....
Christian
13. desember, 13:24