HTML/CSS 4: pozície, relatívne premenné

Trocha responzivity

V dnešnom svete potrebujeme, aby každá webstránka bola responzívna, čiže aby fungovala na zariadení každého rozmeru.

Prvý level toho je urobiť všetky elementy na stránke prispôsobivé šírke obrazovky. Takže ak si manuálne zmenšíme okno prehliadača, elementy sa nejak prispôsobia, tal, aby sa nám nikdy nevytvoril horizontály scroll-bar (s týmto začneme dnes)

Druhý level je fyzicky meniť vzhľad jednotlivých komponentov stránky (zmeniť usporiadanie položiek/vymeniť logo za verziu bez textu/odstrániť niektoré časti stránky) ak je prehliadač príliš malý. Toto je často vidno na verziách pre mobily, stránka sa nám častokrát kompletne poprehadzuje, aby sa vmestila do telefónu. (toto bude niekedy na konci semestra)

Naším cieľom je, aby užívateľ vedel pohodlne stránku používať na akomkoľvek zariadení bez toho, aby to musel nejak sám riešiť. Toto je vlastne dnešný štandard. Áno, existujú stránky, ktoré to nespĺňajú a mali by sa za seba hanbiť

Minulý týždeň sme si robili stránku takéhoto typu:

<!DOCTYPE html>
<html>    
    <head>
        <link rel="stylesheet" href="style.css"> 
    </head>
    <body>
        <div class="modry">
            <p>...</p>
            <p>...</p>        
        </div>    
    </body>    
</html>
.modry{
    width: 600px;
    background-color: deepskyblue;
    
    margin-left: auto;
    margin-right: auto;
}

(do paragrafov si doplňte nejaký text, nech máte na stránke nejaký obsah)

Stránka funguje fajne, ale ak si zmenšíme okno pod 600px, už ju nevidíme celú. ako sa to dá opraviť?

Miesto šírky môžeme využiť tzv. maximálnu šírku. Vymeňte si width:600px za

max-width: 600px;

Teraz bude mať element šírku podľa toho v akom je širokom prostredí, ale maximálne 600px.

Takže element sa nám zmenšil a jeho obsah sa naposúval tak, aby sa zmestil. V zásade takýto typ správania budeme vyžadovať od všetkého na našej stránke.

Analogicky fungujú aj max-height, min-width a min-height

UNITS

Zatiaľ sme používali väčšinou tzv. absolutne jednotky (absolute units), ako napríklad pixely (px).

Druhou základnou skupinou sú relatívne jednotky (relative units). Pre nás zaujímavé budú:

% = veľkosť vzhľadom nadradený element (parent = tj element v ktorom sa nachádza)

Pridám si na stránku medzi paragrafy nový div triedy „pasik“, ktorý bude mať vlastnosti:

.pasik{
    background-color: darkblue;
    width: 50%;
    height: 20px;
}

Šírku si bude udržiavať na 50% veľkého modrého divu (pretože je to to jeho priamy rodič (parent), nech je hociako široký.

Bohužiaľ, ak uložíte vedľa seba viacero elementov, nedá sa spoliehať na to, že sa vedľa seba zmestia ak ich percentuálna šírka sa nasčíta na menej ako sto.

Skúsme si dať vedľa seba dva linky, každý šírky 50%.

a{
    display: inline-block;
    background-color: azure;
    width: 50%;   
}

Zatiaľ môže byť.

Keby sme im teraz chceli dať nejaký rámček, zrazu by sa nezmestili. Rámček sa ráta mimo túto percentuálnu hodnotu. Rovnaký problém by nám spôsobil margin a padding.

Dať dam trošičku menej percent to nezachráni. Môžete si to vyskúšať, v zásade to bode robiť toto: pri nejakých šírkach modrého divu sa objekty zmestiť vedľa seba budú, pri niektorých nie. Niečo takéto:

Je to fuj. V zásade maximálna šírka a percentá boli dostatočne v dobách, kedy boli všetky monitory cca rovnaké a telefóny mali tlačítka. Našťastie nám odvtedy pribudli nové a lepšie nástroje, s ktorými sa dá problém tohto typu pohodlne riešiť. (a niekedy medzitým bola doba, kedy sa web-developeri trápili s týmito starými toolmi pri moderných požiadavkách a bolo to hrozné).

Medzi tieto nové nástroje z veľkej časti patrí css flex a css grid, ktoré si aj postupne preberieme na ďalších hodinách.

Ale ešte najprv niečo k ďalším dôležitým jednotkám. Ďalšia super jednotka je:

em = zvhľadom na výšku fontu elementu.

Všetky vzdialenosti na stránke týkajúce sa textu je dobré škálovať vzhľadom na veľkosť fontu. Tým myslím odsadenie prvého riadku paragrafu, vzdialenosti medzi odsekmi a nadpisami a podobne. Prečo:

  1. na pixel sa nedá tak úplne spoľahnúť. Niektoré zariadenia majú šialene veľké rozlíšenie a podobne
  2. niektorí ľudia si zväčšujú text na stránke rôznymi pomocnými addonmi a nastaveniami, jednoducho preto, že im je príliš malý. Ak sa vám naškáluje font, ale odsadenia ponechajú, rozbije vám to celý dizajn.

Kvôli druhému bodu je VEĽMI dôležité nedávať pevnú výšku textu. Ilustračne asi takto:

Prvý stĺpec má pevne určenú výšku fontu 16px. ostatné majú 1em (v tomto prípade to vychádza práve na tých 16 pixelov). Ak si umelo zvýšim veľkosť fontu, lebo to potrebujem kvôli zlému zraku, prvý paragraf mi ostane nečitateľne malý a všetok ostatný text sa mi upraví.

Takže odteraz budeme (hlavne pri elementoch obsahujúcich text) používať hodnoty typu

p{
    text-indent: 3em;
    margin: 3em;
    font-size: 1.1em;
}

Ďalšie možno zaujímavé jednotky (na ktoré chcem upozorniť) sú:

vw = 1% šírky okna; vh = 1% výšky okna

Pod oknom sa tu myslí okno vášho browsera. Sú trochu podobné ako percentá, rozdiel je v tom, že zatiaľ čo percentá sa pozerajú na svoj rodičovský element, vw a vh fungujú vzhľadom na veľkosť okna browsera.

Viac sa im venovať nebudeme, len som chcela upozorniť, že také niečo existuje.

Jednotiek je v html v skutočnosti celkom dosť, väčšina je pre bežného človeka dosť zbytočných.

Position

Vlastnosť position je veľmi dôležitá. Vyrobte si prázdne stránku, (môžete si premazať aj to čo sme robili doteraz, že to nebudeme potrebovať). Vytvote si tam takýchto 5 kociek vedľa seba:

<body>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
</body>
div{
    width: 50px;
    height: 50px;
    margin: 20px;
    
    display: inline-block;
    background-color: lightblue;
}

Pod ne si pridáme jeden veeeeliký div v tvare obdĺžnika, ten bude iba čisto na to, aby stránka bola dosť dlhá a mohli sme scrollovať.

<div class="dlhan"></div>
.dlhan{
    display: block; 
    height: 1000px;
}

Jednu z horných kocku vyhlásime za špeciálnu, dáme jej vlastnú triedu a odlíšime si ju farbou. Na tejto si budeme skúšať rôzne hodnoty pre position.

.speci{
    background-color: orange;
}

Takže máme zatiaľ toto:

Vlastnosť position nám ponúka niekoľko rôznych hodnôt. Spolu s nimi budeme používať (podľa potreby) aj pomocné vlastnosti top, bottom, left a right, ktoré budú v zásade vyjadrovať posun oproti normálu. Všetky si ich poskúšajte na oranžovom dive.

1. STATIC

Element je umiestený štandardne vzhľadom na to kde sa nachádza. Toto je defaultná hodnota pre position.

position: static;

Vlastnosti top, bottom, left a right tu nič nerobia.

2. RELATIVE

Element sa tvári, že je normálne tam, kde má byť (ako pri static), ale v skutočnosti sa zobrazí trochu bokom. „Trochu bokom“ vieme ovládať pomocou vlastností top, bottom, left a right.

position: relative;
top: 15px;
left: 30px;

Oranžový štvorček sa nám zobrazí o 15px nižšie a o 30px viac doprava.

(pozn. všimnite si, že toto posunutie ostatné elementy vôbec nerozhádzalo, stále sú tam, kde boli predtým, akoby mu tam ostalo alokované miesto)

3. ABSOLUTE

Element sa zobrazí relatívna vzhľadom na svojho najbližšieho predka, ktorý je umiestnený pomocu position (s inou hodnotou ako static). Miesto určíte pomocou pomocných vlastností top, bottom, left a right. V tomto prípade náš div neleží v žiadnom inom tagu s pozíciou, takže pozícia bude vzhľadom na celú webstránku (pričom Left = vzdialenosť od ľavej steny). Vypadne tým z bežného chodu stránky (čiže ostatné elementy zabudnú, že tam je)

 position: absolute;
    top: 15px;
    right: 30px;

4. FIXED

Elemen sa zobrazí na presné miesto v okne browsera, celá webstránka je mu úplne ukradnutá. Vlastnosti top, bottom, left a right mu určia polohu.

position: fixed;
top: 15px;
right: 30px;

Pod týmto si predstavte takých tých pomocníkov/helpdesky/nakupných asistentov na e-shopoch, čo vám vyskočia vpravo dole na stránke a tvária sa veľmi kamarádsky a pýtajú sa vás, či nepotrebujete pomôcť, a vy viete, že je to len robot a cítite sa divne, že sa na vás usmieva.

5. STICKY

Sticky je kombinovaná vlastnosť. V zásade, element sa chová ako static, ale ak by mal kvôli scrollovaniu vypadnúť z webstránky, „prilepí“ sa na okraj stránky a premení sa na fixed.

position: sticky;
    top: 0;

Takáto veľmi konkrétna kombinácia má vlastnú vlastnosť preto, že bol po nej veľký dopyt. Štandardne sa to používa na webstránky, kde chcete mať stále k dispozícii hlavné menúčko aj keď ste odscrollovaní niekde veľmi ďaleko.

Príklad zo života: https://math.stackexchange.com/

Skúste si v tom poscrollovať. Horné menúčko je celý čas prilepené na hornej obrazovke, to je typu position:fixed. Ľavé menúčko (to so záložkami Home, Questions, …) sa najprv normálne scrolluje so stránkou, ale keď už by malo zmiznúť, „prilepí“ sa o vrch stránky. (Ľavé menúčko je prítomné iba ak máte dostatočne veľké okno, )

K všetkému tomuto ešte potrebujeme jednu pomocnú hodnotu:

Z-index

Z index určuje poradie „v osi z“. V zásade ide o to, že pri takýchto trikoch sa nám častokrát dva elementy prekrývajú. Z-index nám určí, ktorý je navrchu.

Udáva sa ako celé číslo, pričom element s väčším číslom bude nad elementom s menším číslom. Maximálna a minimálna povolená hodnota nie je nejak oficiálne určená, bude zrejme závisieť od toho, ako si daný browser zapisuje integery. (Tj rátajte s rozsahom typu -2^(32), … 2^(32) ).

Ak si budete ako z-index dávať nejaké čísla okolo nuly, určite nič nepokazíte.

POZOR! Z-index funguje iba na elementy, ktoré majú position iný, ako static. Ak ho chcete použiť na element typu static, dá sa to obísť tým, že si svoj static element premeníte na relative, ale nikam vedľa neposuniete.

CSS selectory:

Selector určuje, na ktoré elementy sa bude daný kus kódu z css vzťahovať. Základné selectory v css (vrátane tých, čo už poznáme) sú:

Ak ste už s tým aspoň trochu zžití, môžeme sa pozrieť na ďalšie možnosti.

Pozn.: týchto kombinačných selectorov a pseudoselectorov je v skutočnosti omnoho viac, vybrala som iba tie čo sa mi zdali šikovné.

SAMOSTATNÁ ÚLOHA

Dnes to bude také hravejšie.

Tu máte k úlohe vzorové riešenie. Ja som k nemu použila dva obrázky, ghost.png a bubble.png.

Táto úloha nie je úplne priamočiara, existuje viacero relatívne rozličných spôsobov ako to riešiť - môžu byť ekvivalentne dobré. Ak sa vám podarí urobiť funkčné riešenie ale s veľmi neefektínym kódom, považuje sa to za správne riešenie. Elegantné riešenia väčšinou človeka napadnú až keď to najprv pred tým urobí zdĺhavo. Priložené obrázky môžete (a nemusíte) využiť, ak si vymyslíte riešenie, čo potrebuje viacero obrázkov, kľudne si narobte ďalšie.

Ak sa vám bude zdať, že tie pozície a vzdialenosti sa chovajú úplne debilne, tak je to preto, že máte pravdu. Resp. ono za tým je aj nejaká logika, ale chvíľku trvá, kým sa s tým človek zžije.

Úloha je rozdelená na štyri časti. Je to preto, aby ste cestou mali nejaké checkpointy. Ak sa vám podarí iba prvá, nevadí, pošlite mi to aj tak.

Úlohu mi pošlite ako .zip, v ktorom bude všetko zbalené (html+css+všetky obrázky):