Anders är en webbutvecklare och hårdrockare som gillar brädspel, kaffe och öl.

Detta är ett arkiverat inlägg, som importerats hit för referens. Det kan se konstigt ut och innehålla utdaterad information eller inaktuella åsikter.

Vertikal centrering med CSS

Innan CSS blev rekommendation fanns bara presentationsuppmärkning i HTML att använda sig av för att göra alla formgivare och kunder nöjda. Utav alla lösningar som fanns var tabeller den allra kraftfullaste. Knepen för design var fantasifulla, men numera har alla gränssnittsutvecklare med litet värdighet i kroppen övergett dessa för att övergå till lösningar som bygger på webbstandarder.

De flesta saknar inte tabellbaserade layouter, eftersom CSS ger möjligheter att ha snygg och ren uppmärkning utan att inverka på presentationen. Men det finns likväl vissa CSS-implementationer som alla, till och med religiösa webbstandardsadvokater, sliter sitt hår för som på tabellernas era var lätt som en plätt att implementera. En av dessa är att vertikalt centrera blockelement i förhållande till närliggande blockelement.

Vertikal centrering, med tabeller

  1. ``

  2. Statement:

  3. I am vertically centered!

  4. ::: {.p_embed .p_image_embed} :::

  5. ``

+-----------------------------------+-----------------------------------+ | Statement: | ::: {.p_embed .p_image_embed} | | | ::: | | I am vertically centered! | | | ------------------------- | | +-----------------------------------+-----------------------------------+

Rättframt och effektivt. Detta saknar helt motstycke i CSS.

Vad som ställer till det

  • Okänd höjd på block. I regel finns det alltid en statisk bredd på en sida, satt i pixlar, em eller procent. Det är naturligt att göra så, och det visste man när CSS implementerades. Detsamma går inte att säga om höjd, eftersom innehåll nästan alltid består av löpande text som skall kunna förstoras och förminskas, eller radbrytas beroende på webbläsarfönstrets dimensioner.
  • Ingen kontroll på blockhöjder på CSS-nivå. Att centrera horisontellt kan göras smart via automarginaler och text-align: center; i en handvändning. Sådana snabba lösningar saknas helt i CSS när det kommer till att göra detsamma vertikalt.
  • Dåligt webbläsarstöd för CSS. CSS2 innehåller några egenskaper för display som skulle kunna lösa problemet: table, table-cell, table-row och möjligtvis också inline-block. Dessvärre lämnar webbläsarstödet mycket att önska. Det som rör tabeller stöds inte av Internet Explorer, och inline-block stöds inte av Firefox (2.0.11).

Låt oss bestämma vad som definierar en godtycklig lösning för vertikal centrering.

  • Lösningen skall baseras på webbstandarder och vara semantiskt korrekt, med nödvändiga kompromisser. (tabeller uträknade!)
  • CSS och HTML skall validera.
  • Fungerar i alla moderna webbläsare, samt de populäraste. (Internet Explorer)
  • Oberoende av dimensioner; centreringen skall fungera utan exempelvis height: 250px;.
  • Conditional Comments skall inte användas (krav från min arbetsgivare).

Hur har andra löst det då?

Roger Johansson har ett fungerande exempel i sitt labb på 456 Berea Street: Equal height boxes with CSS, part II. Denna demonstrerar hur det skulle kunna lösas i en värld utan Internet Explorer. Med andra ord är vi långt ifrån klara i det här skedet.

Trenton Moss är en av flera som valt att lösa det via line-height:

Specify the line height to be the same as the height of the box itself in the CSS. In this instance, the box is 2em high, so we would insert line-height: 2em into the CSS rule and the text now floats in the middle of the box - perfect!

Detta skapar en vertikal centrering i alla webbläsare, men fungerar enbart för enstaka element. Endast en rubrik, endast ett stycke, och så vidare. Det förutsätter också att vi bestämmer höjden, vilket inte är acceptabelt.

Våra alternativ börjar reduceras. Google hittar inte något åt oss till en början, men efter att ha vaskat ordentligt får vi fram Jak psát web: CSS vertical center solution. Denna lösning närmar sig den vi är ute efter, då Jak insett att höjden inte bör sättas. Lösningen implementerar detsamma som Roger Johansson, och kompletterar med fix för Internet Explorer som dessutom validerar. Lösningen använder sig av en wrapper och två inre div:ar, vilket känns som en godtaglig kompromiss.

Ljuset av tunneln

Lysande. Men förbättringar kan fortfarande göras. Lösningen är oberoende av höjden på det inre innehållet, men wrappern behöver fortfarande en fast höjd för att lösningen skall fungera i Internet Explorer. Dessutom fungerar inte fixet i IE7. Jag tog mig därför friheten att komplettera med det sista som behövs.

Jag slutade med en fungerande vertikal centrering, oberoende av höjd. Ett fungerande exempel finns i mitt labb. Använd koden för all del, men glöm inte vem som gav er den. :)

Att hitta IE7-filtret var för övrigt inte lätt. Sedan IE7 fixade fullt stöd för CSS2.1 selektorer är det fruktansvärt svårt att komma runt IE7 utan Conditional Comments. Det här filtret är det enda jag hittade som både validerar och sorterar ut CSS till enbart moderna webbläsare. Jag rekommenderar alla starkt att att använda Conditional Comments istället för att hacka sig runt, då IE8 högst troligtvis har gjort något åt buggen som skapar möjligheter för filtret. Conditional Comments är det enda rätta.

Testad i följande webbläsare: : Firefox 2 : Internet Explorer 6 : Internet Explorer 7 : Opera 9 : Safari 3

Viktigt: Opera placerar den flytande bilden i exempel 1 litet konstigt. IE7 placerar inte heller det centrerade innehållet exakt i mitten i samma exempel. Båda problemen försvinner dock om en bredd anges.