Kafli 14: Visual Formatting módel

CSS 2.1 skilgreinir visual formatting model sem skilgreinir hvernig við stýrum uppsetningu og flæði efnis á síðu.

14.1 Normal flow – eðlilegt flæði

Ef við höfum ekki skilgreint hvernig element á að haga sér er það í eðlilegu flæði og er sjálfgefið annað hvort block eða inline. Við getum stýrt hvernig element hegðar sér með display eigindinu, sem tekur eftirfarandi gildi (ekki tæmandi listi):

Ef við viljum ekki ganga svo langt að fjarlægja box með display: none; getum við falið allt efni innan þess með visibility: hidden;. Það felur boxið og allt efni í því en reiknar með því í útliti.

Fyrir eftirfarandi HTML:

<div class="box block">block</div>
<div class="box inline">inline</div>
<div class="box inline">inline</div>
<div class="box none">none</div>
<div class="box block">block</div>
<div class="box inline-block">inline block</div>
<div class="box inline">inline</div>
<div class="box inline-block">inline block</div>

og eftirfarandi CSS:

.box {
  width: 10vh;
  height: 10vh;
  margin: 20px;
  border: 2px solid #f00;
  padding: 20px;
  background-color: #eee;
  color: #111;
}
.block {
  display: block;
}
.inline {
  display: inline;
}
.inline-block {
  display: inline-block;
}
.none {
  display: none;
}

fáum við birtingu þar sem við skilgreinum að element með class .box fái fasta breidd og hæð, fast margin og padding á öllum hliðum; og 2px rauðan border til að sjá hvar þau eru. Útfrá eðlilegu flæði og því hvert display gildið er, eru þessi element birt, í okkar tilfelli:

Dæmi

Skjáskot af birtingu dæmis fyrir ofan.

Mynd frá höfundi.

14.2 Efni í boxi

Þegar við stýrum stærð á elementum með height eða width hættum við á að elementið verði of lítið fyrir efni sitt. Þá getur overflow hjálpað en það leyfir okkur að skilgreina hvað gerist við efnið sem flæðir út fyrir:

Í þeim tilfellum sem við takmörkum hæð á elementum sem innihalda texta þá viljum við hugsa sérstaklega um overflow. Það er auðvelt að gera ráð fyrir því að texti muni alltaf vera jafn langur og sá sem við höfum í forritun, en hvað gerist ef einhver bætir við tvisvar sinnum lengri texta? Eða ef fyrirsögn er það löng að hún fari í tvær línur? overflow: hidden er lausn sem viðheldur útliti en felur efni og er því ekki æskilegt. overflow: auto setur sjálfkrafa þær skrunstikur sem verða að vera og er yfirleitt besta lausnin. overflow er short-hand gildi fyrir overflow-x og overflow-y sem við getum notað til að stýra birtingu á x eða y ás sérstaklega.

14.3 Staðsetning

Við getum stýrt staðsetningu á elementum með position eigindinu. Það tekur nokkur lykilorð sem stýra hvernig við viljum breyta staðsetningu. Ásamt því notum við top, right, bottom og left eigindin (stundum kölluð offset eigindi) til þess að staðsetja elementið. Þau taka öll bæði jákvæð og neikvæð gildi sem lengd. static er sjálfgefna gildi position og staðsetur það í eðlilegu flæði. Að gefa element position gildi annað en static gerir það að containing block sem notast er við í suma útreikninga. Fyrsta containing block er rótar elementið, yfirleitt <html>.

14.3.1 Hlutfallsleg staðsetning

Við staðsejum element hlutfallslega í eðlilegu flæði með position: relative;. Staðsetning á elementi er reiknuð út frá eðlilegu flæði en síðan er það flutt hlutfallslega miðað við þá staðsetningu eftir gildum offset eiginda. Eftir flutning er „plássið“ í eðlilegu flæði eftir.

<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
.box {
  margin-bottom: 10px;
  padding: 20px;
  height: 50px;
}
.box:nth-child(2) {
  position: relative;
  top: 150px;
  left: 50px;
}
.box:nth-child(4) {
  position: relative;
  top: -200px;
  left: -50px;
}

Box 2 er flutt niður og til vinstri. Box 4 er flutt upp í pláss box 2 og dregið út til vinstri með neikvæðu gildi. Bæði eru reiknuð fyrst í eðlilegu flæði og fá breidd þaðan og skilja eftir sig pláss.

Mynd frá höfundi.

14.3.2 Nákvæm staðsetning

Við staðsetjum element nákvæmlega með position: absolute;, út frá containing block. Element sem eru staðsett nákvæmlega eru ekki reiknuð í eðlilegu flæði og skilja því ekki eftir sig pláss. Að auki þar sem þau eru ekki með í útreikning í eðlilegu flæði, þá fá þau ekki breidd út frá því. width: 100%; mun ekki gefa breidd sem er jöfn fullri breidd foreldris, heldur mun það taka stærð sem efni krefst.

<div class="absolute">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
</div>
.absolute {
  /* gerum foreldri að containing block */
  position: relative;
  border: 1px solid #000;
}
.box {
  margin-bottom: 10px;
  padding: 20px;
  height: 50px;
}
.box:nth-child(1) {
  position: absolute;
  top: 0;
  right: 0;
}
.box:nth-child(3) {
  position: absolute;
  bottom: 0;
  left: 50px;
  width: 100px;
}

Foreldri er containing block svo staðsetning miðast við það. Box 1 er flutt í efra hægra horn, það fær ekki stærð þar sem það er ekki reiknað í eðlilegu flæði. Box 3 er staðsett í botni 50px frá vinstri og gefin 100px breidd.

Mynd frá höfundi.

Með því að nota position: absolute; getum við látið element fylla út í foreldri sitt að öllu leiti með því að tilgreina öll staðsetningar eigindi í 0. Foreldri verður að vera containing block, annars er barnið staðsett ofar í trénu.

<div class="box">
  <div class="child">
    Box 1 – barn
  </div>
</div>
<div class="box parent">
  <div class="child fill">
    Box 2 – barn
  </div>
</div>
.fill {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.parent {
  position: relative;
}

Barn í boxi 2 fyllir alveg út í foreldri sitt þar sem það er containing block.

Mynd frá höfundi.

14.3.3 Föst staðsetning

Við staðsetjum element fast út frá viewporti með position: fixed;. Element sem eru fast staðsett eru ekki reiknuð í eðlilegu flæði og skilja því ekki eftir sig pláss. Element er fast að því leiti að þegar síða er scrolluð helst element í stað.

/* element er alltaf staðsett uppi í vinstra horni vafra */
.fixed {
  position: fixed;
  top: 0;
  left: 0;
}

14.3.4 Klístruð staðsetning

Klístruð staðsetning með position: sticky; notar samblöndu af hlutfallslegri og fastri staðsetningu. Staðsetning er reiknuð út frá eðlilegu flæði en þegar komið er að ákveðnum þröskuldi á containing block sem getur skrunað, þá er það reiknað sem það væri hlutfallslega fast.

.sticky {
  /* staðsett hlutfallslega þangað til... */
  position: sticky;
  /* 200px frá top á containing block sem skrunar, þá fast */
  top: 200px;
}

14.3.5 Þriðja víddin

Element sem hafa annað gildi en position: static; eru ekki aðeins staðsett í tvívíðu rúmi, þau liggja líka á z-ás. Þetta kemur fram t.d. í því að ef tvö eða fleiri element eigi að birtast í efra vinstra horni, hvert þeirra sést? Þessi staðsetning ræðst af stacking order og hvernig það er reiknað út sjálfgefið fylgir ákveðnum reglum. Við getum ákvarðað hvar í röðinni element liggur með því að gefa því sitt eigið gildi með z-index: <tala>;. Hærra z-index gildi raðar element nær notanda þ.e.a.s. ofar á z-ás.

<div class="zindex">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
</div>
.zindex {
  position: relative;
  border: 1px solid #000;
}
.zindex .box:nth-child(1) {
  position: absolute;
  top: 60px;
  right: 0;
  z-index: 4;
}
.zindex .box:nth-child(2) {
  position: relative;
  z-index: 1;
}
.zindex .box:nth-child(3) {
  position: absolute;
  bottom: 50px;
  left: 50px;
  z-index: 1;
  width: 100px;
}
.zindex .box:nth-child(4) {
  position: relative;
  z-index: 3;
}

Box 1 liggur ofan á öllum öðrum boxum en box 3 liggur ofan á boxi 2 en undir boxi 4.

Mynd frá höfundi.

Eitt sem getur valdið vandræðum með z-index er þegar við viljum birta element innan elements sem hefur skilgreint z-index og hefur systkini sem hafa sama z-index, fyrir utan það. T.d. ef við viljum birta upplýsingar þegar hoverað er yfir eitthvað eða smellt á takka í lista af boxum. Boxin hafa sama z-index og reglur segja til um að seinna í DOM trénu (þ.e.a.s. seinna í HTML röð) hefur forgang í birtingu ef sama z-index gildi er skilgreint.

Texti sem birtist þegar hoverað er yfir texta liggur undir boxi sem kemur á eftir og hefur sama z-index.

Mynd frá höfundi.

14.4 Fela efni ætlað skjálesurum

Það geta komið upp þau tilvik þar sem við viljum fela efni frá vöfrum en gera það aðgengilegt skjálesurum. T.d. „beint í efni“ tenglar eða textar sem auðveldara er að lesa úr samhengi hönnunarsíðu en ef hún er lesin. Til þess að gera þetta „skjálesara aðgengilega efni“ falið, er CSS notað. Það eru nokkrar leiðir til þess að ná þessu fram, t.d. að skilgreina .sr-only skipun:

.sr-only {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

14.5 Floats

Önnur leið sem CSS 2.1 skilgreinir til að hafa áhrif á eðlilegt flæði er með floats en það getum við skilgreint fyrir element með float eigindinu sem getur tekið gildin left, right eða sjálfgefna gildið none. Með því að skilgreina float: left; eða float: right; fjarlægjum við element úr eðlilegu flæði og „fleytum“ því til vinstri eða hægri m.v. þá línu sem það er í. Þessi lína er efri brún staðsetningar elements í eðlilegu flæði áður en því er fleytt. Fleiri en eitt element sem fleytt er í sömu átt munu sitja hlið við hlið lárétt svo lengi sem þau hafa pláss. Um leið og plássið er ekki til staðar mun elementi vera ýtt niður og „ný“ lína mynduð.

<div class="img">mynd</div>
<p>Lorem ipsum dolor sit amet…</p>
.img {
  float: left;
  margin: 0 10px 10px 0;
}

„Mynd“ er fleytt til vinstri og liggur við hliðina á texta.

Mynd frá höfundi.

Við getum stýrt flæðinu í kringum element sem er fleytt með clear eigindinu sem tekur við gildunum left, right, both eða sjálfgefna gildinu none. Ef við „hreinsum“ ekki innan foreldris, sem aðeins inniheldur element sem er fleytt, getum við lent í vandræðum þar sem það fær þá ekki hæð og fellur saman (collapses). Nokkrar leiðir eru til að koma í veg fyrir þetta en sú sem var vinsælust meðan float var meira notað var clearfix sem er sett á foreldrið og útbýr gervi-element á eftir því sem sér um að hreinsa.

.clearfix::after {
  content: '';
  display: table;
  clear: both;
}

Á einum tímapunkti var float töluvert notað til þess að stýra heildar útliti á síðum, t.d. til að fleyta dálkum til hliðar, við hliðina á meginmáli. Í dag ættum við ekki að nota float til að stýra útliti heldur aðeins til að fleyta elementum innan annars efnis, t.d. myndum sem eiga við texta. Til þess að stýra útliti notum við Flexbox eða CSS grid.