Dla administratorów: pełny przebieg z dokładnymi liczbami, poleceniami i konfiguracją. Wersje: stan na listopad 2026.
W skrócie
| Element | Szczegóły |
| Środowisko | WordPress 7.1.4, Elementor 4.3.5 (darmowy), własny motyw na Tailwind CSS 4.3.3, PHP 8.3.36, Apache 2.4.69, MariaDB 11.4.13; stara wersja: WordPress 7.1.3, motyw z generatora, NextGEN Gallery 4.5.3, Cookie Notice 3.1.17, Flagallery 5.5.2 (stan na 2026-11) |
| Objaw | cele dotyku 32×33 px, tekst 14 px / interlinia 1,2, user-scalable=no, tel: i mailto: brak, kontakt ucięty przez overflow: hidden, baner cookies 15–22% ekranu, brak formularza |
| Przyczyna | układ desktopowy z generatora, wersja mobilna doklejona skryptem (script.responsive.js); przebudowa 1:1 poprawiła wydajność, nie użyteczność |
| Rozwiązanie | motyw mobile-first: przyklejony pasek 60 px z tel: i przyciskiem menu z etykietą, panel menu z celami 56 px, tekst 17 px / 1,6, karty treści bez przepełnień, formularz (wp_mail), „Do góry”, tokeny projektu w DESIGN.md |
| Efekt | 5 zadań × 3 szerokości: 15/15 zamiast 9/15; cele < 24 px 0 zamiast 10, < 44 px 0 zamiast 25; tekst < 16 px 0% zamiast 74%; Lighthouse mobile: patrz tabela |
Kontekst
Trzy wersje tej samej strony w laboratorium (te same dane, ten sam serwer):
| Wersja | Co to jest |
| stara | motyw z generatora (2016), jQuery 1.9.1, układ tabelami, wtyczki: NextGEN Gallery, Flagallery (nieużywana), Cookie Notice, TinyMCE Advanced, WP-Sweep |
| przebudowa 1:1 | wcześniejsza przebudowa tej strony dla szybkości: darmowy Elementor + własny motyw Tailwind, wygląd 1:1 |
| redesign | nowy projekt mobile-first na bazie przebudowy (ten sam Elementor i edycja treści, nowy własny motyw) |
Ograniczenia: ta sama treść, edycja w Elementorze przez klienta, bez wtyczek poza Elementorem, bez zmian adresów stron.
Diagnoza: jak mierzyliśmy
1. Testy zadaniowe (emulacja telefonu: isMobile, dotyk, DPR 2, zwykły UA
Androida; 360×780, 390×844, 414×896). Liczą się tylko elementy w całości widoczne w oknie
i niezasłonięte (elementFromPoint w środku elementu); przewijanie gestem o 80% wysokości okna, przy czytaniu przesunięcie
ekranu tak, żeby cały opis był widoczny. Przed każdym dotknięciem 1 s, gest 0,7 s, pisanie 0,33 s/znak,
czytanie 200 słów/min. Trafność dotknięcia: 400 punktów z rozkładu Gaussa wokół środka celu (σ = 2 mm = 12,6 px CSS
przy 160 dpi), trafienie = elementFromPoint wewnątrz celu albo w jego etykiecie. Przy pierwszej wizycie użytkownik
zamyka baner cookies, jeśli zasłania stronę.
2. Pomiary automatyczne na 9 stronach × 3 szerokościach: cele dotyku (linki, przyciski, pola; link z obrazkiem
liczony po prostokącie obrazka, pole wyboru po etykiecie), udział znaków tekstu poniżej 16 px, przewijanie w poziomie,
elementy poza ekranem (prawa krawędź > szerokości okna mimo braku przewijania), telefon tel: w pierwszym ekranie,
blokada powiększania w meta viewport, baner cookies, wysokość pozycji menu.
3. Lighthouse 12.8.2, profil mobilny (Moto G Power, wolne 4G, CPU ×4), 5 stron × 2 przebiegi, mediana.
4. Ocena heurystyczna (10 heurystyk Nielsena, waga 0–4), jeden oceniający.
Wyniki: testy zadaniowe
| Zadanie | Wersja | Ukończone (360/390/414) | Dotknięcia | Przewinięcia | Czas [s] | Oczekiwane chybienia | Błędy |
| 1. Telefon | stara | częściowo ×3 | 3 | 3 | 7,3 | 0,47–0,56 | numer jako tekst, do przepisania |
| 1:1 | częściowo ×3 | 2 | 3–4 | 5,7–6,6 | 0,35–0,41 | jw. |
| redesign | tak ×3 | 1 | 0 | 1,0 | 0,09–0,13 | |
| 2. Galeria | stara | tak ×3 | 3 | 0 | 4,7–4,8 | 0,45–0,54 | |
| 1:1 | tak ×3 | 2 | 0 | 3,1 | 0,30–0,40 | |
| redesign | tak ×3 | 2 | 0 | 3,1 | 0,06–0,08 | |
| 3. Oferta | stara | tak ×3 | 1 | 0–1 | 29,9–30,7 | 0,12–0,13 | |
| 1:1 | tak ×3 | 0 | 0–1 | 28,3–29,1 | 0 | |
| redesign | tak ×3 | 0 | 4–6 | 35,3–37,0 | 0 | |
| 4. Formularz | stara | nie ×3 | 3 | 1 | 5,6 | 0,47–0,50 | brak formularza, e-mail „(at)” bez linku |
| 1:1 | nie ×3 | 2 | 1–2 | 4,0–4,8 | 0,33–0,35 | jw. |
| redesign | tak ×3 | 8 | 2 | 50,9 | 0,28–0,30 | (116 znaków, mail w Mailpit) |
| 5. Do góry | stara | tak ×3 | 0 | 5 | 4,3 | 0 | |
| 1:1 | tak ×3 | 0 | 6 | 5,1 | 0 | |
| redesign | tak ×3 | 1 | 0 | 1,9–2,0 | 0,12–0,13 | |
Sumy zadań 1, 2, 3 i 5 (wykonalnych w każdej wersji), średnio na szerokość:
| Wersja | Ukończone w pełni | Dotknięcia | Przewinięcia | Czas | Oczekiwane chybienia |
| stara | 9/12 | 7,0 | 8,7 | 46,8 s | 1,14 |
| przebudowa 1:1 | 9/12 | 4,0 | 10,3 | 43,3 s | 0,73 |
| redesign | 12/12 | 4,0 | 5,0 | 42,2 s | 0,31 |
Trafność pojedynczych celów (σ 2 mm): przycisk menu starej 32×33 px 60,5–67%, „Zgadzam się” na banerze 110×38 px
84–87%, „Zadzwoń” w pasku redesignu 48×48 px 89%, „Menu” 98×48 px 93–96%, pozycje panelu menu 56 px 97,5–98,3%.
Wyniki: pomiary automatyczne (9 stron)
| Miara (390×844; 360 i 414 bez różnic poza banerem) | Stara | Przebudowa 1:1 | Redesign |
| Cele dotyku | 73 | 63 | 108 |
| Cele < 24 × 24 px (WCAG 2.5.8) | 10 (14%) | 9 (14%) | 0 |
| Cele < 44 × 44 px | 25 (34%) | 21 (33%) | 0 |
| Przycisk menu | 32×33 px, bez nazwy | 32×33 px | 98×48 px, „Menu” |
| Pozycje menu | 33–54 px | 54 px | 48–56 px, podmenu widoczne |
| Znaki tekstu < 16 px (mediana stron) | 74% | 78,3% | 0% |
| Mediana rozmiaru tekstu | 14 px | 14 px | 17 px |
| Przewijanie w poziomie | 0 px | 0 px | 0 px |
| Strony z treścią poza ekranem | 1 (kontakt: 4 elementy, do 780 px) | 0 | 0 |
Telefon tel: w pierwszym ekranie | 0/9 | 0/9 | 9/9 |
| Początek treści od góry strony | 252–256 px | 246 px | 85 px |
| Baner cookies przy pierwszej wizycie | 15–22% ekranu | brak | brak |
user-scalable=no | tak | nie | nie |
Wyniki: Lighthouse mobile
Mediana 2 przebiegów na stronę (profil mobilny Lighthouse 12.8.2: Moto G Power, wolne 4G, CPU ×4):
| Strona | Wersja | Wydajność | Dostępność | Dobre praktyki | SEO | LCP [s] | TBT [ms] | CLS | Waga [KB] | Żądania |
| Strona główna | stara | 72 | 90 | 100 | 92 | 2,7 | 8 | 0,806 | 279 | 22 |
| Strona główna | 1:1 | 100 | 98 | 100 | 100 | 1,4 | 0 | 0,000 | 49 | 11 |
| Strona główna | redesign | 100 | 100 | 100 | 100 | 1,5 | 0 | 0,000 | 61 | 9 |
| Kontakt | stara | 71 | 90 | 100 | 92 | 3,0 | 5 | 0,751 | 368 | 23 |
| Kontakt | 1:1 | 100 | 100 | 100 | 100 | 1,5 | 0 | 0,000 | 94 | 13 |
| Kontakt | redesign | 100 | 100 | 100 | 100 | 1,5 | 0 | 0,000 | 66 | 10 |
| Badania ratownicze | stara | 66 | 90 | 100 | 92 | 11,2 | 2 | 0,180 | 3594 | 32 |
| Badania ratownicze | 1:1 | 100 | 100 | 100 | 100 | 1,5 | 0 | 0,000 | 1226 | 21 |
| Badania ratownicze | redesign | 94 | 100 | 100 | 100 | 2,6 | 0 | 0,000 | 1197 | 18 |
| Galeria | stara | 71 | 89 | 79 | 92 | 5,3 | 2 | 0,180 | 718 | 44 |
| Galeria | 1:1 | 100 | 100 | 100 | 100 | 1,5 | 0 | 0,000 | 444 | 21 |
| Galeria | redesign | 100 | 100 | 100 | 100 | 1,1 | 0 | 0,000 | 278 | 17 |
| Realizacje | stara | 68 | 89 | 100 | 92 | 7,1 | 4 | 0,180 | 1109 | 25 |
| Realizacje | 1:1 | 98 | 100 | 100 | 100 | 2,0 | 0 | 0,000 | 351 | 14 |
| Realizacje | redesign | 99 | 100 | 100 | 100 | 1,7 | 0 | 0,000 | 323 | 11 |
Mediana pięciu stron: stara 71 / 90 / 100 / 92, przebudowa 1:1 100 / 100 / 100 / 100, redesign 100 / 100 / 100 / 100
(wydajność / dostępność / dobre praktyki / SEO). Nieprzechodzące audyty dostępności: stara link-name (linki-obrazki bez
tekstu alternatywnego) i meta-viewport (user-scalable=no), 1:1 heading-order, redesign żadnego. Redesign na stronie
„Badania ratownicze” ma 94 pkt wydajności (LCP 2,6 s): zdjęcia na całą szerokość ekranu pobierają wariant 804 px.
Wysokie CLS starej (0,75–0,81 na stronie głównej i kontakcie) to jedno przesunięcie całej komórki treści
div.art-layout-cell.art-content: skrypt motywu przelicza układ po załadowaniu i dopisuje jej styl (style="height: 424.781px").
Ocena heurystyczna (Nielsen, waga 0–4, telefon)
| Heurystyka | Stara | Redesign | Uwagi |
| Widoczność stanu | 2 | 0 | redesign: zaznaczona bieżąca strona w menu, tytuł strony zawsze widoczny, potwierdzenie wysłania formularza |
| Zgodność z rzeczywistością | 2 | 0 | stara: ikona bez podpisu, „imię(at)domena” |
| Kontrola i swoboda | 3 | 0 | stara: blokada powiększania, brak powrotu na górę, podmenu tylko w dziale Realizacje; redesign: „Do góry”, link „Wróć”, Esc i link zamykają menu, powiększanie dozwolone |
| Spójność i standardy | 3 | 0 | stara: numery bez tel:, adresy bez mailto: |
| Zapobieganie błędom | 3 | 1 | stara: cele 32 px; redesign: walidacja formularza tylko dymkami przeglądarki (do kroku dostępności) |
| Rozpoznawanie zamiast przypominania | 2 | 0 | redesign: podpisane „Menu”, podmenu rozwinięte |
| Elastyczność i efektywność | 3 | 0 | redesign: „Zadzwoń” na każdej stronie w pasku |
| Estetyka i minimalizm | 3 | 1 | stara: nagłówek ~250 px, cyfry 120 px, baner; redesign: dłuższa strona główna (czytanie oferty 4–6 przewinięć) |
| Rozpoznawanie i naprawa błędów | 3 | 2 | stara: brak formularza; redesign: ogólny komunikat błędu po stronie serwera |
| Pomoc i dokumentacja | 2 | 0 | kontakt dostępny z każdej strony |
Przyczyna
generator motywów generuje układ desktopowy (tabele art-content-layout, stałe szerokości zdjęć 401 px w treści, tabela kontaktu
z czterema kolumnami i padding-left: 90px) i dokleja „responsywność” skryptem: klasa responsive, przycisk
a.art-menu-btn (trzy span, bez tekstu i aria-label), menu rozwijane pod przyciskiem. Kontener strony ma
overflow: hidden, więc szerokie elementy są ucinane zamiast przewijać. Treść klienta wprowadzana w edytorze
klasycznym: telefony i adresy jako tekst (adresy zaciemnione „(at)” przeciw spamowi). Przebudowa 1:1 odwzorowała ten
wygląd na lżejszym kodzie, więc zachowała te same decyzje projektowe.
Co nie było oczywiste
- Brak przewijania w poziomie nie oznacza, że wszystko jest widoczne. Stara strona przy 390 px ma
scrollWidth = innerWidth (0 px przewijania), a mimo to na stronie kontaktu 4 elementy kończą się na 459–780 px:
adresy dwóch osób i komórki tabeli. overflow: hidden na kontenerze ucina je bez śladu. Standardowa kontrola
„przewijanie w poziomie” tego nie widzi; trzeba mierzyć prostokąty elementów względem okna.
- Baner cookies znika przed narzędziami. Cookie Notice 3.1.17 z włączonym
bot_detection nie wypisuje banera dla UA
z „HeadlessChrome”: curl -A "…HeadlessChrome…" | grep -c 'id="cookie-notice"' daje 0, ze zwykłym UA Androida 1.
Pomiar z takim identyfikatorem przeglądarki pokazałby stronę bez banera i bez dotknięcia na jego zamknięcie.
href="#top" przy przyklejonym nagłówku z id="top" nie przewija. Przeglądarka przewija do elementu o tym id,
a przyklejony nagłówek zawsze jest w oknie, więc nic się nie dzieje. Test zadania 5 zakończył się niepowodzeniem;
po usunięciu id="top" działa specjalny fragment #top z HTML (przewinięcie na początek dokumentu):
1 dotknięcie, 1,9–2,0 s.
- Czytelność kosztuje przewijanie. Tekst 17 px / 1,6 zamiast 14 px / 1,2 i sekcja otwierająca nad usługami: czytanie
trzech opisów usług wymaga 4–6 przewinięć zamiast 0–1, czas 35,3–37,0 s zamiast 29,9–30,7 s (przy tej samej liczbie
słów, bo czas czytania liczony jest z treści). Uznaliśmy to za akceptowalny koszt; w sumie zadań redesign i tak jest
najszybszy (42,2 s).
- Pole wyboru 24 × 24 px: 50,5% trafień. Zgoda w formularzu, wcześniej sam
input, przy rozrzucie σ 2 mm. Po
objęciu pola i tekstu etykietą jako jednym celem (min. 48 px wysokości): 95,3–96,3%. WCAG 2.5.8 (24 px) to minimum, nie
gwarancja trafienia kciukiem.
- Lighthouse 100 nie znaczy „wygodna na telefonie”. Przebudowa 1:1 dostaje 98–100 we wszystkich kategoriach
Lighthouse, a w testach zadaniowych ma te same niepowodzenia co stara (telefon do przepisania, brak formularza,
przycisk menu 32×33 px). Lighthouse 12.8.2 nie ma już audytu
tap-targets (brak w raportach JSON), a audyt
font-size przechodzi przy tekście 14 px (wymaga tylko, żeby 60% tekstu miało co najmniej 12 px).
Rozwiązanie
Pasek i menu (header.php): przyklejony pasek, „Zadzwoń” jako tel: (etykieta widoczna od 420 px, niżej ukryta
wizualnie), przycisk „Menu” z tekstem i aria-expanded, panel na pełny ekran, podmenu zawsze rozwinięte:
<meta name="viewport" content="width=device-width, initial-scale=1"> <!-- bez user-scalable=no -->
<a class="icon-btn icon-btn--call" href="tel:+447700900400">…<span class="icon-btn__label">Zadzwoń</span></a>
<button type="button" class="icon-btn icon-btn--menu" aria-controls="menu" aria-expanded="false">…Menu</button>
.icon-btn { min-width: 48px; min-height: 48px; }
.nav { position: fixed; inset: 60px 0 0; display: none; } /* telefon: panel */
.nav.is-open { display: block; }
.nav__menu a { min-height: 56px; font-size: 21px; }
@media (width >= 1024px) { .nav { position: static; display: block; } } /* desktop: menu poziome */
Tekst i układ (Tailwind 4, tokeny w DESIGN.md): 17 px / 1,6, max-width: 62ch, text-wrap: balance w nagłówkach
i pretty w akapitach, zdjęcia skalowane do szerokości (srcset z WordPressa: 402/804/1200 px), galeria 2 kolumny 4:3.
Kontakt: osoby jako lista, numer i adres jako linki z ikoną (min. 48 px), formularz motywu:
<input id="f-email" name="email" type="email" autocomplete="email" required>
<input id="f-telefon" name="telefon" type="tel" autocomplete="tel">
<label class="check" for="f-zgoda"><input id="f-zgoda" name="zgoda" type="checkbox" required> <span>Zgadzam się…</span></label>
Obsługa: admin-post.php → walidacja po stronie serwera → wp_mail() z Reply-To klienta → przekierowanie
z komunikatem; po błędzie wartości wracają do pól (transient 10 min).
„Do góry”: <a class="to-top" href="#top" hidden>, widoczny po 1,5 wysokości okna, bez id="top" w nagłówku.
Bez banera cookies: strona nie ustawia ciasteczek i nie wczytuje zasobów z obcych domen.
Rezultaty
| Etykieta | Wartość |
| Zadania ukończone w pełni (5 × 3 szerokości) | 9/15 przed, 15/15 po |
| Formularz kontaktowy | 0/3 przed (brak), 3/3 po: 8 dotknięć, 50,9 s, mail dostarczony |
| Telefon do firmy | 3 dotknięcia + 3 przewinięcia + przepisanie numeru przed, 1 dotknięcie po |
| Powrót na górę najdłuższej strony | 5 przewinięć przed, 1 dotknięcie po |
| Oczekiwane chybienia w zadaniach 1, 2, 3, 5 | 1,14 przed, 0,31 po |
| Cele dotyku < 24 px / < 44 px (9 stron) | 10 / 25 przed, 0 / 0 po |
| Znaki tekstu < 16 px | 74% przed, 0% po |
| Treść ucięta poza ekranem | 1 strona (4 elementy) przed, 0 po |
| Telefon w pierwszym ekranie | 0 z 9 stron przed, 9 z 9 po |
Wnioski
- Projekt mobile-first to decyzje o zadaniach, nie o szerokości kolumn. Kontakt jednym dotknięciem i formularz dały
więcej niż jakakolwiek zmiana wyglądu.
- Mierzalne kryteria (cele dotyku, tekst, treść poza ekranem, zadania) pozwalają sprawdzić projekt przed oddaniem
i powtórzyć sprawdzenie po każdej zmianie.
- Narzędzia automatyczne mają ślepe plamki: Lighthouse nie mierzy celów dotyku, wtyczki ukrywają banery przed testami,
kontrola przewijania nie widzi uciętej treści. Dlatego łączymy je z testem zadań i przeglądem zrzutów.
- Badanie z pięcioma osobami pokaże to, czego pomiary nie zgadną. Plan takiego badania jest częścią przekazania.