Gdy element nie mieści się w linii, sprawdź jego display
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".
Najczęstsza przyczyna to treść wewnątrz. Element inline-block wyrównuje się dolną krawędzią swojego ostatniego wiersza tekstu, a nie zewnętrznym bokiem pudełka. Jeśli w jednym bloku jest sam obrazek, a w drugim akapit, ich linie bazowe wypadają w innych miejscach. Krótki tekst bez zstępników, czyli bez liter schodzących pod linię, też przesuwa punkt odniesienia. Zanim uznasz, że coś jest zepsute, wpisz do obu elementów identyczną treść i porównaj.
Najprostszy sposób na pewną zmianę to umieszczenie nowej reguły po tej, którą chcesz nadpisać, przy zachowaniu identycznego selektora. To działa, ale bywa kruche: wystarczy przenieść fragment kodu do innego pliku albo zmienić kolejność importów i efekt znika. Dlatego zamiast polegać wyłącznie na kolejności, lepiej zadbać o strukturę. Trzymaj reguły bazowe na początku, a modyfikacje i warianty później. Nie mieszaj przypadkowo stylów globalnych z lokalnymi, bo wtedy kaskada zaczyna działać na twoją niekorzyść.
Białe znaki między elementami inline-block to jeden z najczęstszych powodów, dla których układ „nie chce" się ułożyć tak, jak wynika to z obliczeń. Przeglądarka traktuje każdy znak nowej linii, tabulacji i spacji w kodzie jako zwykłą spację w tekście. Jeśli obok siebie stoją dwa elementy inline-block, ta spacja zajmuje miejsce i wypycha drugi element w prawo lub do nowej linii. Efekt jest szczególnie widoczny przy trzech i więcej kafelkach ustawionych w rzędzie — ostatni spada poniżej, mimo że szerokości mieszczą się w kontenerze.
Na koniec: dziedziczenie to nie magia, tylko jawna lista właściwości. Kolor jest na tej liście, ramka nie. Jeśli zapamiętasz tę jedną różnicę i będziesz sprawdzać wartości obliczone w narzędziach deweloperskich, przestaniesz zgadywać, dlaczego tekst zmienia barwę, a obramowanie zostaje tylko na górnym elemencie.
Praktyczna metoda pracy: najpierw ustal, czy element ma być samodzielnym blokiem, czy tylko nośnikiem treści. Dla samodzielnych bloków ustawiaj ramkę jawnie na każdym z nich, zamiast liczyć na dziedziczenie. Dla tekstu wewnątrz bloku ustaw kolor na kontenerze i pozwól mu spłynąć w dół. Gdy kolor nie chce się zmienić, sprawdź, czy nie nadpisuje go bardziej szczegółowy selektor albo styl wbudowany. Gdy ramka nie chce zniknąć, sprawdź, czy nie pochodzi z outline, box-shadow albo z domyślnego stylu elementu, np. pola formularza. Przeglądarka potrafi dodać własne obramowanie, którego nie ma w Twoim CSS.
W praktyce najpierw sprawdź, czy elementy mają taką samą wysokość fontu i czy nie zawierają obrazków z marginesem. Potem ustaw jednolitą wartość vertical-align dla całego wiersza, a na końcu wyreguluj wysokość linii rodzica. Dopiero gdy to nie wystarczy, sięgnij po flexbox. Wyrównywanie inline-block do linii bazowej to nie kwestia przypadku, tylko trzech zależności: treści, fontu i kontekstu wiersza.
Każdy element HTML ma domyślny sposób zachowania w układzie strony, nazywany display. Najczęściej spotkasz trzy wartości: block, inline oraz inline-block. Od nich zależy, czy element zajmie całą szerokość, czy tylko tyle miejsca, ile potrzebuje jego treść, a także czy będzie można ustawiać mu szerokość i wysokość. Zanim zaczniesz przesuwać elementy marginesami, sprawdź, z jakim displayem pracujesz — to oszczędza mnóstwo czasu.
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ę.
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.