Hopp til innholdet

cjohansen.no

Semantiske tabeller

Tabeller har fått et noe frynsete rykte etter å ha blitt misbrukt som layout-kontroll i årevis. Desverre har enkelte blitt så redde for tabeller at de unngår tabeller for enhver pris. Tabeller har absolutt sin plass i HTML enda, og passer perfekt til tabulær data. 14 timers reise og 9 timer tidsforskjell for ta støyten for at dette kommer noe seint.

Aktuelle elementer

Når vi koder tabeller er det et mangfold av elementer å forsyne seg av; <table>, <thead>, <tbody>, <tr>, <th>, <td>, <caption>, <colgroup>, <col>. Vi skal se på de fleste av disse i detalj nedover.

Hva er tabulær data?

Jeg begynte med å si at tabeller ikke er en akseptert måte å gjøre layout på, men at de passer kjempefint til "tabulær data". Men hva er egentlig det? Tabulær data er data som kan grupperes under noen merkelapper i rader og kolonner. På ethvert punkt i tabellen vil data i en celle ha et forhold til merkelappen på toppen av inneværende kolonne og annen data på samme rad. Data som er naturlig å notere i et regneark eller en database-tabell er tabulær data.

En enkel tabell

La oss begynne med en ganske enkel tabell som viser en oversikt over mennesker og hvor mye penger de har spilt bort og vunnet i poker (jeg er tross alt i Vegas mens dette skrives).

<table>
    <tr>
        <td>Person</td>
        <td>Innsats</td>
        <td>Antall spill</td>
        <td>Gevinst</td>
    </tr>
    <tr>
        <td>Arne</td>
        <td>10.000,-</td>
        <td>6</td>
        <td>0,-</td>
    </tr>
    <tr>
        <td>Ingrid</td>
        <td>5.000,-
        <td>12</td>
        <td>1.500,-</td>
    </tr>
    <tr>
        <td>Ivar</td>
        <td>5.000,-</td>
        <td>12</td>
        <td>15.000,-</td>
    </tr>
    <tr>
        <td>Anne</td>
        <td>1.500,-</td>
        <td>7</td>
        <td>0,-</td>
    </tr>
</table>

Dette er en tabell i sin enkleste form. Foreløpig gir den veldig lite ekstra informasjon - både visuelt og strukturelt - om hva som er hva. Hva er headingene i denne tabellen? Hva handler den om? Hvordan henger data sammen?

Headinger

Ved å bytte ut td-taggene (som markerer tabell-data) i den første raden med th-tagger (som markerer tabell-headinger) får vi strukturert informasjon om headingene:

<tr>
    <th>Person</th>
    <th>Innsats</th>
    <th>Antall spill</th>
    <th>Gevinst</th>
</tr>

Dette er et skritt i riktig retning, og kan være passende for mange små tabeller. Hvis vi derimot ser for oss at tabellen etterhvert vil få mange rader bør vi dele opp tabellen bedre.

Mer struktur på headinger med <thead>

Ved å bruke <thead> rundt headingen og <tbody> til å gruppere selve dataene i tabellen gir vi enda mer strukturert informasjon om dataene våre. HTML-spesifikasjonen for tabeller foreslår for eksempel at headingen i <thead> kan repeteres på alle sider i tilfeller hvor utskrift av en tabell strekker seg over flere sider.

<table>
    <thead>
        <tr>
            <th>Person</th>
            <th>Innsats</th>
            <th>Antall spill</th>
            <th>Gevinst</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Arne</td>
            <td>10.000,-</td>
            <td>6</td>
            <td>0,-</td>
        </tr>
        ...
    </tbody>
</table>

Kortere headinger for hyppig repetisjon

Når tabeller leses opp av skjermlesere kan skjermleseren med vår strukturerte tabell velge å lese kolonne-labelen til hver datacelle i tabellen. Altså: "Person: Arne, innsats: 10.000, antall spill: 6, gevinst: 0". I slike tilfeller vil brukeren sette pris på at headingene er så korte som overhodet mulig mens de fortsatt forstår innholdet. I stedet for å kutte headingene våre helt i filler kan vi bruke abbr-attributtet. Dette attributtet tillater oss å gi en kortversjon av headingen som for eksempel kan brukes av skjermlesere:

<thead>
    <tr>
        <th>Person</th>
        <th>Innsats</th>
        <th abbr="Spill">Antall spill</th>
        <th>Gevinst</th>
    </tr>
</thead>

Eksempelet mitt er ikke det beste for å illustrere nytten av dette attributtet, men tenk deg en heading som Google Analytics' "Oversikt over besøkende". "Besøkende" er langt mer behagelig å få lest opp mange ganger.

Horisontale merkelapper

Det siste jeg skal si om headinger er headinger i <tbody>. Noen ganger kan det være interessant å ha subheadinger, for eksempel som gjelder for inneværende rad. Til dette formålet kan vi bruke <th> som tidligere, men i tillegg kan vi angi retning med scope-attributtet. Scope sier noe om hva headingen gjelder for, og mulige verdier er "col", "row", "colgroup" og "rowgroup".

col er det vi vanligvis mener, og angir altså inneværende kolonne. Dette er verdien vi antar for <th> på toppen av tabellen. row er for en gitt rad, mens rowgroup gjelder for <thead>, <tbody> og <tfoot> og colgroup gjelder for <colgroup> og <col> som vi ser på litt senere.

<table>
    <thead>
        <tr>
            <th scope="col">Person</th>
            <th scope="col">Innsats</th>
            <th scope="col" abbr="Spill">Antall spill</th>
            <th scope="col">Gevinst</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Arne</th>
            <td>10.000,-</td>
            <td>6</td>
            <td>0,-</td>
        </tr>
        ...
    </tbody>
</table>

Her kunne jeg også ha brukt <td> med scope-attributtet i <tbody>. Spesifikasjonen sier ikke noe om eventuelle standardverdier av scope (som naturlig ville være "col"), men i enkle tabelleksempler skipper W3C også dette attributtet.

headers-attributtet

En annen måte å gi knytning mellom headinger og data i tabellen er headers-attributtet. Med dette attributtet setter man id på alle headingene, for så å referere til disse i headers-attributtet på tabellcellene. Dette er spesielt nyttig når headingene ikke er plassert på en så rett frem måte som i mitt eksempel. headers fyller forøvrig det samme formålet som scope, så å bruke begge er overflødig.

For å bedre illustrere nytten av dette attributtet har jeg utvidet tabellen vår med en ekstra dimensjon. Antall spill er nå delt opp i Poker og Black Jack:

<table>
    <thead>
        <tr>
            <th id="person" rowspan="2">Person</th>
            <th id="innsats" rowspan="2">Innsats</th>
            <th abbr="Spill" id="antall" colspan="2">Antall spill</th>
            <th id="gevinst" rowspan="2">Gevinst</th>
        </tr>
        <tr>
            <th id="poker" headers="antall">Poker</th>
            <th id="blackjack" headers="antall">Black Jack</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th id="arne" headers="person">Arne</th>
            <td headers="innsats arne">10.000,-</td>
            <td headers="antall poker arne">3</td>
            <td headers="antall blackjack arne">3</td>
            <td headers="gevinst arne">0,-</td>
        </tr>
        <tr>
            <th id="ingrid" headers="person">Ingrid</th>
            <td headers="innsats ingrid">5.000,-</td>
            <td headers="antall poker ingrid">8</td>
            <td headers="antall blackjack ingrid">4</td>
            <td headers="gevinst ingrid">1.500,-</td>
        </tr>
        ...
    </tbody>
</table>

axis

Det siste attributtet som bør diskuteres i denne sammenhengen er axis. axis er en vilkårlig merkelapp du kan sette på cellene for å knytte de til enda en dimensjon, for eksempel ved å kategorisere celler og labler rundtom i tabellen på samme måte. Dette attributtet er mest nyttig når du har flerdimensjonale tabeller som kanskje har mellomsummer eller lignende underveis.

(Opp)summmering av tabellen

Tilsvarende til <thead> finnes radgruppen <tfoot> som kan brukes til å samle summer eller annen konkluderende data i tabellen. Denne kan, som <thead>, vises på alle sider ved flersidig utskrift. Med disse radgruppene er det også mulig å scrolle <tbody> uavhengig av de andre gruppene for å passe på at brukeren alltid har headingene og summene tilgjengelig på skjermen sin.

Når du bruker <thead> og/eller <tfoot> er det viktig at disse kommer i riktig rekkefølge: <thead>, <tfoot>, SÅ <tbody>. Dersom du ikke bruker hverken <thead> eller <tfoot> er det ikke nødvendig å bruke <tbody>.

Sammendrag og overskrift

Som seende brukere har vi en unik mulighet til å danne oss en rask oversikt når vi ser tabeller, selvom de er veldig komplekse og inneholder data. Vi kan fort få følelsen av hva tabellen viser oss, uten at vi nødvendigvis får med oss detaljene. For en person uten syn, eller med dårlig syn, er dette så å si umulig med tabellen vår slik den står nå.

Attributtet summary er til for nettopp dette. Gjennom dette attributtet kan vi gi en kort og konsis forklaring som gir brukere uten syn den samme oversikten over hva som er i tabellen som seende har:

<table summary="Oversikt over personer som har spilt
                poker og blackjack, samt deres innsats,
                antall spill og gevinst">

<caption>

<caption> er en noe mykere variant av summary. Formålet med <caption> er å gi, sammen med headerne i tabellen, en rask oversikt over tabellens struktur. Den skal altså ikke trenge å stå alene og forklare tabellen fullt ut, slik summary gjør. Siden hverken summary eller <caption> er påkrevd anbefaler spesifikasjonen at summary særlig brukes i de tilfellene hvor <caption> ikke foreligger. En litt trist sak med <caption> er begrensede muligheter for styling, noe som ofte gjør det mer interessant og rett og slett heller bruke en heading-tag over tabellen istedet.

Når <caption> brukes skal det alltid kun være én av den, og denne skal stå direkte etter <table>-starttaggen. Når du skal skrive innholdet i dette elementet kan du tenke deg at tabellen skal inkluderes som en figur i et dokument, og teksten her er "bildeteksten" som vises til figuren.

<table summary="Oversikt over personer som har spilt poker
                og blackjack, samt deres innsats, antall spill
                og gevinst">
    <caption>Gambling blant personer</caption>
    <thead>
        ...
    </thead>
    <tbody>
        ...
    </tbody>
</table>

Andre ting

Jeg har ikke nevnt <colspan> og <col> i noen særlig grad. Disse kan brukes til å lage en struktur på kolonnene dine som gis aller først i tabellen. Det er ikke ofte disse gir noen praktisk gevinst, og med begrensede muligheter til å style ved hjelp av CSS er det heller ikke stor grunn til å ta de i bruk. Jeg har heller ikke sett de ofte brukt.

Dette har vært - om ikke et fullstendig - så ihvertfall en relativt grundig gjennomgang av tabell-markup som er tilgjengelig idag. Har jeg glemt noen punkter? Hvilke biter av dette bruker du hyppigst?

Muligens relatert

2006 - 2012 Christian Johansen Creative Commons Lisens