Co zrobić, gdy dwie etykiety label wskazują na to samo pole?
Przy zagnieżdżonych siatkach pamiętaj, że jednostka fr działa w kontekście najbliższego kontenera grid. Jeśli wewnątrz kolumny umieścisz kolejny grid z własnymi kolumnami fr, nie dziedziczy on podziału z zewnątrz. To częste źródło zdziwienia, gdy wewnętrzna siatka „nie chce" wyrównać się do zewnętrznej. Rozwiązaniem jest albo jawne ustawienie tych samych proporcji, albo użycie subgrid, jeśli przeglądarki, na których ci zależy, to wspierają.
Możesz łączyć jednostki fr z wartościami stałymi, na przykład 200px 1fr 2fr. Wtedy najpierw odejmowana jest kolumna 200 pikseli, a pozostała przestrzeń dzielona jest w stosunku jeden do dwóch. Błąd pojawia się, gdy do sztywnej kolumny wrzucisz treść szerszą niż jej szerokość. Jednostka fr nie chroni przed przepełnieniem — sztywna kolumna po prostu rozepchnie układ albo obetnie zawartość. Lekarstwem jest min-width: 0 na elementach wewnątrz kolumn oraz unikanie długich, nieprzerywalnych ciągów znaków.
Kolor tekstu i ramka to dwie właściwości, które w CSS zachowują się zupełnie inaczej, choć w arkuszu stylów wyglądają podobnie. Kolor jest dziedziczony domyślnie — każdy element potomny przejmuje go od rodzica, chyba że sam go nadpisze. Ramka nie jest dziedziczona — element potomny nie dostaje obramowania tylko dlatego, że ma je rodzic. Zrozumienie tej różnicy oszczędza godziny debugowania i tłumaczy, dlaczego czasem „nic się nie zmienia", a czasem „wszystko się rozjeżdża".
Zacznij od ustalenia, czy to rzeczywiście błąd, czy świadoma decyzja. Dwie etykiety mają sens, gdy opisują to samo pole z różnych perspektyw, na przykład jedna jest widoczna, a druga ukryta dla technologii asystujących. Problem pojawia się wtedy, gdy obie są widoczne i zawierają różny tekst. Wówczas osoba korzystająca z czytnika ekranu usłyszy przy polu dwie nazwy, co utrudnia zrozumienie, czego formularz oczekuje. Podobnie bywa z automatycznym wypełnianiem: przeglądarka może wybrać etykietę, która nie odpowiada intencji autora.
Po poprawkach przetestuj formularz z klawiaturą i czytnikiem ekranu. Kliknięcie w etykietę powinno przenosić fokus do właściwego pola, a komunikat czytnika ma być jednoznaczny. Jeśli pole jest wymagane, dodaj informację o tym w jednej etykiecie, a nie w obu. Krótko mówiąc: jedna etykieta to nazwa, druga może być opisem — ale nigdy dwiema nazwami naraz.
Kolejna pułapka: flex-basis: 100% nie zawsze oznacza pełną szerokość widoczną dla użytkownika. Jeśli element ma margin, border albo padding poza box-sizing, wizualnie wyjdzie poza rodzica i pojawi się poziomy pasek przewijania. Bezpieczniej używać flex-basis: 100% razem z box-sizing: border-box i bez marginesów poziomych. Przy zawijaniu (flex-wrap: wrap) elementy z flex-basis: 100% zajmą cały wiersz, a kolejne przejdą do następnej linii — to przydatne do nagłówków sekcji wewnątrz elastycznego układu.
Kotwice sprawdzaj na urządzeniach mobilnych, bo tam nawigacja bywa inna, a przyklejone menu wyższe. Przetestuj również po odświeżeniu strony z hashem w adresie — dobry dokument powinien od razu pokazać właściwą sekcję. Jeśli link prowadzi do treści ładowanej dynamicznie, kotwica może nie zadziałać, dopóki element nie pojawi się w DOM. Wtedy trzeba przewinąć widok skryptem po załadowaniu danych.
Uważaj na różnicę między „odziedziczone" a „przejęte wizualnie". Kolor tekstu dziedziczy się automatycznie, ale na przykład background-color już nie — dziecko nie dostanie tła rodzica. Ramka ma jeszcze jeden haczyk: jeśli ustawisz border: none na rodzicu, a na dziecku border: inherit, dziecko otrzyma wartość none, czyli brak ramki. Wartość inherit bierze to, co faktycznie obliczył rodzic, a nie to, co sobie wyobrażasz. Podobnie z border-radius — on również nie jest dziedziczony. Zaokrąglenie narożników rodzica nie zaokrągli automatycznie narożników dziecka, nawet jeśli dziecko jest wizualnie w środku.
Po kliknięciu linku adres w pasku zmieni się o dopisek z hashem, a strona przewinie się do celu. Warto zadbać o margines — jeśli na górze jest przyklejony pasek nawigacji, nagłówek może schować się pod nim. Rozwiązaniem jest dodanie w CSS odstępu, np. scroll-margin-top dla elementu z id. Dzięki temu treść nie ląduje pod nakładką i wygląda estetycznie na każdym ekranie.
Jak wymusić dziedziczenie ramki, gdy naprawdę jest potrzebne Jeśli chcesz, aby obramowanie pojawiło się również na dzieciach, masz trzy praktyczne drogi. Pierwsza: użyj selektora potomka, np. .karta >* i nadaj tam border: 1px solid. Druga: zastosuj border: inherit na wybranych elementach potomnych — to jawnie wciąga wartość obliczoną rodzica. Trzecia: zamiast ramki użyj outline lub box-shadow z ostrym cieniem, ale pamiętaj, że outline nie wpływa na układ, a box-shadow bywa niewidoczny przy braku tła. Najczęstszy błąd to wpisanie border: inherit na wszystkich potomkach bez zastanowienia — wtedy ramka pojawia się także na elementach inline, np. w środku zdania, co psuje typografię.