Esenciálne CSS tipy a triky

napísal , 8 Nov 2010 [ CSS ]

CSS je slušný bordel. Nie že by sa s ním nedalo pracovať, avšak aby ho dizajnér donútil vypľuť zo seba ako-tak-modernú stránku, potrebuje poznať riadnu dávku trikov, odžubov a čiernej mágie.

V tomto článku predstavíme problémy, s ktorými sa web-človek bežne stretáva, ukážeme si riešenia a nakoniec možno prihodíme pár užitočných tipov a možno aj trikov. Ak budete poslúchať. ;)

Predtým ale odporúčam mrknúť na HTML inline a block elementy. Článok tiež predpokladá aspoň základnú znalosť CSS. Ak také nemáte, nevadí, zastavíte sa neskôr :) Ok? Let's go.

Horizontálne centrovanie

Na zarovnanie textu na stred máme text-align: center; ale pre block elementy (ako <div>) nič podobné neexistuje. Čo je problém v dobe, kedy je väčšina stránok na stred obrazovky.

Riešenie: nastaviť centrovanému elementu pevnú šírku a margin: 0px auto;

centrovanie cez margin

V tomto prípade bude #box2 zhora a zdola odsadený o 15px a zo strán o "auto", čo prehliadač chápe tak, že ho má hodiť na stred rodiča - čiže do stredu divu #container.

#container { 
   width: 960px;
   text-align: center; 
}
#box { 
   width: 500px; 
}
#box2 { 
   width: 500px; 
   margin: 15px auto;
}

Vertikálne centrovanie

Vycentrovať block elementy vertikálne nie je pomocou margin: auto; triku možné a vyžaduje si toľko čarovania, že to až pekné neni. Naštastie také niečo zväčša nebýva potrebné. Každopádne, pre zvedavých: Vertical Centering With CSS.

Najčastejšie potrebujem vertikálne vycentrovať obrázok.
Riešenie: vertical-align: middle; na obrázok.

Do you know a girl with hair like this: hair like this ?

Do you know a girl with hair like this: hair like this ?

img { vertical-align: baseline; }

img { vertical-align: middle; }

Naľavo sú vlasy zarovno písmom (toto je štandardné nastavenie), napravo sú na stred riadku.

Prípadne chcem aby bol text presne v strede riadku pevnej výšky.
Riešenie: height: 100px; line-height: 100px;

purple hair = HAIR

Stačí aby výška riadku a výška elementu boli rovnaké a text je v strede.

p {
  height: 100px; line-height: 100px; text-align: center;
  padding: 15px; border-radius: 5px; border: 1px solid #efefef; 
}

Ak by však text presahoval dĺžku jedného riadku, medzery medzi jednotlivými riadkami by boli obrovských 100px. Takže pozor na to. V takom prípade by ste boli nútení hrať sa s padding/margin hodnotami, prípadne použiť position.

Position

Ah, spomínaj čerta ;) CSS atribút position nám dovoľuje na pixel presne určiť, kde sa bude element na stránke nachádzať.

Môže nadobúdať hodnoty: position: relative | absolute | fixed pričom za normálnych okolností majú všetky elementy position: static;.

Funguje to asi takto - ak sa zmení position, môžeme pozíciu elementu kontrolovať pomocou left: 10px a top: 5px;. Rovnako sa dá použiť aj right a bottom. Čo sa bude s elementom diať, záleží od position...

position: absolute;

w3schools píše "position: absolute vytvorí element umiestnený relatívne voči prvému z rodičov s position iným ako static". Toto...

#box { 
  position: absolute; left: 100px; top: 100px; 
}

...by #box odsadilo o 100px od ľavého horného rohu stránky - zľava o 100px, zhora o 100px. Ak by #box mal rodiča s position: relative;, bol by odsadený od ľavého horného rohu tohto rodiča.

position: relative;

Takže ešte raz. Ak pridáme elementu position: relative;, všetky jeho deti s position: absolute; sa budú posúvať vrámci tohto rodičovského elementu. Zároveň ale môžeme používať left, right a tak, takže ak len potrebujem niečo posunúť o 2px dole, môžem spraviť position: relative; top: 2px;.

Rozdiel je, že absolute element odpojí od "document flow", čiže ak element posuniem nad text, text bude prekrytý a dokument bude pokračovať ako keby sa nechumelilo. Pri position: relative sa chumelí. Look here:

gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule

gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule

gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule

gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule gule

position: absolute;

position: relative;

Máme dva <p> s textom a medzi nimi <div> - ten štvorec. Naľavo vidíme odstavce pekne oddelené od seba, všetko vyzerá tak ako má, len nad tým poletuje štvorec. Napravo je medzi odstavcami mega medzera a to preto, lebo je medzi nimi 75px vysoký <div>. Posunutý je len vizuálne, v dokumente je stále pevne na svojom mieste.

.nechumeli, .chumeli { background: pink; width: 75px; height: 75px; }
.nechumeli {
  position: absolute;
  top: 25px; 
  left: 40px;
}
.chumeli {
  position: relative;
  top: 25px; 
  left: 40px; 
}

Vidíme tiež, že napriek rovnakým hodnotám top a left je pozícia štvorca rozdielna. Pri absolute totiž posúvame o 30px od vrchu rodiča, pri relative o 30px od vlastnej pozície elementu. Dajú sa použiť aj mínusové hodnoty, pričom top: -70px; je ekvivalent bottom: 70px; a rovnako fungujú aj left a right.

position: fixed;

Ak chceme aby nám nejaký dríst poletoval 150px od vrchu okna prehliadača, spravíme:

#drist {
  position: fixed;
  top: 150px;
}

Keďže poletuje 150px od vrchu okna prehliadača, bude stále na tom istom mieste, aj keď budeme scrollovať hore dole po stránke. V IE6 to nefunguje, kuk sem pre fix.

z-index

Ak sa nám elementy prekrývajú, pomocou z-index vieme určiť, ktorý má byť navrchu atď. Stojí to za zmienku, pretože z-index funguje iba na elementy s position: relative | absolute | fixed;.

z-index: 1
z-index: 0
z-index: 2

Hlavná stránka a sidebar vedľa nej

Block elementy zaberajú plnú šírku svojho rodiča a okupujú vlastný riadok. Takže ak máme dva <div>y, zobrazia sa pod sebou. Block elementy sú zároveň práve tie elementy, ktoré sa používajú na obaľovanie ostatných - napríklad <div id="main"> pre hlavnú stránku a <div id="sidebar"> pre sidebar. A potrebujeme ich vedľa seba.

Ak elementu nastavíme float: left, stratí šírku rodiča a "odpláva" na ľavú stranu, pri float: right odpláva na pravú stranu. Ak máme dva float: left elementy, zobrazia sa vedľa seba. Tak to skúsme:

#main {
  float: left;
  width: 150px;
}
#sidebar {
  float: left;
  width: 80px;
}

Ok, sú vedľa seba. Je to zmenšený ekvivalent toho, čo by sme spravili pri dizajne rozloženia stránky - nastaviť jednotlivým #main a #sidebar pevnú šírku a float: left.

Nasledovné elementy (ako tento text) sa však zobrazia vedľa nich. Čo je fajn, ak by sme naľavo mali obrázok či citát a chceli by sme aby text okolo neho obtekal - nastavíme float: left, hodíme mu margin a hotovo.

V tomto prípade je to však problém. Ak má naša stránka mať footer, chceme ho dole a nie takto divne napravo. Po tom čo dofloatujeme elementy, potrebujeme ich "plávanie" takpovediac zrušiť, inak ovplyňuje aj elementy, u ktorých to nemusí byť žiaduce.

.container

#main
#sidebar

Riešenie: obaliť floatované elementy do kontajnera s overflow: hidden. Prečo? Ak všetci potomkovia rodiča floatujú, rodič nemá žiadnu výšku. Huh? Nuž.. je to tak :) overflow: hidden to napraví, rodič pekne obalí floatovaných potomkov a všetko čo je pod rodičom sa teda zobrazí tam kde má - pod rodičom.

<div class="container">
  <div id="main">
    #main
  </div>
  <div id="sidebar">
    #sidebar
  </div>
</div>
<div id="footer">
  #footer
</div>
.container { overflow: hidden; }
.container, #footer {
  margin: 35px auto; width: 350px; 
}
#main {
  width: 200px; float: left; 
  margin-right: 20px;
}
#sidebar {
  width: 130px; float: left;
}

Ak by nebolo možné použiť overflow: hidden dá sa za floatované elementy pridať toto...

<div style="clear: both;"><!-- --><div>

...a je to fixed. Existujú aj iné spôsoby, reálne používam len tieto dva, takže ostatné necháme tak.

Dôležité: ak floatujete elementy a robí to neplechu, spomeňte si na tento text :)

Internet Explorer *sigh*

Ok. Že vám IE (6&7) dosere dizajn, na to sa môžete spoľahnúť. Mnohé problémy sa dajú vyriešiť skúšaním, zvolením iného postupu a prepisovaním CSSka až kým to mirakulózne nezačne fungovať všade, vrátane IE. Niekedy to ale nejde.

Samostatné CSS len pre IE

Ak je problémov veľa, stojí za to vytvoriť CSS špeciálne pre IE a v ňom všetko opraviť:

<!--[if lt IE 8]>
  <link rel="stylesheet" href="style-ie.css">
<![endif]-->

niečo takéto pridáte do hlavičky html dokumentu, pod link na normálne css

Ide o HTML komentár s tým, že všetko čo sa nachádza medzi <!--[if IE]> a <![endif]--> vidí len Internet Explorer. Nemusí to byť len odkaz na CSS. Komentár môže obsahovať prakticky čokoľvek, kľudne JavaScript alebo dokonca aj HTML kód, aj keď to zrovna neodporúčam :)

Dokonca je možné presne určiť verziu prehliadača, like this:

[if IE 6] vidí len IE6.

[if lt IE 8] znamená "ak na toto človek čumí cez IE menej ako 8 (lt = less than = menej ako) tak...". Čiže to bude platiť pre 7, 6, 5...

[if lte IE 8] by znamenalo "ak menej alebo rovné 8 (lte = less than or equal = menej alebo rovné)".

IE hacks

Ak blbne len pár maličkostí a samostatný súbor sa zdá prehnaný, je možné použiť takzvané IE hacks:

body {  
 background: black;  /* všetky prehliadače */  
 background: red\9;  /* IE8 a dole */  
 *background: green; /* IE7 a dole */  
 _background: blue;  /* IE6 */  
}  

Ok, čo je toto za bordel? V prvom rade: ak v CSS napíšete nejaký nezmysel, preklep, neexistujúci atribút alebo čokoľvek, čomu prehladač nerozumie, jednoducho sa to odignoruje. Rôzne verzie IE ale reagujú na rôzne znaky.

ie hacks

Ak za hodnotu atribútu pridáte \9 uvidia to IE verzie 8 a dole. Čiže ak by sme mali v hore uvedenom CSS len prvé 2 riadky, všetky CSS staršie ako 8 plus osmička, by zobrazili červené pozadie.

Ak však pridáme ďalší atribút, tentoraz s predponou * rozprávame sa s IE7 a dole. Takže v IE8 je pozadie červené, v starších zelené.

_ je to isté pre IE6.

Kým _color: red; je pre normálne prehliadače nezmysel, IE6 vidí color: red;. Všetci ignorujú, IE6 počúva.

Praktické využitie: zadáte margin-left: 20px ale IE6 to zobrazí ako 40px (v istých prípadoch). Ak je toto jediný problém, stačí takýto fix:

.brm { margin-left: 20px; _margin-left: 10px; }

Aj keď sú mnohí proti, hacky sú v poriadku. Stráviť hodiny hľadaním alternatívnych všade-fungujúcich riešení je vo väčšine prípadov zbytočné hrdinstvo a zabitý čas. Rovnako je zbytočné používať IE-only CSSko, ak je problémov len zopár. Ak ich však máte kopec, je určite lepšie vybaviť si to v samostatnom súbore.

Samozrejme, najprv s problémom bežte na google a k podobným záležitostiam sa uchýľte, až keď do 5 minút nenájdete jednoduché riešenie :)

Prečo sú mnohí proti? Vraj nie je možné zaručiť, že prehliadače budú hacky rozpoznávať naveky - čo ak niekto vydá update a fixne tento bug? Nuž, v tom prípade pokazí internety, tie sú totiž plné "hacknutých" CSSiek, a to si nikto nedovolí ;)


Toto je prvý zo série mega-článkov s CSS tematikou. Ostatné:

napísal , 8 Nov 2010

18 komentárov

komentuj ku každému komentáru sa v databáze ukladá iba meno, text a dátum, iba za účelom zobrazenia pod článkom
neukladá sa email, IP adresa ani informácie o prehliadači a údaje sa nepoužívajú na reklamu, newsletter, na žiadnu ekonomickú aktivitu, nikam sa neposielajú, sú v databáze len aby sa mohli zobraziť pod článkom
  1. maralok [ Utorok 16.11.2010, 12:00 ]

    Chtěl bych se zeptat, k odstavci "Hlavná stránka a sidebar vedľa nej".

    .container { overflow: hidden; }
    .container, #footer {
    margin: 35px auto; width: 350px;
    }
    #main {
    width: 200px; float: left;
    margin-right: 20px;
    }

    Jakej je rozdíl mezi .main (class) a #main (id)? Jde mi o to kdy správně psát "tečku" a kdy "sharp".

  2. yablko [ Utorok 16.11.2010, 16:40 ]

    ak máš v html <div id="main">, tak v css napíšeš #main
    ak máš <div class="main">, napíšeš .main

    id sa používa ak je element na stránke len jeden, napríklad header bude zrejme vždy len jeden, takže <div id="header">

    class sa používa, keď je toho viac.. napríklad ak máš blog a na stránke kopu príspevkov, tak napíšeš <div class="prispevok">

    jedno = id
    viac = class

    so yeah... :)

  3. maralok [ Streda 17.11.2010, 22:59 ]

    dik :)

  4. yablko [ Štvrtok 18.11.2010, 00:44 ]

    neni zač:)

  5. jaqkit [ Utorok 26.7.2011, 16:45 ]

    velmi dobry clanok, niektore veci som vobec nevedel :D

  6. J [ Piatok 16.9.2011, 02:02 ]

    K casti "Hlavná stránka a sidebar vedľa nej" co sa tyka ukoncenia dedenia tych obtekani #main a #sidebar ja na to pouzivam co vy nato?

  7. J [ Piatok 16.9.2011, 02:05 ]

    kod sa akosi nezobrazil takze takto: div style=clear:both

  8. yablko [ Piatok 16.9.2011, 14:05 ]

    J: aj tak sa dá:) je to vlastne aj v texte spomenuté

  9. S [ Štvrtok 26.9.2013, 12:31 ]

    Ahoj chcela by som sa opytat....

    V tvojom priklade mas v kazdom " boxe" ( container, main a sidebar ) meno.
    V html kode #main a #sidebar vidim ale .container nie.
    Skusila som si napisat tvoj priklad, pridala som si do stylu aj backgroun-color a ostatne aby sa to zobrazilo presne ako v tvojom prikade. Vsetko ok az na text
    .container. Ked ho napisem do html tak sa mi nezobrazi hore v lavo v boxe container ale na pravej strane boxu #main a sidebar mi posunie pod main.
    Vies mi povedat preco?
    Inak fajn tipy....Dik

  10. yablko [ Štvrtok 26.9.2013, 13:34 ]

    kde konkrétne? ja tam vidím tento kód

    <div class="container">
    <div id="main">
    #main
    </div>
    <div id="sidebar">
    #sidebar
    </div>
    </div>
    <div id="footer">
    #footer
    </div>

    a tam je .container hneď hore, prvý riadok:)

  11. S [ Štvrtok 26.9.2013, 14:23 ]

    1

    2 TU by nemalo byt napisane .container
    aby sa to zobrazilo ako pomenovanie v sedom boxe container
    vlavo hore ako v tvojom priklade ?

    3
    4 #main
    5
    6
    7 #sidebar
    8
    9
    10
    11 #footer
    12

    Ja som to pochopila tak ze lavy stlpec je kod html a pravy css. V pravom stlpci vidim .container ale myslela som ze je to ako selector pre styl css takze v tom pripade v sedom boxe nie je nic napisane. No, a ked napisem .container do riadku 2 tak sa mi
    posunie ako som vysvetlila predtym.

    Ja som zaciatocnik tak sa prosim necuduj ak sa nahodou pytam na nezmysly)

  12. S [ Štvrtok 26.9.2013, 14:26 ]

    kod sa mi nezobrazil takze

    TU .container

    #main

    .
    .
    .
    .
    .

  13. S [ Štvrtok 26.9.2013, 14:29 ]

    sorry ale nezobrazuje sa mi kod

  14. S [ Štvrtok 26.9.2013, 17:30 ]

    Este stale nerozumiem ako je mozne ze v sedom boxe vlavo hore je napisane .container ked v kode html vnutri v div-e container nei je napisane .container
    a ked pouzijem tvoj priklad a napisem dnu do div-u container .container tak sa samozrejme zobrazi ale sa posunie na pravu stranu boxu #main ( nemam ziadny padding tak by text nemal byt vlavo hore v boxe container? suradnice 0 0)
    Prosim skus mi to vysvetlit lebo sa s tym uz dost natahujem a nic.
    Thanks

  15. yablko [ Štvrtok 26.9.2013, 21:18 ]

    počkaj:

    <div id="main">
    #main
    </div>

    na tom texte #main vo vnútri divu nezáleží
    to je len text, ktorý som tam napísal, aby som naznačil, ktorý CSS selektor k tomu patrí

    ale je jedno, čo tam je
    pokojne to mohlo vyzerať takto:

    <div id="main">
    vajčíská
    </div>

    je to iba text
    na texte nezáleží
    záleží na atribútoch:

    ak v HTML je id="gule", tak v CSS napíšeš #gule
    ak v HTML je class="vajcia", tak v CSS napíšeš .vajcia

    id (HTML) = # (CSS)
    class (HTML) = . (CSS)

    a to čo je vo vnútri tých elementov, to je druhá vec
    v CSS pristupuješ k elementom na základe atribútov, ako sú napríklad id="" alebo class=""

  16. S [ Piatok 27.9.2013, 08:40 ]

    Ok. Dakujem. Cele poobedie som studovala a akosi sa mi rozjasnilo. Hlavne pridavajte dalsie prispevky budem sledovat vas blog. A keby daco tak sa ozvem... ::))

  17. Ja neviem [ Utorok 6.1.2015, 18:39 ]

    Nevie mi prosim niekto poradit ako sa robí take menu ked scrollujete dole aby to islo s vami ako to ma napríklad twitter ? dakujem

  18. Marya [ Sobota 12.9.2020, 00:02 ]

    HOOJ...

    Ten blby float. Vsetko mi islo do lava, islo ma rozhodit, cely den pri tom sedim, uz mam dekubity😂😂... ale to zaklinadlo
    ......si vytapetujem...dakujem....

ku každému komentáru sa v databáze ukladá iba meno, text a dátum, iba za účelom zobrazenia pod článkom
neukladá sa email, IP adresa ani informácie o prehliadači a údaje sa nepoužívajú na reklamu, newsletter, na žiadnu ekonomickú aktivitu, nikam sa neposielajú, sú v databáze len aby sa mohli zobraziť pod článkom