Blog / Zaujalo ma

Ako na responzívne obrázky

CSS css html img

Keď chceme spraviť responzívne obrázky, musíme riešiť 3 veci naraz: -aby obrázok nepretiekol z kontajnera (mobil vs desktop) -aby stránka neskákala pri načítaní (rezervovať miesto) -aby sa obrázky nenačítavali zbytočne (lazy loading + správna veľkosť)

<div class="ukazka"> <img src="https://picsum.photos/id/237/600/400" alt="obrázok čierneho psa" width="600" height="400" loading="lazy" decoding="async" > </div> .ukazka { border: 1px solid #a50000; max-width: 800px; /* len aby bolo vidno, že kontajner môže byť užší */ margin: 2rem auto; } /* 1) ZÁKLAD: obrázok sa prispôsobí šírke kontajnera / .ukazka img { display: block; /* odstráni "medzeru pod obrázkom" (baseline) * / max-width: 100%; /* nikdy nebude širší než rodič * / height: auto; /* zachová pomer strán */ } 1) Prečo obrázky často “rozbijú” mobil? Lebo majú natvrdo šírku (alebo prídu veľké) a kontajner je menší. Riešenie je vždy toto duo: max-width: 100% , height: auto To znamená: keď je kontajner úzky (mobil), obrázok sa zmenší, keď je kontajner široký, obrázok môže byť vo svojej prirodzenej veľkosti, ale nepretečie. 2) “Pripraviť miesto” pre obrázok ešte pred načítaním (aby stránka neskákala) To je presne ten moment, keď sa načíta obrázok a celý text pod ním odskočí. Najjednoduchšie a najlepšie riešenie: dať obrázku width a height atribúty . <img src="..." width="600" height="400"> Prečo to funguje? Prehliadač si vie dopredu vypočítať pomer strán (aspect ratio) , teda si hneď rezervuje správnu výšku miesta a keď sa obrázok načíta, nič sa neposúva. Toto je dnes najpraktickejší spôsob. CSS max-width: 100% stále funguje, len miesto je dopredu rezervované . 3) Lazy loading: nech sa obrázky načítajú až keď treba Keď máš stránku dlhú a pod prvým ekranom sú obrázky, je zbytočné ich sťahovať hneď. Stačí: loading="lazy" Takže: <img src="..." loading="lazy"> Kedy nedávať lazy ? Na hlavný obrázok hore (hero, prvý vizuál na stránke). Ten chceš mať rýchlo, nie “neskôr”. 4) decoding="async" (malý bonus) decoding="async" Hovorí prehliadaču: “dekóduj obrázok mimo hlavnej práce stránky, keď sa dá.” Nie je to zázrak, ale je to čisté a bezpečné nastavenie. 5) Keď chceš rovnaký “výrez” na všetkých zariadeniach (ako banner) Toto je iná situácia: nechceš zachovať celý obrázok, chceš aby vyplnil box. Vtedy robíme toto: .ukazka { border: 1px solid #a50000; aspect-ratio: 3 / 2; /* box má stále rovnaký pomer */ overflow: hidden; /* čo trčí, odrežeme */ } .ukazka img { width: 100%; height: 100%; object-fit: cover; /* vyplní box, oreže okraje */ display: block; } Rozdiel: height: auto = ukáže celý obrázok (len sa zmenší) object-fit: cover = vyplní box, ale časť odreže (ako “crop”) 6) Najčastejšie chyby chýba max-width: 100% → obrázok pretiekne z kontajnera obrázok je inline → “medzera pod obrázkom” (rieši display:block ) bez width/height → stránka môže skákať pri načítaní lazy na prvom (hero) obrázku → paradoxne spomalíš vizuál hore Moderný základ: responsívne zdroje (srcset + sizes) = mobil stiahne menší súbor, desktop väčší moderný formát (WebP/AVIF) + fallback cez <picture> Doteraz sme riešili: aby obrázok nepretiekol (max-width/height auto), aby neskákala stránka (width/height), aby sa neťahalo všetko hneď (lazy). Ale stále môže byť problém: mobil si stále stiahne 600×400 , aj keď ho zobrazuje napr. len 320px široký. A to je tá “neporiadnosť” v praxi (zbytočné dáta). (reálne pre web) – <picture> + srcset + sizes HTML <body> <h1>Obrázky poriadne: responsive + webp + bez skákania</h1> <div class="ukazka"> <picture> <!-- 1) moderný formát --> <source type="image/webp" srcset=" /images/dog-320.webp 320w, /images/dog-600.webp 600w, /images/dog-1000.webp 1000w " sizes="(max-width: 700px) 100vw, 700px" > <!-- 2) fallback (jpg/png) --> <img src="/images/dog-600.jpg" srcset=" /images/dog-320.jpg 320w, /images/dog-600.jpg 600w, /images/dog-1000.jpg 1000w " sizes="(max-width: 700px) 100vw, 700px" alt="obrázok čierneho psa" width="600" height="400" loading="lazy" decoding="async" > </picture> </div> </body> CSS (rovnaký základ) * { margin: 0; padding: 0; box-sizing: border-box; } .ukazka { border: 1px solid #a50000; max-width: 700px; margin: 2rem auto; } .ukazka img { display: block; max-width: 100%; height: auto; } Prečo takto? 1) srcset = viac veľkostí toho istého obrázka Hovoríš prehliadaču: „Tu máš 320/600/1000… vyber si.“ 2) sizes = koľko bude obrázok reálne veľký na stránke Toto je kľúčové. Bez sizes si prehliadač často vyberie väčší súbor “pre istotu”. sizes="(max-width: 700px) 100vw, 700px" znamená: keď je viewport do 700px → obrázok bude približne na celú šírku okna inak bude mať max 700px 3) <picture> = moderný formát + fallback Keď prehliadač vie WebP, zoberie WebP. Keď nevie, spadne na <img> (jpg/png). Keď chceme použiť srcset + sizes , tak najskôr musíme mať viac verzií toho istého obrázka (rôzne šírky). Lebo prehliadač si nemá z čoho vybrať, ak mu dáš len jeden súbor. Čo to znamená v praxi Musíš mať napríklad tieto súbory (ten istý obrázok, len zmenšený): dog-320.jpg (pre mobily) dog-600.jpg (stred) dog-1000.jpg (desktop) a ideálne aj to isté vo WebP: dog-320.webp dog-600.webp dog-1000.webp Až potom má zmysel napísať: < img src = "/images/dog-600.jpg" srcset = "/images/dog-320.jpg 320w, /images/dog-600.jpg 600w, /images/dog-1000.jpg 1000w" sizes = "(max-width: 700px) 100vw, 700px" > Prečo to robíme mobil si stiahne 320w (malý súbor), desktop si stiahne 1000w (kvalita), a ty nepreplácaš dáta tam, kde netreba.

Zarovnanie, zalomenie textu v <p>

CSS <p> css

Správanie textu: zalamovanie, riadky, „…“

Zarovnanie textu v <p> : zalamovanie, riadky, „…“ HTML šablóna <body> <div class="ukazka"> <p> "nejaký text" </p> </div> </body> CSS štart .ukazka { border: 1px solid #a50000; padding: 16px; } /* tu budeme skúšať vlastnosti */ .ukazka p { border: 1px solid #4c7460; max-width: 65ch; } 1) Zarovnanie textu (text-align) 1.1 Default (vľavo) text-align: left; .ukazka p { border: 1px solid #4c7460; max-width: 65ch; text-align: left; } Toto je bežné správanie: text začína vľavo a končí tam, kde skončí riadok. 1.2 Stred text-align: center; .ukazka p { border: 1px solid #4c7460; max-width: 65ch; text-align: center; } Text je vycentrovaný. Použiteľné skôr na krátke texty (napr. nadpisy), nie na dlhý odsek. 1.3 Vpravo text-align: right; .ukazka p { border: 1px solid #4c7460; max-width: 65ch; text-align: right; } Skôr výnimočne (napr. podpis, cena, čísla). 1.4 Do bloku (justify) text-align: justify; .ukazka p { border: 1px solid #4c7460; max-width: 65ch; text-align: justify; } Tu sa deje to, že prehliadač „roztiahne medzery“ tak, aby riadok končil pekne zarovno vpravo aj vľavo. Pozor na nevýhodu: niekedy vzniknú divné veľké medzery medzi slovami. Ak chceš, môžeš to trochu „zjemniť“ s hyphens: .ukazka p { border: 1px solid #4c7460; max-width: 65ch; text-align: justify; hyphens: auto; } hyphens: auto; umožní delenie slov (funguje lepšie, keď má dokument správny jazyk, napr. lang="sk" na <html>, ale nie bezchybne ). 2) Zalamovanie textu (wrap) Zalamovanie znamená: „čo sa stane, keď sa text už nezmestí do šírky“. 2.1 Normálne správanie (default) .ukazka p { border: 1px solid #4c7460; max-width: 65ch; white-space: normal; } Text sa láme medzi slovami. 2.2 Keď máš dlhé slovo / URL a nechce sa zalomiť Príklad: veľmi dlhý string bez medzier (link, hash, kód). <body> <div class="ukazka"> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugiat excepturi, est eligendi incidunt quia error itaque minima voluptatum quas voluptas eos magni magnam repellat architecto possimus at, accusantium delectus accusamus hic modi ipsam molestiae repudiandae praesentium. Facere amet veritatis natus. A teraz dlhé slovo bez medzier: superdlheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee A teraz URL: https://example.com/nejaka/straaasne/dlha/cesta/bez/medzier/aby/sme/videli/co/sa/stane </p> </div> </body> Najpraktickejšie je toto: .ukazka p { border: 1px solid #4c7460; max-width: 65ch; overflow-wrap: anywhere; } Alebo miernejšia verzia: .ukazka p { border: 1px solid #4c7460; max-width: 65ch; overflow-wrap: break-word; /* často stačí */ } Polopate: anywhere = „ak treba, zlom to hocikde, aj v strede slova“ break-word = „zlom to, keď naozaj musíš“ 3) Koľko riadkov zobraziť (line-clamp) „Ukáž mi len 3 riadky z odseku“, čo chceš napríklad na kartičkách (výpis blogu, produkty, zoznam). 3.1 Ukáž len 3 riadky a zvyšok schovaj .ukazka p { border: 1px solid #4c7460; max-width: 65ch; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } Ako to funguje: povieš: „tento text bude ako krabička s riadkami“ a potom povieš: „dovoľ iba 3 riadky“ a zvyšok „odrež“ ( overflow: hidden ) 4) Ukončenie „…“ (ellipsis) Tu sú 2 situácie: 4.1 „…“ pre 1 riadok Keď chceš, aby bol text len na jednom riadku a potom ... .ukazka p { border: 1px solid #4c7460; max-width: 65ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } Polopate: nowrap = „nezalamuj, drž to v jednom riadku“ overflow: hidden = „čo sa nezmestí, skry“ ellipsis = „na koniec daj tri bodky“ 4.2 „…“ pre viac riadkov (napr. 3 riadky) Tu sa používa práve line-clamp (z bodu 3). Prehliadač spraví „…“ automaticky podľa možností. .ukazka p { border: 1px solid #4c7460; max-width: 65ch; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } 5) Extra: presná výška odseku cez line-height Niekedy chceš mať „pevný layout“: napr. každý card má rovnakú výšku textu. .ukazka p { border: 1px solid #4c7460; max-width: 65ch; line-height: 1.4; max-height: calc(1.4em * 3); overflow: hidden; } Toto je „ručná verzia“: presne povieš „3 riadky“. Nevýhoda: nie je to také pohodlné ako line-clamp .

height

CSS css height

height - výška prvku

Článok: CSS height – výška prvku bez kúziel a nervov height: auto (predvolené správanie) Ak nič neriešime, prehliadač to urobí za nás. auto znamená: výška = toľko, koľko potrebuje obsah text pribudne → výška sa zväčší text zmizne → výška sa zmenší Toto je default , aj keď height vôbec nenapíšeš. .ukazka { height: auto; } Používaj vždy, keď nechceš nič „lámať“, máš dynamický obsah (texty, CMS, blog) Pevná výška ( px ) Ak chceme presnú výšku, musíme ju natvrdo povedať. .ukazka { height: 100px; } Čo sa stane: prvok má vždy 100px, obsahu je jedno, či sa zmestí Problém: veľa textu → pretečie, málo textu → prázdne miesto Používaj len keď: robíš ikonky, bannery, karty, presne vieš, čo tam bude Percentá ( % ) – častý zdroj zmätku Ak chceme výšku v %, rodič MUSÍ mať výšku. Ak nemá výšku rodič, len toto NEBUDE fungovať : .ukazka { height: 50%; } Prečo? - prehliadač nevie: 50% z čoho? Správny postup: html, body { height: 100%; } .ukazka { height: 50%; } Pravidlo: percentá výšky fungujú len ak rodič má definovanú výšku . min-height a max-height – najpraktickejšie riešenie Ak nechceme prvok „zabiť“, ale len obmedziť. .ukazka { min-height: 100px; } nikdy nebude menší ako 100 px, môže rásť podľa obsahu .ukazka { max-height: 200px; } nikdy nebude vyšší ako 200 px, obsah môže pretekať Často spolu: .ukazka { min-height: 100px; max-height: 300px; } Toto je zdravý kompromis . Viewport jednotky ( vh , svh , lvh , dvh ) Ak chceme výšku podľa okna prehliadača. .ukazka { height: 100vh; } 100vh = celá výška obrazovky (ak sú nejaké prvky pred a za{nad a pod} , tie sa prirátajú k výške, vznikne scrollbar na boku.) Pozor na mobil: adresný riadok mení výšku → skákanie obsahu height: 100% - závisí od rodiča height: 100vh - ignoruje rodiča aj súrodencov Je to absolútna jednotka , nie relatívna k layoutu. Novšie jednotky (mobil-friendly) height: 100svh; /* small viewport */ - Najmenšia možná výška okna height: 100lvh; /* large viewport */ - Najväčšia možná výška okna height: 100dvh; /* dynamic viewport */ - Aktuálna výška okna v danom momente Na mobile sa deje toto: hore máš adresný riadok, keď scrolluješ, schová sa, tým pádom sa zmení výška viditeľnej obrazovky Staré 100vh sa správa takto: raz ráta s adresným riadkom, raz bez neho, výsledok: skákanie layoutu "svh": ráta aj s adresným riadkom, ráta s najhorším scenárom a už to nemení. "lvh": počíta výšku tak, akokeby adresný riadok neexistoval. Ale adresný riadok tam stále je, len výpočet výšky je väčší než aktuálne viditeľná plocha. Preto prvok má väčšiu výšku, časť je schovaná pod adresným riadkom, môže vzniknúť scroll. lvh je určené pre prostredia, kde je viewport trvalo maximálny – typicky PWA alebo fullscreen aplikácie, nie klasické webové stránky. "dvh": znamená „Daj mi výšku okna takú, aká je PRÁVE TERAZ.“ Čo sa deje: scrolluješ → adresný riadok zmizne → výška sa zväčší, scroll hore → adresný riadok sa vráti → výška sa zmenší. Áno: mení sa, prepočítava sa, layout reaguje. Toto je viewport jednotka , ktorá je zámerne dynamická. Podpora (Can I Use): vh → OK všade svh / lvh / dvh → moderné prehliadače (Chrome, Safari, Firefox nové verzie) staré prehliadače → fallback Bezpečný zápis: .ukazka { height: 100vh; height: 100dvh; } (prehliadač si vezme to, čo pozná) viewport ≠ automaticky fullscreen dvh , svh , lvh nie sú príkaz „zaber celú obrazovku“ . Sú to len mierky . Takže: height: 30dvh; znamená iba: „Tento prvok má mať 30 % výšky aktuálneho viewportu.“ Kedy to už zmysel má (aj vo vnútri stránky) Hero / vizuálna sekcia, ale nie fullscreen .hero { min-height: 40dvh; } Nechceš celú obrazovku, chceš konzistentný vizuálny dojem, bez ohľadu na výšku zariadenia. „Okno“ v stránke (mapa, kalendár, preview) .calendar { height: 50dvh; } Má to byť „pol obrazovky“, zvyšok je text, reaguje to na zmenu viewportu. Limity, nie príkazy Veľmi zdravý pattern je: .section { min-height: 30svh; max-height: 60svh; } Čo tým hovoríš: nech nie je smiešne malá, nech nezaberie celú stránku, viewport slúži len ako mierka . Kde je hranica, kedy to začne byť divné Divné to je vtedy, keď: .card { height: 100dvh; } a karta je súčasťou článku, nemá význam „obrazovky“, ignoruje rodiča. Vtedy vzniká pocit: „prečo sa tento prvok tvári ako stránka?“ Nie preto, že je to dvh . Ale preto, že je to 100 . Viewport jednotky nie sú o hierarchii , ale o mierke . % → mierka voči rodičovi vh / dvh / svh → mierka voči obrazovke Použiť ich môžeš na 100 % (layout obrazovky), ale aj na 20–60 % (vizuálne proporcie) height vs line-height (častý omyl) height = výška boxu line-height = výška riadku textu .ukazka { height: 50px; line-height: 50px; } Text bude vertikálne vycentrovaný (1 riadok). Zhrnutie Nechcem riešiť → height: auto Chcem presnú výšku → px Chcem minimálnu / maximálnu → min-height , max-height Chcem podľa obrazovky → vh (+ dvh ) Percentá → iba ak rodič má výšku

Zarovnanie prvku - horizontálne

CSS css

Ako dať prvok, napríklad v <div> na stred.

Zarovnanie prvku: ako dať <div> na stred (polopate) Keď začíname s CSS, najväčší zmätok je v tom, že “stred” môže znamenať dve rôzne veci: text vnútri prvku je na stred samotný prvok (box) je na stred stránky A to sú dve úplne iné pravidlá. 1) Základ: <div> je defaultne display: block To znamená: <div> si zoberie celý riadok čiže jeho šírka je (prakticky) 100% rodiča ďalší prvok pôjde automaticky pod neho Spravíme si ukážku s borderom, aby bolo vidieť “box”. HTML <body> <h1>blog</h1> <div class="ukazka">Ukážka</div> </body> CSS * { margin: 0; padding: 0; box-sizing: border-box; } .ukazka { border: 1px solid #a50000; } Výsledok: uvidíš červený rámik, ktorý ide cez celú šírku stránky . To nie je chyba — to je presne to, čo robí block . 2) Keď je prvok cez celú šírku, “centrovať” vieme len jeho obsah Ak má box šírku 100%, tak ho nemá zmysel “posúvať do stredu” — lebo on už je všade. Čo ale vieme spraviť: dať text vnútri na stred. .ukazka { border: 1px solid #a50000; text-align: center; padding: 2rem; } Box stále ide cez celú šírku, ale nápis „Ukážka“ je uprostred. Padding-om (vnútornými okrajmi) sme si len zväčšili prvok. Toto je prvé pravidlo: Keď je prvok block a zaberá celú šírku, centrovanie riešime cez text-align (centruje obsah, nie box). 3) Kedy má zmysel “div dať na stred” ako box? Až vtedy, keď ten box nie je cez celú šírku . Čiže keď ho “zmenšíme”. A prečo ho zmenšovať? Lebo keď chceš mať napríklad “kartičku”, “badge”, “štítok”, “box s obsahom” — nechceš, aby to bolo roztiahnuté cez celú stránku. 4) Zmenšíme box na šírku obsahu Najjednoduchší trik: .ukazka { display: inline-block; border: 1px solid #a50000; padding: 2rem; } Box už nebude 100% široký. Bude “tak veľký, ako potrebuje”. Lenže teraz vzniká ďalšia vec: Inline-block sa centrovať dá cez text-align , ale na rodičovi. 5) Keď je prvok “zmenšený”, musíme povedať “v čom” má byť na strede - a to je kľúčové. Varianta A: dám text-align: center na rodiča - body (rýchle, ale môže centrovať všetko) body { text-align: center; } .ukazka bude v strede, lebo je inline-block . Ale pozor: budeš centrovať aj iné veci v body (texty, linky…). Varianta B: obalíme to wrapperom (obalom, <div class="center">, čisté riešenie) HTML: <body> <h1>blog</h1> <div class="center"> <div class="ukazka">Ukážka</div> </div> </body> CSS: .center { text-align: center; } .ukazka { display: inline-block; border: 1px solid #a50000; padding: 2rem; } Len tento jeden blok bude centrovaný. h1 ostane normálne. Druhé pravidlo: Keď prvok zmenšíš (napr. inline-block), musíš centrovanie riešiť cez rodiča — lebo rodič je tá “plocha”, v ktorej sa to má zarovnať. 6) Alternatíva: zmenším box a vycentrujem ho cez margin: 0 auto Toto je “klasika” pre bloky. Funguje, ak: prvok je block „ margin: 0 auto funguje len keď prvok nie je 100% široký (t.j. má šírku/je zmenšený).“ .ukazka { border: 1px solid #a50000; padding: 2rem; width: fit-content; margin: 0 auto; } Box sa zmenší na šírku obsahu a posunie sa na stred. Mini-zhrnutie (čo si zapamätať) <div> je defaultne block → zaberá celý riadok keď je box 100% široký → centrovať vieš hlavne obsah ( text-align:center ) keď chceš centrovať box , musí byť užší než rodič keď je inline-block → centrovanie riešiš cez text-align na rodičovi keď je block so šírkou → centrovanie riešiš cez margin: 0 auto Centrujem text vnútri → text-align: center na prvok Centrujem box → box musí byť užší a buď: margin: 0 auto (block + šírka) alebo text-align: center na rodiča (inline-block)