Hjem > CSS > CSS: Sådan laver du perfekt CSS

CSS: Sådan laver du perfekt CSS

Igennem mit arbejde og efter kraftig inspiration af Andy Clarke har jeg fundet den “perfekte” måde at lave CSS og markup på. I denne artikel vil jeg forsøge kun at koncentrerer mig omkring CSS delen og give dig opskriften, som tager udgangspunkt i solskinsdage. Til den dovne læser har jeg lavet et kort resume til sidst under hvert punkt.

0: Markup

Lav altid dit markup før du begynder at style. Sørg for at den er valid, og at den er semantisk opbygget. En god tommelfingerregel er, at ens markup skal give mening uden brug af CSS.

Resume: Markup før CSS!

1: Validering

Ligesom med dit markup skal dit CSS være valid. Hvis du er i tvivl, kan du validere dine stylesheets via W3’s CSS validator. Mange undervurderer vigtigheden af valid kode, så længe det bare ser ud, som det skal. Men ved ikke at have valid kode, kan man ikke være sikker på, at ens websider vil blive vist rigtigt i fremtiden, og at mindre og alternative fremvisere kan vise dit indhold. Hvis ingen fulgte en vis standard ville khaos regerer.

Resume: Lav valid kode!

2: Normalisering

Normaliserer altid dit stylesheet inden du går i gang. Forskellige browsere har forskellige default værdier til de forskellige elementer, hvorfor det til tider kan være umuligt at lave en side, der opfører sig ens cross-browser uden brug af reset. Hvor meget eller hvor lidt der skal resettes er en temperamentssag. Herunder er listet nogle eksempler:

  1. CSS Reset Reloaded by Eric Meyer
  2. Yahoo! UI Library: Reset CSS
  3. CSS Global Styles Reset by Kyle Neath

Være opmærksom på at det korte og brugte reset: * { margin: 0; padding: 0; } er et misforstået reset. Det er tungere at renderer (især med store websider), da det definerer regler for hvert enkelt element i ens dokument og nulstiller alt, hvorfor det ikke er anbefalingsværdigt.

Resume: Reset dit stylesheet før start!

3: Navngivning

Navngivning er utrolig vigtig og desværre også utrolig undervurderet. Uanset hvad du vælger så vær konsekvent. Hold dig evt. til engelsk, brug camelCaseMedLilleBegyndelsebogstav og giv strukturelle navne frem for præsentationsmæssige.
Et strukturalt navn beskriver, hvad det er for et element, du vil henvise til frem for et præsentationsmæssigt navn, som beskriver, hvor elementet befinder sig på siden eller hvordan det ser ud.

Præsentationsmæssige navne:

topNav, leftTopLogo, footer, leftContent, redBoldLink

Strukturelle navne:

primaryNav, branding, siteInfo, mainContent, externalLink

De præsentationsmæssige navne låser elementet fast, hvorfor de skal undgås. Hvad nu hvis din top menu (#topNav) pludselig skal ligge til venstre for dit indhold?

Resume: Vær konsekvent og brug camelCaseMedLilleBegyndelsebogstav samt strukturelle navne i din navngivning.

4: Struktur

Ens struktur kan virke utrolig ligegyldig og spild af tid hos mange, men er faktisk et af de vigtigste punkter i perfekt CSS. For din egen skyld, for kundens skyld og for fremtidige udvikleres skyld sørg for at have struktur i dit CSS. Som med navngivningen er det vigtigt at være konsekvent.

a) Inddel dit stylesheet i afsnit, fx via sektioner eller selectors.

/****** STRUCTURE  ******/
#branding, #primaryNav, #mainContent...
/****** HEADERS  ******/
h1, h2, h3 ...
/****** ANCHORS  ******/
a, a:hover ...
etc

b) Et element pr. linje.

#element 1 { egenskab 1, egenskab 2 ... egenskab n }
#element 2 { egenskab 1, egenskab 2 ... egenskab n }

Mange vil måske være uenige, og hælder til den mere fyldige og måske mere overskuelige-ved-første-blik-måde; en egenskab pr. linje:

#element 1 {
    egenskab 1;
    egenskab 2;
    ...
    egenskab n
}

Men her må jeg insister. Min erfaring er, at ved større projekter bliver stylesheets hurtigt store og uoverskuelige ved en egenskab pr. linje, også selvom man deler det op og har et stylesheet pr. side.

c) Undlad hierarkier i niveauer

Jeg har set folk anbefale, at man inddeler sit stylesheet i et niveau-hierarki, som afspejler sit markup:

div#element { egenskab 1, egenskab 2 ... egenskab n }
  ul { egenskab 1, egenskab 2 ... egenskab n }
    li { egenskab 1, egenskab 2 ... egenskab n }
      a { egenskab 1, egenskab 2 ... egenskab n }

Ideen er rigtig god, men forvirrer mere end den gavner. Desuden kræver det mere vedligeholdelse. Hver gang du ændre det mindste i dit markup, skal du ind og opdatere dit CSS, så de afspejler hinanden.

d) Opstil dine egenskaber i alfabetisk rækkefølge for at få et hurtigere overblik:

#element { float: left; height: 250px; width: 250px; }

e) Vis type på dit element (unikke), igen for overblikkets skyld:

div#element 1 { egenskab 1, egenskab 2 ... egenskab n }
ul#element 2 { egenskab 1, egenskab 2 ... egenskab n }

f) Kombinere elementer med samme regler. For at undgå redundans skal man samle elementer med samme egenskaber:

div#element 1, p#element 2 { egenskab 1, egenskab 2 ... egenskab n }

Resume: Vær struktureret og konsekvent. Inddel i afsnit, et element pr. linje, sortere egenskaber alfabetisk, illustrer type på dit element og kombinere elementer med samme egenskaber.

5: Shortcase

Brug shortcase. Du kan formindske din kode betydeligt og derved få et bedre overblik. Et eksempel illustrer guleroden meget bedre:

div#element 1 { margin-bottom: 15px; margin-left: 5px; ...
                ... margin-right: 20px; margin-top: 10px; }

bliver til

div#element 1 { margin: 10px 20px 15px 5px; }

Du kan bruge shortcase hos følgende egenskaber; background, border, font, list, margin, outline og padding. Dustin Diaz har skrevet en fremragende guide til emnet.

Resume: Brug shortcase!

6: Spring mellemledet over

Som i den virkelige verden er det oftest bedst for forbrugeren, at mellemledet bliver fjernet, og det er det også hos CSS. Mellemledet er ofte ubrugeligt og fylder kun ekstra i dit stylesheet, hvorfor det skal fjernes. Der findes dog situationer, hvor du kan blive tvungen til at inkluderer det men som udgangspunkt; fjern det:

div#element ul li a span.class

bliver til

.class eller div#element .class hvis man har behov for at specificere det lidt

Resume: Undgå unødvendige elementer hos en regel!

7: Flere stylesheets

Det kan være en god ide at have flere mindre stylesheets end kun et samlet, specielt når man udvikler. Udover at det giver et bedre overblik, kan man også undgå at skulle indlæse alle regler på sider, de ikke vedkommer, og have muligheden for at overskrive en regel, som ellers ville forstyrre ens underside eller kræve ekstra og unødvendig markup.
Nogle deler desuden deres stylesheets op i selectors, hvorfor de har et til headers, et til links, et til billeder etc. men det er en smule overkill og gavner ikke just overskueligheden. Desuden resulterer det i en masse ekstra http-requests og dermed længere load time, medmindre man samler og eventuelt minify‘er sit stylesheet, inden man skubber det live. Igen skal opdelingen kun ske, når det giver mening og eventuelt kun i udviklingsøjeblikket.
Ved større projekter har jeg et generelt stylesheet, hvor der defineres de generelle regler inklusiv reset, og så et pr. underside med de specifikke regler. Selvfølgelig alle i et strutureret stylesheet.

Resume: Adskil i flere stylesheets, men kun når det giver mening!

8: !Hacks

Hold dig fra at bruge hacks! Hvad enten det er * hack, _ hack eller lignende. Brug i stedet Conditional Comments til fx at indsætte et Internet Explorer 6 specifikt stylesheet.

<!--[if IE 6]>
<link type="text/css" href="ie6styling.css" rel="stylesheet">
<![endif]-->

Resume: Undgå hacks, brug conditional comments i stedet.

9: Adskillelse

Markup og CSS er som Batman og Robin. De er fantastiske sammen, dog kan Batman fint klare sig alene, hvorimod Robin er ubrugelig uden Batman.
Man må aldrig begynde at sammensmelte markup og CSS og lave noget så uhyggeligt som inline styling. For at sikre fleksibilitet og overblik er det vigtigt at alt styling adskilles fra markup og kun styres fra sit stylesheet. Der er dog situationer, hvor inline-styling kan være eneste løsning, men brug det kun som sidste udvej, og ikke fordi du er doven.

Resume: Markup og CSS skal adskilles!

10: Divitus, classitis og idikus

Undgå at få divitus, classitis eller idikus. Generelt for alle 3 sygdomme er, at man overforbruger. Man kan sammenligne det med et sønderjysk kaffebord, hvor der minimum er 14 forskellige kager, 7 bløde og 7 hårde, hvilket er helt unødvendigt. Derimod ville 1-2 kager fra hver kategori have været rigeligt.
Divitus er når man bruger for mange div‘er. Mange nybegynder har en tendens til at smide en div rundt om alt:

<div id="mainHeader"><h1>Min overskift</h1></div>

Div‘en er ikke nødvendig, og man kan i stedet skrive

<h1>Min overskrift</h1>

og så style på h1 i stedet for #mainHeader.
Classitis og idikus minder meget om divitus:

<ul id="unsortedList">
  <li class="listItem">Item 1</li>
  <li class="listItem">Item 2</li>
  <li class="listItem">Item 3</li>
</ul>

Det er ikke nødvendigt at overklistre alle selectors med klasser og id’er:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

Resume: Minimer dit markup!

11: Centrer med margin

Centrer med margin: 0 auto; i stedet for fx at hardkode en fast padding i venstre side. For at centrer med margin skal du definerer en bredde:

div#element { margin: 0 auto; width: 800px; }

Resume: Brug margin: 0 auto; til at centrer

12: Position og floats

Brug position og float rigtigt! Lær dem at kende, og brug dem når det passer ind. Lad være med at låse dig fast, hvor du kun bruger float eller position.

Resume: Brug position og float når det giver mening.

13: Vær doven

Sidste punkt som i øvrigt gælder programmering generelt er, at man skal være doven. Hvorfor opfinde den dybe tallerken igen og igen, når den nu er opfundet? Genbrug dine komponenter medmindre du ønsker eller mangler træning i at forstå eller lave dem.
Man støder på mange ens og lignende problemstillinger i CSS, hvorfor det vil være uhensigtsmæssigt, at skulle gennemtænke samt lave samme løsning gang på gang, og da man selvfølgelig har en strukturel navngivning, er det ikke noget problem at genbruge sin kode.

Resume: Genbrug dit veludviklet kode!

< SLUT / >

Det var mit bud på, hvordan man, ved hjælp af nogle simple principper, opnår bedre og mere overskueligt CSS. Vigtigst af alt er, at man er konsekvent hele vejen igennem og tro mod kode standarderne. Sammen kan vi gøre verden til et bedre sted. Kom gerne med en kommentar, hvad enten det er ris eller ros.

  1. 27 februar, 2010 på 19:32 | #1

    Nogle gode punkter du bringer på banen. Følger selv hovedparten af dem, men foretrækker dog at niveauinddele min CSS, så den afspejler mit HTML. Somregel skal man ikke ind at lave store ændringer i sit HTML, der bevirker, at man også skal ændrer meget i sit CSS. Eller jeg har i hvertfald ikke siddet med så store hjemmesider/projekter, hvor det har været direkte nødvendigt.

    Ellers har jeg også selv medbrangt mange af punkterne og flere i en serie på to blogindlæg omkring bedre struktur i HTML og CSS.

  2. 28 februar, 2010 på 11:06 | #2

    Hej Michael. Tak for din kommentar.
    Er glad for at du er meget enig, resten skal nok komme ;)

    Vedr. niveauinddeling i CSS synes jeg som sagt, at tanken er god, men vil stadig ikke anbefale det.
    Jeg ser følgende forhindringer:

    1) Hvis man som jeg vælger at inddele sit stylesheet i afsnit via selectors bliver niveauinddelingen allerede udelukket der :)
    2) Det kræver mere vedligeholdelse. Jeg vil gerne sætte vedligeholdelses områderne til et minimum. Min erfaring siger, at det er en god ide især ved store projekter, og når man arbejder mange om samme kode. En anden ting er, hvis man skal lave en prototype eller POC. Her kan man lige så godt lave det rigtigt fra starten af, og derved lave valid kode samt stille det ordentlig op, hvorfor man kan genbruge dele til det egentlige produkt. Her vil det give noget mere vedligeholdelse.
    3) Ved at niveauinddele sit CSS kræver det, at man har en meget stor opløsning på sin(e) skærm(e), da fx sjette niveau rykker din regel en del til højre, og når man som jeg har et element pr. linje, mister man overblikket, og kode forsvinger ud af skærmen.
    4) Det gør det sværere at genbruge komponenter uden du skal “rette” i dem.
    5) Man kan ikke være sikker på at ens spejling er komplet, hvorfor jeg ikke kan se fidusen i niveauinddeling. Dette punkt kræver noget uddybelse.
    Eksempel: du har en container, hvor du definerer noget styling på anchor. I din markup har du to anchors indenfor containeren, hvoraf den ene er i en usorteret liste. Hvis du vil have en komplet spejling af niveauinddelingen i dit stylesheet, vil du skulle lave redundant data, hvilket selvfølgelig er dumt. Derfor vil du undlade af definerer anchor i listen, da den arver fra containeren, hvilket er fint. Men så forsvinder fidussen med, at man ikke behøver at se sin markup for at vide opbygningen, og ligeledes hvad hvis en kollega har glemt at rykke nogle niveauer rigtig ind?

  3. 28 februar, 2010 på 15:59 | #3

    Fed og grundig artikel. Det eneste du måske mangler for at runde den helt af, er at snakke lidt mere perfomance og optimering af stylesheets, som især er vigtig på større websites.

    F.eks. er der performance gevinster ved at samle ens stylesheets i et “super stylesheet”, når siden kommer i produktion, og dermed spare på sidens http-request.

    Også ved at minify sine stylesheets kan opnå performance forbedringer. Igen er der selvfølgelig mere at spare på store stylesheets end på små.

    Glæder mig til at læse mark-up-delen. ;)

  4. 1 marts, 2010 på 10:19 | #4

    Jeg kan godt følge dig, men jeg har højest været ude i niveau 3, når jeg niveauopdeler min CSS.

    Inddeler også min CSS i sektioner, dog ikke vha. af selectors. Deler derimod min CSS ud på nogle forskellige filer, som eventuelt bliver smækket sammen vha. af Minify.

  5. 1 marts, 2010 på 21:52 | #5

    Hej Niels.

    Tak for de fine ord.
    Må indrømme at jeg nok ikke har vægtet performance så højt, som jeg måske burde. Har aldrig stået i en situation, hvor det har været nødvendigt. Måske fordi jeg laver så clean CSS og ikke overdriver med http-requests ;) Men helt sikkert et godt punkt til den revideret udgave.

    Vedr. markup-delen går der nok en dag eller ti før den kommer. Har desværre ikke den fornødne tid til at gøre det grundigt for tiden.

  6. 2 marts, 2010 på 18:23 | #6

    En rigtig god og detaljeret gennemgang af CSS. Jeg takker for indlægget!

  7. 11 marts, 2010 på 23:18 | #7

    Hej brormand!
    Jeg kan jo kun være enig:-)
    Du mangler lige at tilføje to ting samt et link:
    1) En af de væsentligste grunde til at køre med et “modularized” style sheet setup (et style sheet pr. sektion eller side) er at man potentielt sparer http requests, da man ikke henter alle sitets billeder på én gang. Hvis brugeren kun browser halvdelen af dit site, har du med andre ord sparet alle de http requests som de præsentations billeder i de style sheets som ikke er blevet hentet ville have genereret (hver billede reference i et style sheet laver et http request).
    Derfor mener jeg også at ideen går lidt tabt hvis man vælger at samle alle style sheets i et “super style sheet” på klienten.

    2) Sørg for at samle så mange billeder i et billede (CSS sprites), da man herved sparer så mange http requests som der er billeder… i billedet!

    Linket: http://developer.yahoo.com/performance/rules.html

  1. 27 februar, 2010 på 14:58 | #1
  2. 26 april, 2010 på 21:55 | #2