Kafli 10: CSS málfræði

10.1 Málfræði

Málfræði CSS er einföld, flest það sem við gerum byggist á því að vinna með reglusett sem samanstenda af selectors og yfirlýsingum. Hægt er að setja inn athugasemdir í CSS innan /* og */ en í CSS er engin leið til að skilgreina athugasemd sem tekur yfir eina línu (oft gert með // athugsemd eða # athugasemd).

/* eftirfarandi er eitt reglusett */
p /* selector */
{ /* yfirlýsingar innan { } */
  color: green; /* yfirlýsing */
  margin: 1em; /* yfirlýsing */
}

10.1.1 Selector

Selector er strengur sem lýsir því hvaða element við viljum að taki við yfirlýsingum. Sér í lagi getum við skrifað:

Gervi-klasar skiptast síðan áfram í flokka:

Hægt er að tengja saman selectors með   bili (e. whitespace), >, + eða ~:

*              /* öll element */
div            /* öll div */
div p          /* öll p, afkomendur div */
div > p        /* öll p sem eru börn div */
p + p          /* öll p með p sem fyrra systkini */
p ~ span       /* öll span sem koma á eftir p */
div.important  /* öll div með class important */
a:hover        /* öll a sem verið að hovera á */
div#main       /* öll div með id main */
div[lang="is"] /* öll div með attribute lang=is */

Ef fyrir eftirfarandi HTML:

<div>
  <p>Halló <strong id="text">heimur</strong></p>
</div>
<div class="text">
  <em>Lorem</em> <span lang="is">ipsum <em>dolor</em> sit amet</span>,
  consectetur adipiscing elit.
</div>
<div class="text">
  <em>Lorem</em> <span lang="is">ipsum <em>dolor</em> sit amet</span>,
  consectetur adipiscing elit.
</div>
<div class="text"><!-- viljandi tómt --></div>

skilgreinum við CSS sem stýrir útliti með mismunandi selectors, sjá athugasemdir við hvern um hvað er gert:

/* Fjarlægjum allt margin og padding af öllum elementum */
* {
  margin: 0;
  padding: 0;
}
/* Setjum padding aðeins á body og stækkum letur */
body {
  padding: 50px;
  font-size: 20px;
}
/* svartur 1px breiður border á öll div og padding */
div {
  padding: 5px;
  border: 1px solid #000;
}
/* látum öll em vera með undirlínu, ekki skáletrun */
em {
  text-decoration: underline;
  font-style: none;
}
/* en ef þau eru beint undir div er textinn blár */
div > em {
  color: #00f;
}
/* div sem er systkini div fær 20px margin fyrir ofan sig
    og annan bakgrunnslit */
div + div {
  margin-top: 20px;
  background-color: lightcyan;
}
/* öll div á eftir div.text fá neon grænan bakgrunn */
div.text ~ div {
  background-color: rgb(0, 255, 0);
}
/* fyrsti stafur undir div.text verður tvöfaldur að stærð */
div.text:first-letter {
  font-size: 2rem;
}
/* Ef html er með attribute lang með gildið is, setja ljósgráan bakgrunn
    hvað gerist fyrir bakgrunnslit fyrsta div? */
html[lang='is'] {
  background-color: lightgray;
}
/* Ef *eitthvað* element sem er barn body er með attribute lang með
  gildið is, gefa gulan bakgrunn */
html [lang='is'] {
  background-color: yellow;
}
/* ef div.text er tómt, gefa því rauðan bakgrunn
    en af hverju ekki neon grænan? af hverju er það svona lítið? */
div.text:empty {
  background-color: red;
}
Dæmi

Birting á dæmi í vafra.

Skjáskot frá höfundi.

10.1.2 at reglur

At reglur leyfa skilgreiningar á aukaupplýsingum. Þær geta verið fyrir ákveðið gildi, t.d. @import 'typography.css'; sem innifelur allt CSS úr typography.css. Þær geta einnig verið hreiðraðar (e. nested), innihalda þá CSS reglur sem eru aðeins notaðar við ákveðin skilyrði, t.d.

10.1.3 Gervi-element

Gervi-element (e. pseudo-elements) leyfa okkur að velja elementi sem er ekki til staðar í DOM tré. Þau eru skilgreind í selector með ::.

10.1.4 Villumeðhöndlun

CSS er hannað til að fyrirgefa minniháttar villur, þá er öll yfirlýsingin hunsuð og haldið áfram að næstu. Þetta gerir það að verkum að CSS er traust og byggt til að virka í dag með virkni sem verður til á morgun, t.d.:

Meiriháttar villur stoppa lestur á skjali frá þeim stað sem þær eiga sér stað. Þetta gerist yfirleitt þegar { og } eru ekki í jafnvægi ({ er ekki lokað á réttum stað).

p {
  color: blue;
  /* næstu tvær reglur eru hunsaðar, vantar ;, leitar að næsta */
  color: yellow
  font-size: 10em;
  /* ekki hunsað */
  font-size: 2em;
}
/* a verður litað grænt þó } vanti */
a {
  color: green;
/* engar reglur héðan í frá taka gildi því } vantar */
em {
  color: purple
}

10.1.5 Skilgreiningar

Skilgreiningar á reglusetti eru innan { og }, og innihalda enga eða fleiri yfirlýsingar aðgreindar með semíkommu. Yfirlýsing byrjar á nafni eigindis (e. property), tvípunkti, gildi eigindis (e. value) og loks endar semíkomma yfirlýsinguna. eigindi: gildi;. Nöfn eiginda eru margvísleg í CSS og bætast við fleiri eftir því sem ný virkni er skilgreind. Gildin eru hinsvegar töluvert færri.

Fyrir sum eigindi er hægt að skilgreina í einni yfirlýsingu, þetta er kallað shorthand. Þessi virkni getur minnkað fjölda lína sem við þurfum að skrifa og kannski sparað tíma. Shorthand leyfir líka að sleppa því að skilgreina ákveðin gildi og eru þá sjálfgefin gildi sett í staðinn. Þetta getur valdið vandræðum ef það skrifar yfir gildi sem við höfum áður skilgreint.

10.2 Gildi í CSS

Strengir er skilgreindir með ' eða ". Ef við þurfum að skrifa þessa stafi notum við lausnarstafinn (e. escape character) \ til að skilgreina lausnarrunu (e. escape sequence) fyrir stafinn.

Url skilgreinum við með url(<slóð>) þar sem slóð er innan eða utan strengs.

Strengir sem skilgreindir eru án ' eða " eru lykilorð sem vísa þá í vel skilgreinda hegðun samkvæmt CSS staðli. T.d. display: block;, block er lykilorð sem gefur til kynna hverskonar display hegðun element á að fylgja.

Tölur geta verið jákvæðar og neikvæðar heiltölur og rauntölur. Rauntölur eru skilgreindar með punkti, t.d. 1.2. Tölur notum við yfirleitt þegar við vinnum með lengdir í CSS. Einingar á tölum geta verið ýmsar en einnig getum við skilgreint prósentur, t.d. 25.5%. Þegar við notum prósentur miðast þær alltaf við gildi foreldris eða breidd tækis. width: 100%; lætur element taka breidd sem er jöfn 100% af breidd foreldris eða skjás.

10.2.1 Sérstök gildi

Nokkur gildi eru sérstök og virka með örðum gildum eða upprunagildum:

Hægt er að nota þessi sérstöku gildi með sérstaka eigindinu all sem á við öll eigindi elements. T.d. all: initial; lætur öll eigindi fyrir element taka sín upprunagildi.

10.3 Litir

Liti má skilgreina með:

10.4 Lengdir

Þegar unnið er með útlit í CSS er mikið unnið með lengdir. Hvort sem það er til að stýra hversu breið, há eða hve mikið bil er á milli elementa. Eigindin geta tekið hinar ýmsu einingar. Í grunninn eru þær hlutfallslegar og nákvæmar.

Eitt sérstakt gildi er hægt að gefa fyrir lengd en það er auto sem leyfir vafra að reikna lengdina sjálfkrafa.

10.4.1 Nákvæmar einingar

Nákvæmar einingar eiga við þegar við vinnum með hluti sem þurfa nákvæmar mælingar. T.d. fyrir prent þar sem við prentum á þekkta stærð í raunheimum, þar er hægt að nota einingar eins og in, cm, eða mm. Að skilgreina 1cm í CSS þýðir samt ekki að útkoman verði nákvæmlega einn sentimeter útprentuð. Nákvæma gildið er alltaf hlutfallslegt við upplausn prentunar, dpi eða dots per inch.

Í langflestum tilfellum reynum við að sleppa því að nota nákvæmar einingar þegar við útbúm birtingu fyrir vafra og stafræn tæki. Umhverfið sem vefurinn okkar birtist í er ekki þekkt stærð. Þó eru aðstæður þar sem við þurfum að nota nákvæmar einingar og þá notum við px eða pixel. Það er þó flóknara en svo að 1px í kóða sé 1px á öllum tækjum, þar kemur til upplausn tækis og fleira.

10.4.2 Hlutfallslegar einingar

Hlutfallslegar einingar skiptast í tvo hópa, letur-hlutfallslegar einingar (e. font-relative lengths) og skjá-prósentu einingar (e. viewport percentage lengths).

Letur-hlutfallslegar einingar horfa til font-size eigindsins þegar þær skilgreina stærð fyrir element. Yfirleitt notum við em eða rem einingar. em var upphaflega stærð skilgreind útfrá breidd M í leturgerð en hefur í dag verið skilgreind í CSS sem stærð font-size. Ef ekkert hefur verið átt við font-size er 1em == 16px en ef font-size: 18px; hefur verið skilgreint verður 1em == 18px.

Þegar reiknað er úr em gildum í elementum sem eiga sér foreldri með skilgreint em gildi eru þau margfölduð. Þetta getur oft valdið ruglingi þegar em er notað:

<div class="text">
  Texti utan &lt;p&gt;, smár.
  <p>Texti innan &lt;p&gt;, stærri.</p>
  <p>
    Texti innan &lt;p&gt; sem inniheldur <strong>enn stærri texta</strong>.
  </p>
</div>
/* texti innan html er núna 16px * 2 = 32px */
html {
  font-size: 2em;
}
/* texti innan .text er nákvæmlega 16px */
.text {
  font-size: 16px;
}
/* texti í p undir .text er 16px * 1,5 = 24px */
.text p {
  font-size: 1.5em;
}
/* texti í em undir p undir .text er nákvæmlega 12px */
.text p em {
  font-size: 12px;
}
/*
  texti í strong undir p undir .text er:
  16px * 1,5 * 2 = 48px
  þar sem 12px komur frá .text
  margföldum með 1,5 út af .text p
  margföldum með 2 út af skilgreiningu sjálfri
*/
.text p strong {
  font-size: 2em;
}
Dæmi

Birting á dæmi í vafra.

Skjáskot frá höfundi.

Núna gætu einhverjir spurt sig, af hverju í ósköpunum að hafa svona flækjustig í útreikningum á stærðum fyrir texta? Þetta er svona flókið þar sem við getum með þessu útbúið vefi þar sem vertical rhythm eða lóðréttur hrynjandi í texta er réttur. Öll bil og allar stærðir eru margfeldi af grunnstærð. Einnig gerir þetta það að verkum að notendur geta breytt stærð og við það skalast allt sem skilgreint er í hlutfallslegum einingum í réttum hlutföllum. Ef við skilgreinum stærðir eingöngu í pixlum gerist það ekki, og vefurinn okkar verður óaðgengilegur.

Ef við notum rem eininguna þurfum við ekki þessa margföldun í gegnum tréð; hún notar alltaf stærð rótar elements, font-size á <html>. Þar með getum við fengið kosti þess að skilgreina hlutfallslega án þess að þurfa að vera í sífellu að reikna hlutföll.

Skjáskot af síðu sem nýtir grid og vertical rhythm.

Síða sem nýtir grid og vertical rhythm.

Skjáskot frá höfundi.

Ástæðan fyrir því að nota hlutfallslegar einingar er, eins og áður var nefnt, til að hjálpa okkur að láta vefinn okkar birtast rétt í þeim mýmörgu tækjum sem hann gæti verið skoðaður í. Ef við fastsetjum allar stærðir útfrá stórum skjám með háa upplausn munu einstaklingar sem skoða hann á minni skjám með minni upplausn lenda í vandræðum, og öfugt.

Skjá-prósentu einingar eru hlutfallslegar við stærð viewports sem er yfirleitt stærð vafragluggans.

Hægt er að nota þessar einingar bæði til að stýra stærðum á elementum eða öðru, t.d. leturstærð.