1. Webdesign 101 forside
  2.  » CSS
  3.  » CSS under hjelmen

Fomreglernes vægt

Begrebet hedder egentlig specificitet. Der er ganske bestemte regler for med hvilken vægt en given formregel skal påvirke et element.

Et klassisk og let forståeligt eksempel er, at du et sted i dit stylesheet har en formdeklaration h3 {color:red;} og et andet sted har en formdeklaration, der indeholder en formregel:

h3 {
font-variant:small-caps:
margin:0.4em auto;
color:teal;
...}

Og den klassiske og letforståelige regel er, at den formregel der står nærmest elementet er den "der vinder". I HTML-koden <h3 style = "color : teal";>...</h3> kan formreglen, der bestemmer farve, dårligt komme nærmere på elementet. Formdeklarationen i style-attributten i dette eksempel kaldes for en inline style eller en inline formdeklaration.

Arv, specificitet og kaskade

Der er tre forhold, der styrer formen (udseendet) på et element.De er:

  • Arv – det fænomen, at et element arver visse af forældreelementets egenskaber. For eksempel er vi jo aldrig i tvivl om, at alle tekstelementer får den farve, vi sætter som forgrundsfarve for body-elementet.
  • Specificitet – ja, jeg ved det er et gebrækkeligt ord, men det hedder det altså. Med specificitet menes det fænomen, at nogle formregler har større vægt end andre i kraft af den selektor, der er knyttet til formreglerne.
  • Kaskaden, hvormed menes hvor nært en given formregel er knyttet til et givet element.

Det er det sidste forhold, der har størst praktisk betydning. De andre forhold begynder vi normalt først at interessere os for, når vor forståelse af kaskaden svigter. Det er heldigvis også det forhold, der er nemmest at forstå, idet det forholder sig som allerede beskrevet - jo nærmere et element, jo større vægt.

Det er blandt andet dette forhold, der har givet navn til CSS – Cascading Style Sheets.

Som nævnt trumfer en inline style (næsten) alle andre formregler, men jeg kan ikke anbefale at du bruger dette. Adskillelse af form og indhold opnås ved at alle formregler nedlægges i et eller flere stylesheets, der er eksterne i forhold til siden.

Forestillinger vi os nu at du har et globalt stylesheet for alle dine sider, samt et eller flere øvrige stylesheets, der vedrører bestemte grupper af elementer, du kun har på nogle få sider, fungerer kaskaden fortsat, således at den formregel, der står nærmest – det vil sige i det sidst indlæste stylesheet – har større vægt end stylesheets der er indlæst forudgående.

Der kan siges noget mere overordnet om kaskadeprincippet, som imidlertid mest har teoretisk karakter i det daglige arbejde. Derfor har jeg gemt disse bemærkninger: Klik her for at vise/skjule disse bemærkninger.

I omtalen af kaskaden i denne artikel befatter jeg mig udelukkende med de formregler, du skriver og knytter til de elementer, du har på dine websider.

Der er imidlertid andre spillere med i legen. Den overordnede kaskade hedder på engelsk Author, User, Browser og udtrykker en vægtfordeling mellem de tre spillere, således at de formdeklarationer, du laver, har større vægt end dem, brugeren eventuelt laver, og disse har igen større vægt end dem, der er indbygget i browseren. Tager vi såvel din som brugerens mulighed for at bruge nøgleordet !important i en given formregel får vi en opstilling med i alt fem punkter:

  1. Brugerens !important deklarationer
  2. Konstruktørens !important deklarationer
  3. Konstruktørens normale deklarationer
  4. Brugerens normale deklarationer
  5. Browserens deklarationer

Jo højere op på listen, des større betydning.

Ovenstående bemærkninger om kaskaden, lidt sund sans og et simpelt eksperiment i ny og næ vil antagelig være nok for de fleste til at klare sig ud af eventuelle vanskeligheder på dette område.

Men lad os alligevel overveje, hvordan en browser skal håndtere et stylesheet, der indeholder følgende formregler:

h2.red {color:red}
h2 {color:green;}
h1 {color:maroon;}
body h1 {color:navy;}

Specificitet

Browseren skal beregne specificiteten af hver selektor. Specificitetens værdi kan udtrykkes i fire dele, således: 0,0,0,0. Den faktiske specificitet beregnes på følgende måde:

  • For hver id attributværdi, der er indeholdt i selektoren, tillægges specificiteten 0,1,0,0.
  • For hver class attributværdi, attributreference eller pseudoklasse i selektoren tillægges specificiteten 0,0,1,0.
  • For hvert element og pseudoelement i selektoren tillægges specificiteten 0,0,0,1.

På denne måde kan browseren beregne fire tal for en hvilken som helst selektor. Nogle eksempler:

Beregning af formreglers specificitet
h1 {color:red;} Specificitet: 0,0,0,1 (Ét element)
p strong {color:navy;} Specificitet: 0,0,0,2 (To elementer)
.red {color:red} Specificitet: 0,0,1,0 (Én class attributværdi)
p.red {color:red;} Specificitet: 0,0,1,1 (Ét element, én class attributværdi)
div#leftcol {color:navy;} Specificitet: 0,1,0,1 (Ét element, én id attributværdi)
p.red em.maroon {color:maroon} Specificitet: 0,0,2,2 (To elementer, to class attributværdier)

Således bevæbnet kan vi vende tilbage til vore fire eksempler og sætte nogle specificitetsværdier på:

h2.red {color:red}  /* 0,0,1,1 */
h2 {color:green;}  /* 0,0,0,1 */
h1 {color:maroon;}  /* 0,0,0,1 */
body h1 {color:navy;}  /* 0,0,0,2 */

Vægten af tallene er større, jo længere til venstre, de står. Af to tal på samme position har det største tal den største vægt. Derfor giver ovenstående stylesheet til resultat, at h2-overskrifter bliver røde, hvis de har class="red", og alle h1-overskrifter bliver mørkeblå.

Hvis du undrer dig over, hvad det venstre tal, der ifølge ovenstående altid er nul, gør godt for, kan jeg sige, at specificiteten på en inline formregel er 1,0,0,1, hvis der i øvrigt ikke er knyttet en class eller en id til elementet.

!important

Du kan beslutte dig for, at en bestemt formregel er så vigtig, at den skal komme til at gælde, uanset alle andre stylesheet regler, inklusive inline formregler. Dette gøres ved at knytte nøgleordet !important til den formregel, du tillægger denne størst mulige vægt:

a.ekstern:link {
  color:maroon !important; 
  background-color:white;}

En sådan formregel vil betyde, at et link med klassenavnet ekstern altid har en rødbrun farve. Bemærk syntaksen: !important indsættes i formreglen før denne afsluttes med semikolon, og gælder kun for color-egenskaben, og altså ikke for background-color-egenskaben.

Når tingene ikke virker

Hvis du arbejder seriøst med stylesheet formatering vil du måske komme ud for, at tingene ikke virker som forventet.

Det kan have mange årsager. Først og fremmest er det meget nødvendigt at du bruger helt korrekt syntaks i både din html-kode og i dine stylesheets. Er du i tvivl om, hvorvidt forkert syntaks er årsagen, bør du straks undersøge validiteten af såvel HTML-kode som stylesheets, for eksempel ved hjælp af W3C's validatorer.

Specielt i forbindelse med formateringen af menuer, eller rettere med formateringen af a-markøren, har jeg ofte oplevet “fejl”, som ikke er syntaktiske, men som skyldes forskellig vægt af de formregler, jeg har anvendt. Kig et øjeblik på nedenstående udsnit af et stylesheet til en menu:

div#navbar ul.topmenu li a { 
  color:black; background-color:white; }
ul.topmenu li a:hover {
  background-color:#dddddd; }
ul.topmenu li a#link3 {
  background-color:#dddddd;}

Meningen med disse i alle måder korrekte formregler er, at et link i en li i en ul med klassen topmenu skal have sort tekst på hvid baggrund, men at baggrundsfarven skal skifte til en lys grå, når musen er over et link (:hover-tilstanden), samt at ét bestemt link, som har en id="link3", også skal have denne grå baggrundsfarve.

Disse farveskift sker blot ikke. Det er sådan set nemt nok at få det til at ske, ved at indsætte nøgleordet !important de rette steder, således:

div#navbar ul.topmenu li a { 
  color:black; background-color:white; }
ul.topmenu li a:hover {
  background-color:#dddddd !important; }
ul.topmenu li a#link3 {
  background-color:#dddddd !important;}

Men det er jo ikke nogen forklaring på, hvorfor det fejler i første omgang. Forklaringen har at gøre med at de korrekte formdeklarationer har forskellig specificitet, således at den øverste formdeklaration, der gælder a-markøren, har en større vægt end de efterfølgende, der gælder for nogle specielle udgaver af den samme a-markør. Du kan selv regne efter, hvis du henholder dig til ovenstående.

Men i samme øjeblik, idéen om formdeklarationernes vægt har meldt sig, er det jo let at indse, at jeg har sjusket med de to nederste formdeklarationer. Der er ikke noget forkert ved dem, men de er ufuldstændige i forhold til den øverste formdeklaration.

Den ønskede effekt opnås ved at skrive disse 3 formdeklarationer på nedenstående form:

div#navbar ul.topmenu li a { 
  color:black; background-color:white; }
div#navbar ul.topmenu li a:hover {
  background-color:#ddd; }
div#navbar ul.topmenu li a#link3 {
  background-color:#ddd;}

November 2009