Postupně na malých webech opouštím nenáročný redakční systém GetSimple a přecházím na generátor statických webů Hugo. Důvod proč tak činím? Čím více webů mám, tím více času mi zabírá kontrola bezpečnostních aktualizací použitých systémů. A rád si ji někde odpustím.
Hugo mi pohodlně generuje statické HTML a přitom nabízí jistý komfort pro vytváření obsahu. To, že mám web bez redakčního systému ještě neznamená, že tam všechno buším v HTML kódu. Hugo pracuje se soubory v markdownu, které se dají snadno editovat v různých textových programech, včetně zvýrazňování syntaxe.
Naposledy jsem si vzal na paškál jednoduchý webík o chorvatském letovisku Njivice. A protože mě před Vánocemi zaujal utility-first CSS framework Tailwind, rozhodl jsem se web předělat s jeho pomocí. Dále jsem přidal přepínač stránek Swup. V angličtině bychom řekli transition library, tedy udělátko, které načítá jen měnící se části stránky a zlepšuje tak výsledný dojem z rychlosti webu.
První dojmy z CSS frameworku Tailwind
Moje úplné začátky s Tailwindem byly jako na houpačce. Od euforie, že toto jsem vždycky hledal, až po přečtení několika hanobících článků, že se to hodí jen na minimum věcí. Velkým zklamáním bylo zjištění, že sice nemusím psát vlastní stylesheet, ale ten od Tailwindu má přes dva megabajty.
Vše se v dobré obrátilo, zjistil jsem, že musím více studovat. Jak jsem se s frameworkem více seznamoval, našel jsem vlastnost purge, která při sestavování webu k produkci vyhodí veškeré nepoužívané definice a připraví skutečně malinkatý výsledný stylesheet.
Nejsem ten typ, co zhltne teorii a je okamžitě připraven psát vlastní kód. Rád studuju již hotové komponenty, postupně je upravuju a koukám, jak se změny projevují. Abych si seznamování s Tailwindem zpestřil, tak jsem si zaplatil službu Shuffle.dev, na které lze naklikat celé stránky z různých komponent, vygenerovat si jejich kód a ten dále upravovat. Umí také Bootstrap nebo framework Bulma.
Tailwind má různá rozšíření. Já jsem využil dvě:
- Tailwind Typography, které řeší velikosti písma, mezery, rozestupy a další věci v textu. Nikdo nechce psát neustále třídy ke všem odstavcům, to je navíc nereálné.
- Tailwind Aspect Ratio - výborná vychytávka, která dvěma dopsanými třídami zajistí správné respondování vložených iframů, například videa z YouTube. Zachová potřebný poměr stran.
Jsem zvědav, jak se mi bude s Tailwindem pracovat, až se pustím do kódování podle nějakého konkrétního grafického návrhu. Tohle byla zatím jen taková etuda, nemusel jsem řešit, jak udělat něco. Prostě jsem vzal komponentu ve výše zmíněném builderu. Ale myslím, že to půjde dobře.
Veškerý kód píšu v PhpStorm, který si s Tailwindem také rozumí a nabízí dokončování tříd.
Pokud byste zkoumali kód onoho webu, pak prosím s rezervou. Zkušenější tailwinďáci by mě asi sepsuli, že opakovat několikrát stejné třídy u více prvků je nesmysl a měl bych použít direktivu @apply. Stále se s tím seznamuju, ale web jsem potřeboval v nějaké fázi spustit.
Hugo + Tailwind
Generátor statických webů Hugo jsem na Maxiorlovi už představoval v článku Hugo: moje první zkušenost s generátorem statických webů. Když jsem s ním chtěl nastoupit na web o Njivici, tak jsem ještě netušil, že propojení s Tailwindem bude tak jednoduché. Tedy, když chcete něco více, než napojení jednoho CSS do HTML.
Hugo totiž umí při generování webu spustit právě proces purge v Tailwindu, aplikovat PostCSS a vytvořit malinkatý výsledný soubor. Navíc v konfiguraci Tailwindu snadno nastavíte, kde najde HTML šablony, ze kterých si před purge vyzobe použité CSS třídy.
Pomohl mi článek Install Tailwind on Hugo. Začnete tím, že nachystáte jednoduchou kostru pro Hugo, vytvoříte HTML soubory se šablonou a pak pomocí npm a dvou příkazů do projektu nainstalujete Tailwind:
npm init
npm install tailwindcss@latest postcss-cli@latest autoprefixer@latest --save
Následně Tailwind inicializujete pomocí:
npx tailwindcss init -p
Vznikne konfigurační soubor frameworku, do kterého v sekci purge doplníte následující:
purge: { content: ["./layouts/**/*.html", "./content/**/*.md", "./content/**/*.html"], "./themes/VASETEMA/**/*.html" }
Do souboru assets/css/main.css přidáte trojici řádků a jste hotovi:
@tailwind base;
@tailwind components;
@tailwind utilities;
Jakmile nastartujete lokální server s Hugo, Tailwind by vám měl začít fungovat. Pro produkci stačí upravit proměnou v node a spustit generování webu v tomto tvaru:
NODE_ENV=production hugo --minify -b https://www.ADRESAWEBU.cz/ -D
Jednoduchost implementace mě vážně překvapila.
Tipy k Hugo
V tomto článku nechci dělat nějaký návod k Hugo, ale narazil jsem na pár věcí, které mě na chvíli zdržely. Vědět je dříve, projekt by mnohem lépe odsýpal. Třeba se tyto tipy budou hodit i vám.
Hugo zatím neumí WebP. Můžete sice začlenit už hotové soubory do HTML šablon nebo se na ně odkazovat shortkódy v textu, ale není tu možnost je automaticky upravovat nebo snad do WebP konvertovat zdrojové PNG či JPG. Já to na webech s Hugo řeším zatím maximální možnou optimalizací klasické grafiky. Sestavení webu mám v shellovém skriptu a po jeho provedení ještě na Macu volám následující:
find -E public -type f -iregex '.*\.(png|jpe?g|svg)' -print0 | xargs -0 -I {} -P 8 /Applications/Optimage.app/Contents/MacOS/cli/optimage -v --strip-meta all {}
Příkaz projde všechny obrázky ve složce public a optimalizuje je s využitím aplikace Optimage. Jasně, to není řešení pro nějaký automatický deployment z Gitu, ale mohu s tím žít.
U výchozího shortcode pro značku figure mi vadilo, že Hugo používá pro popis obrázku v tagu figcaption h4. Nechtěl jsem řešit novou vlastní šablonu, ale jen tuto drobnou úpravu. Dobrá zpráva je, že výchozí šablony pro zabudované shortkódy najdete zde na GitHubu. Stačí je si vybraný soubor stáhnout do tématu vzhledu a složky layouts/shortcodes a tam upravit.
Níže popisovaná přechodová knihovna potřebuje kompletní URL v odkazech, což zajistí přidání nastavení do config.toml:
canonifyURLs = true
Chcete-li používat shortkódy v textu, nezapomeňte do konfiguračního souboru pro Hugo přidat též následující řádek:
enableInlineShortcodes = true
Jak se zbavit tagů a kategorií? Hugo s nimi standardně počítá a generuje odkazy na stránky s výpisem termínů i v případě, že je na webu nepoužíváte. Nadělá to pak paseku v sitemap.xml. Potlačení znamená přidat do konfigurace následující řádek:
disableKinds = ["taxonomy", "taxonomyTerm"]
Swup
Přechodovou knihovnu Swup jsem prvně zaznamenal na konferenci Symfony World Online 2020. Zaujaly mě ukázky její implementace ve spojení s Symfony UX. A protože je to zkrátka jenom JavaScript, chtěl jsem si ji vyzkoušet na menším projektu, než ji zabuduji do něčeho většího.
První dojmy? Je to pěkné, ale dokumentace je pro začátečníka zmatená. V kombinaci s Tailwindem jsem narazil na problém, kdy se po kliknutí na odkaz uskutečnilo načítání dat z jiné podstránky, ale už se nevykreslila. Swup totiž koliduje s prefixy v Tailwindu a bylo nutné konfiguraci Swupu mírně upravit:
const swup = new Swup({
animationSelector: '[class*="swup-transition-"]',
plugins: [new SwupSlideTheme(), new SwupGaPlugin(), new SwupScrollPlugin()],
containers: ["#swup", "#header-text"],
});
Pro animaci jsem tedy nastavil místo selektoru transition-* nový, s označením jako swup-transition-*.
Na webu si můžete všimnou, že se mění obsahová část a text v hlavičce, zatímto pozadí hlavičky je beze změny. Definice dvou kontejnerů je ve Swup hračkou. Využil jsem také zpracování události contentReplaced, abych správně napojil proklikávačku v galerii obrázků.
Základ jsem rozšířil o trojici pluginů:
- SwupSlideTheme dělá pěkný efekt příjezdu změněného obsahu
- SwupGaPlugin zajistí správné počítání PageViews v Google Analytics
- SwupScrollPlugin mám nasazen pro zajištění přechodu na začátek textu po změně stránky ze spodního menu
Pokud v textu plánujete mít kotvy pro posun na stránce, dávejte je rovněž plnou adresou s hashtagem na konci. Jinak takové odkazy po změně stránky Swupem nebudou fungovat.
Tipy pro zrychlování webu
Ze svého pohledu hotový web jsem nasadil a zkusil prohnat online verzí Lighthouse na web.dev. Jaké bylo zklamání, když jsem u čistého HTML uviděl červená čísla! Samozřejmě, problém byl klasicky na straně Google. On vůbec rád vyhodnocuje cizí weby a jako největší brzdu na nich vidí své vlastní kódy.
V daném případě se mi asi 50 bodů strhlo za video z YouTube. Jednoduchý vložený iframe s lazyloadingem. Prý načítá zbytečné množství JavaScriptu. No jo, to je sice pravda, ale co s tím?
Využil jsem pěkný tip od vývojáře aryaziai, který popisuje v článku Improve Speed with Lazy-Loaded Youtube Videos (+Autoplay). V podstatě místo klasického iframu použijete upravený tak, že v něm bude atribut srcdoc obsahující odkaz na embedované video a ikonku pro přehrávání. Na pozadí se natáhne akorát výchozí obrázek z videa. Do doby, než uživatel klikne na přehrávání, tak nejsou stahovány vůbec žádné skripty z YouTube a sám Google se nebude mračit na pomalé načítání.
Tento postup začnu používat i na dalších webech. V případě Hugo, kde video vkládám do markdownu pomocí shortkódu to znamenalo stáhnout si opět výchozí šablonu z GitHubu a upravit ji dle zmíněného návodu.
Stejně tak v Lighthouse vadily H4 ve figcaption, čehož nápravu jsem popsal už výše. Jelikož mám kostru stránky vygenerovanou builderem, narazil jsem ještě na brzdu v podobě načítání písma z nějaké cizí domény. Nahradil jsem ji za Google Fonts a odkaz pro načtení písma jsem umístil do patičky webu, odkud se případně přehodí JavaScriptem, až se stránka stáhne.
Výsledné hodnocení je už skoro v pořádku. Samozřejmě, jakmile budu v Hugo načítat WebP místo optimalizovaných JPEGů, dostanu se do zelených čísel komplet. V tuto chvíli mi to na vyzkoušení kombinace tří různých “technologií” bohatě stačí.
Tvůrce webů z Brna se specializací na Drupal, WordPress a Symfony. Acquia Certified Developer & Site Builder. Autor několika knih o Drupalu.
Web Development Director v Lesensky.cz. Ve volných chvílích podnikám výlety na souši i po vodě. Více se dozvíte na polzer.cz a mém LinkedIn profilu.
Podobné články
Komentáře k článku
Ahoj, je to jednoduché:
"PhpStorm recognizes tailwind.config.js files and provides completion based on customization you make to them". Viz info na webu.
Ano, Hugo je v Go, ta node proměnná s nastavením na production je tam proto, aby se spustil purge proces pro ten Tailwind. Normálně to kvůli rychlosti kompilace Hugo neudělá.
Ale je fakt, že by to šlo řešit asi i jiným způsobem, a to úpravou konfigurace v Hugo, viz odkaz do jeho dokumentace. Zatím jsem to nezkoušel.
Bez Tailwindu už ani ránu. Kdo si to jednou vyzkouší + možnost konfigurace nad výchozí konfigurací už se nikdy nemůže vrátit k Bootstrapu či jinému frameworku.
Ahoj, 2 otazky:
- `Veškerý kód píšu v PhpStorm, který si s Tailwindem také rozumí a nabízí dokončování tříd.` - toto plati asi o vsetkom cssku nie? Alebo ma phpstorm nejake specialne rozsirenie pre tailwind?
- `NODE_ENV=production hugo --minify -b https://www.ADRESAWEBU.cz/ -D` - preco je tam potrebna ta node premenna? hugo je v Golangu nie? ci on sa stara aj o kompilovanie frontend assetov?