skeleton skrýnTakéSkeleton UI, Skeleton loader, Content placeholder, Shimmer effectZákladní

Definice

Skeleton screen je způsob zobrazení načítacího stavu, při kterém rozhraní ukáže šedé obrysy budoucího obsahu (bloky místo textu, obdélníky místo obrázků) namísto spinneru. Uživatel tak vidí strukturu stránky dřív, než dorazí data, čekání mu připadá kratší a po dokreslení obsahu nedochází k poskakování rozvržení.

Kategorie: UX/UI designAktualizováno
<h2>Proč obrysy fungují líp než spinner</h2> <p>Spinner sděluje jedinou informaci: něco se děje. Skeleton screen sděluje navíc <strong>co</strong> se děje a <strong>kolik toho přijde</strong>. Uživatel vidí, že nahoře bude nadpis, pod ním tři karty a vpravo obrázek, takže si stihne zorientovat oko dřív, než data dorazí. Vnímaný čas čekání (perceived performance) klesá, i když se skutečná doba načtení nezmění ani o milisekundu.</p> <p>Druhý přínos je technický. Skeleton drží stejné rozměry jako cílový obsah, takže po jeho nahrazení nedojde ke skokové změně rozvržení. To přímo snižuje metriku Cumulative Layout Shift, kterou Google měří v rámci Core Web Vitals.</p> <h2>Z čeho se skeleton skládá</h2> <p>Skeleton je obvykle sada prázdných boxů s jednotnou barvou pozadí a zaoblenými rohy, které kopírují typografický rytmus cílové komponenty: řádek nadpisu je širší a vyšší, řádky odstavce užší, poslední řádek zkrácený na zhruba 60 % šířky. Animace se řeší dvěma způsoby:</p> <ul> <li><strong>Pulse</strong>: plynulá změna průhlednosti, levná na výkon.</li> <li><strong>Shimmer</strong>: světlý pruh přejíždějící zleva doprava přes gradient pozadí.</li> </ul> <p>Animace není povinná. Statický šedý obrys funguje také, jen méně jasně signalizuje, že se stále čeká.</p> <h3>Kdy se skeleton vyplatí</h3> <p>Skeleton dává smysl u obsahu s předvídatelnou strukturou, který se načítá zhruba 0,3 až 3 sekundy: feed příspěvků, výpis produktů, dashboard s grafy, detail objednávky. Pod 300 milisekund je lepší nezobrazit vůbec nic, protože problikávající skeleton působí jako závada.</p> <h3>Kdy skeleton škodí</h3> <p>U operací, jejichž výsledek nemá známý tvar (nahrávání souboru, platba, dlouhý export), skeleton lže: slibuje rozvržení, které nakonec nepřijde. Tam patří progress bar nebo textový stav. Škodlivý je i skeleton, jehož geometrie neodpovídá reálnému obsahu: pak vzniká přesně ten layout shift, kterému měl zabránit.</p> <h2>Skeleton a čtečky obrazovky</h2> <p>Skeleton je čistě vizuální berlička a pro asistivní technologie nemá žádnou hodnotu, spíš je matoucí. Dekorativní bloky se proto skrývají přes <code>aria-hidden="true"</code> a stav načítání se oznámí zvlášť, například kontejnerem s <code>role="status"</code> a textem „Načítám produkty“. Po dokončení se text nahradí. Bez toho čtečka ohlásí prázdnou oblast a uživatel neví, jestli má čekat. Detailům se věnuje heslo <a href="/slovnik/pristupnost">Přístupnost</a>.</p> <p>Animaci je vhodné vypnout při <code>prefers-reduced-motion: reduce</code>, protože opakovaný shimmer přes celou obrazovku obtěžuje citlivé uživatele.</p> <h2>Kde se skeleton v aplikaci vykresluje</h2> <p>V klasické klientské aplikaci skeleton renderuje komponenta, dokud dotaz nevrátí data. V React 18 a novějších frameworcích se stejnou roli plní hranice <code><Suspense fallback={...}></code>, kterou lze použít i při streamovaném serverovém renderování: server pošle skeleton okamžitě v prvním chunku HTML a pomalou část dopraví později, jakmile je hotová.</p>

Příklady z praxe

  1. Výpis produktů v e-shopu

    Kategorie načítá 24 produktů z API, které odpovídá zhruba za 800 ms. Místo prázdné bílé plochy se okamžitě vykreslí 24 karet s šedým obdélníkem místo fotky a dvěma řádky místo názvu a ceny. Karty mají pevnou výšku, takže po dorazení dat se stránka ani nehne a filtry vlevo nezmění pozici.

    <article class="card" aria-hidden="true">
      <div class="sk sk-img"></div>
      <div class="sk sk-line" style-less></div>
    </article>
    <p role="status">Načítám produkty…</p>
  2. Skeleton jako Suspense fallback v Reactu

    Detail objednávky se skládá z rychlé hlavičky a pomalého seznamu položek, který čeká na platební bránu. Hlavička se vykreslí hned, seznam obalí hranice Suspense se skeletonem. Uživatel tak vidí číslo objednávky během desítek milisekund a poskakující tabulku dostane až hotovou.

    export default function Order({ id }) {
      return (
        <>
          <OrderHeader id={id} />
          <Suspense fallback={<ItemsSkeleton rows={5} />}>
            <OrderItems id={id} />
          </Suspense>
        </>
      );
    }

Časté omyly

MýtusSkeleton screen zrychlí načítání aplikace.
Ve skutečnostiSkeleton screen nezrychlí nic: data dorazí ve stejnou chvíli jako předtím. Mění se jen vnímání čekání, protože uživatel má na co koukat a ví, jaká struktura přijde. Reálný výkon se řeší cachováním, menším payloadem a rychlejším dotazem.
MýtusSkeleton je vždycky lepší než spinner.
Ve skutečnostiSkeleton je lepší jen tam, kde je tvar výsledku předem známý. U akcí bez předvídatelného rozvržení (odeslání platby, generování PDF) je jasnější spinner s popiskem nebo progress bar s procenty.
MýtusSkeleton stačí prohodit za obsah, o přístupnost se starat nemusím.
Ve skutečnostiSkeleton je pro čtečku obrazovky prázdná změť prvků. Bez aria-hidden na dekoraci a bez živé oblasti s textovým stavem uživatel nepozná, že se něco načítá.

Časté dotazy

Jak dlouho má být skeleton screen vidět, než se zobrazí obsah?
Skeleton screen má smysl zobrazit až po krátké prodlevě, typicky 200 až 300 milisekund od začátku načítání. Pokud data dorazí dřív, skeleton jen problikne a působí jako grafická chyba. Zároveň se doporučuje minimální doba zobrazení, například 300 až 500 milisekund, aby se skeleton nezjevil a hned nezmizel. Nad zhruba třemi sekundami už skeleton přestává stačit a je vhodné doplnit textovou informaci o tom, na co se čeká, případně přejít na progress indikátor s reálným postupem.
Jak skeleton screen ovlivňuje Core Web Vitals?
Skeleton screen pomáhá hlavně metrice Cumulative Layout Shift, protože rezervuje přesné rozměry budoucího obsahu a stránka po načtení dat nepodskočí. Vliv na Largest Contentful Paint je nejednoznačný: šedé bloky se obvykle za největší obsahový prvek nepočítají, takže LCP se řídí až skutečným obrázkem nebo textem. Skeleton tedy metriky sám o sobě nevylepší, pokud je server pomalý. Nejvíc se vyplatí kombinace: skeleton pro stabilní rozvržení a skutečná optimalizace dotazů, cache a velikosti obrázků.
Čím se skeleton screen liší od placeholderu typu blur-up u obrázků?
Skeleton screen zastupuje celou strukturu rozhraní, tedy nadpisy, řádky textu i pozice karet, a nenese žádnou informaci o skutečném obsahu. Blur-up placeholder naopak ukazuje rozmazanou miniaturu konkrétního obrázku, kterou prohlížeč postupně nahradí ostrou verzí. Obě techniky se dají kombinovat: karta produktu má skeleton pro text a cenu, zatímco pro fotku použije rozmazaný náhled o velikosti pár set bajtů. Společný cíl je stejný, tedy rezervovat prostor a zabránit poskočení rozvržení.
Musím si skeleton screen psát ručně, nebo existují hotová řešení?
Skeleton screen se dá napsat ručně několika řádky CSS: barevné pozadí, zaoblené rohy, pevné rozměry a volitelně animace přes keyframes. Většina komponentových knihoven ale nabízí hotový prvek, například MUI Skeleton, Chakra Skeleton nebo utility třídy v Tailwindu s animací pulse. Existují i nástroje generující skeleton automaticky ze snímku hotové komponenty. Ruční řešení je bezpečnější v tom, že rozměry odpovídají reálnému obsahu, což je u skeletonů to nejdůležitější.

Zdroje

  1. Cumulative Layout Shift (CLS)(otevře se v novém okně)MDN Web Docs
  2. prefers-reduced-motion(otevře se v novém okně)MDN Web Docs
  3. ARIA live regions(otevře se v novém okně)MDN Web Docs
  4. <Suspense>(otevře se v novém okně)React
  5. Web Content Accessibility Guidelines (WCAG) 2.2(otevře se v novém okně)W3C, 2023

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.