Flex-wrap czy ściskanie: co decyduje o układzie elementów
Wariant z opakowaniem wygląda tak: label otacza zarówno tekst etykiety, jak i pole input. Przeglądarka sama łączy je w jedną całość, więc kliknięcie w tekst ustawia fokus w polu. Nie trzeba wtedy nadawać polu identyfikatora ani pisać atrybutu for. To wygodne w prostych formularzach, zwłaszcza gdy etykieta i pole są obok siebie w jednym bloku. Uwaga na pułapkę: jeśli w label znajdzie się więcej niż jedno pole, powiązanie staje się niejednoznaczne. Przeglądarka zwykle ustawi fokus na pierwszym z nich, co bywa źródłem błędów w formularzach z polami wyboru.
Zasada działania jest prosta. Przeglądarka układa elementy w linii, dopóki suma ich szerokości mieści się w kontenerze. Gdy następny element miałby zostać ściśnięty poniżej swojej szerokości bazowej, zostaje przeniesiony do nowej linii. Wartość wrap-reverse odwraca kierunek układania kolejnych rzędów — nowe linie pojawiają się nad poprzednimi, co bywa mylące przy kolumnach z rosnącą osią główną.
Kiedy min-width: 0 to jeszcze za mało Jeśli po dodaniu min-width: 0 element nadal się nie zmniejsza, sprawdź, czy nie ma ustawionej sztywnej szerokości, np. width: 400px, albo czy nie używasz flex-basis z dużą wartością. Flex-basis wygrywa z width w kontenerze flex, więc element może być blokowany przez samą wartość bazową. Warto wtedy zmienić flex-basis na 0 lub na auto i przetestować. Kolejny częsty winowajca to white-space: nowrap — tekst w jednej linii nie może się zawinąć, więc jego minimalna szerokość równa się szerokości całego zdania i element nie ma jak się skurczyć.
Zagnieżdżanie kilku pól w jednym label bywa wygodne przy kompaktowych formularzach, np. przy wyborze daty złożonej z dwóch pól liczbowych. Uwaga jednak na kliknięcia: kliknięcie w etykietę może przenosić fokus tylko do pierwszego pola, co bywa mylące. Przy polach typu radio i checkbox lepiej użyć osobnych label dla każdej opcji, bo inaczej użytkownik nie wie, którą wartość zaznacza. To jeden z najczęstszych błędów w formularzach z wieloma opcjami.
W praktyce warto zacząć od display: flex; flex-wrap: wrap; gap: 1rem; i dopiero potem dodawać wymiary dzieciom. Jeśli układ ma się łamać w konkretnym punkcie, lepiej użyć flex-basis z wartością procentową lub jednostką względną niż sztywnej szerokości w pikselach. Dzięki temu elementy same decydują, kiedy przejść do nowego rzędu, a kontener pozostaje odporny na zmianę szerokości okna i dłuższe treści.
Najczęstszy błąd to brak flex-wrap przy jednoczesnym ustawieniu flex: 1 na dzieciach. Elementy nie mają wtedy dokąd uciec, więc rosną lub maleją w nieskończoność, a zawartość wychodzi poza kontener. Drugi problem to zapominanie o min-width — element z długim słowem potrafi rozepchnąć rząd, mimo że wrap jest aktywny. Warto ustawić min-width: 0 na dzieciach, jeśli mają się kurczyć, oraz overflow-wrap: anywhere przy długich ciągach znaków bez spacji.
Zupełnie inaczej podchodzi się do problemu, gdy elementy mają układ oparty na flexboxie lub gridzie. W tych modelach białe znaki między elementami nie generują odstępu, bo elementy nie są już układane jak znaki w wierszu tekstu. To najczystsze rozwiązanie, jeśli nie musisz wspierać bardzo starych przeglądarek. Wystarczy ustawić na kontenerze display: flex i zadbać o gap albo marginesy, a odstępy staną się w pełni kontrolowane.
Rem odwołuje się do rozmiaru czcionki elementu głównego, czyli html. Domyślnie to 16px, ale można to zmienić jedną regułą. Ustawienie html font-size: 62.5%; daje 10px, co upraszcza liczenie — 1.6rem to wtedy 16px. Rem nie mnoży się przez zagnieżdżenia, więc ten sam komponent wygląda identycznie niezależnie od miejsca w drzewie DOM. To czyni go najlepszym wyborem do typografii i odstępów w nowoczesnych projektach.
Praktyczna zasada: rozmiar tekstu i odstępy opieraj na rem, ewentualnie na em w miejscach, gdzie skala ma zależeć od kontekstu, na przykład w komponencie o zmiennym rozmiarze. Pikseli używaj do rzeczy, które naprawdę mają być sztywne — obramowań czy cienkich linii. Testuj stronę przy powiększonej czcionce w przeglądarce i przy różnych szerokościach okna. Jeśli po zmianie ustawień dostępności layout pęka, winne są zwykle piksele tam, gdzie powinny być rem.
Em liczy się od rodzica, rem od korzenia Em jest jednostką relatywną i odnosi się do rozmiaru czcionki elementu nadrzędnego. Jeśli akapit ma 16px, to 1.5em da 24px. Uwaga na zagnieżdżenia: lista wewnątrz elementu o rozmiarze 1.5em, gdzie kolejny poziom też ma 1.5em, daje już 2.25em względem bazy. To najczęstsze źródło niekontrolowanego rozjeżdżania się tekstu. Zagnieżdżone komponenty mnożą wartość przez siebie, więc dwa poziomy to iloczyn, nie suma.
Rozwiązanie jest proste: ustaw na elemencie min-width: 0. Wtedy przeglądarka przestaje brać pod uwagę naturalną szerokość treści jako dolną granicę i pozwala elementowi się kurczyć. W układzie pionowym, czyli przy flex-direction: column, analogicznie działa min-height: 0, ponieważ wtedy kolumna ma domyślnie auto i nie zmniejszy się poniżej wysokości swojej zawartości.