Projekt 41 ze 100 – Psaní responzivních CSS v JSX

Ahoj! Jsem na misi vytvořit 100 projektů React.js, které skončí 8. března. Sledujte můj profil dev.to nebo můj twitter pro aktualizace a v případě dotazů nás neváhejte kontaktovat. Děkujeme za vaši podporu!

Odkaz na dnes nasazenou aplikaci:Odkaz
Odkaz na repo:github

Jednalo se o krátký projekt navazující na první návrh klientského webu. Web je optimalizován pro mobily, ale chtěli jsme do něj vložit jen pár stylů, aby byl srozumitelný i pro stolní diváky. Primární výzvou byl prvek statického obrázku na pozadí, který říkal (parafrázováno ze španělštiny) „Více již brzy“.

Pro mobilní obrazovky jsem chtěl využít background-size: cover CSS vlastnost jednoduše pokrýt prostor. Na poměrně velkých obrazovkách to však může vypadat směšně, protože se možná bude zobrazovat jen malá část obrazu.

V čistém CSS to lze snadno vyřešit dotazem na média. Jednoduše uveďte velikost obrazovky, pro kterou optimalizujete (řekněme přes 570 pixelů na šířku) a nastavte styly v hranatých závorkách.

V tomto projektu ve skutečnosti využívám props předat komponentě adresu URL obrázku, aby byla komponenta znovu použitelná. Protože nastavuji CSS background vlastnost v rámci JSX, přepíše některé jiné styly ve skutečné šabloně stylů.

CSS je načteno v

stránky html dlouho předtím, než je tomuto objektu předána adresa URL obrázku, takže mi to bránilo dát obrázku background-size: cover styl.

Místo toho můžeme použít Javascript ke kontrole velikosti obrazovky pomocí následující vestavěné vlastnosti vanilla Javascript window objekt:

window.innerWidth

Tato vlastnost vrací vnitřní šířku okna, což vám umožňuje nastavit styly pro různé velikosti obrazovky.

Problém? Tato vlastnost je volána pouze jednou při načtení stránky. Upřímně řečeno, pro mobily je to v pořádku, ale pokud se na to někdo dívá v prohlížeči a rozhodne se změnit velikost okna a odsunout ho na stranu, nebude znovu voláno. K opětovnému volání vlastnosti při změně velikosti okna využíváme zpětné volání na window.onresize metoda. Používám React useState pro nastavení proměnné windowWidth na velikost obrazovky při načtení stránky a při každé změně velikosti obrazovky.

  const [windowWidth,setWindowWidth] = useState(0);

  window.onresize = () => {
    setWindowWidth(window.innerWidth);
  }

Nyní, když máme proměnnou, která se aktualizuje při každé změně velikosti obrazovky, můžeme vytvořit samostatné objekty stylu, které se předají prvku JSX pro každou velikost obrazovky, jako zde, kde používám trojici:

  const innerImageStyle = windowWidth < 570 ?
   ({
    width: '100%',
    height: '80vh',
    backgroundImage: `url(${props.imageUrl})`,
    backgroundSize: 'cover',
  }) : 
   ({
    width: '100%',
    height: '500px',
    backgroundImage: `url(${props.imageUrl})`,
    backgroundSize: 'contain',
  });

Jak vidíte, pokud se jedná o mobilní zařízení (šířka menší než 570 pixelů), chceme, aby pozadí pokrývalo dostupný prostor. Pokud je to stolní počítač, chceme, aby se pozadí opakovalo (zde volba klienta, ale líbí se mi to).

Jsem si jistý, že bychom to mohli udělat také pomocí háčku React useEffect, ale toto je zamýšleno jako jednoduchá verze a upřímně mám pocit, že vestavěné metody okna Javascript jsou podceňovány a nedostatečně vyučovány na to, jak jsou výkonné.

Dejte mi vědět, co si myslíte a jak děláte podmíněný styl pro komponenty React v komentářích...