Jak wyśrodkować element html w poziomie i pionie?
W niniejszym wpisie, przedstawię moim zdaniem 3 najlepsze/najprostsze sposoby na osiągnięcie wymarzonego środka 😉.
Misja - wyśrodkować niebieski kwadrat w poziomie i pionie
Poniżej widać jak wygląda sytuacja początkowa naszego kwadratu.
Kwadrat ma rozmiar 100px wysokości i szerokości.
Jego rodzic jest wyższy i szerszy od niego, zatem w naturalny sposób, kwadrat dotyka lewej i górnej krawędzi rodzica.
Naszym celem jest ustawienie kwadratu dokładnie po środku szarego pola. Mówiąc dokładniej, środek kwadratu powinien pokrywać się dokładnie ze środkiem szarego pola. Nasze rozwiązanie musi być elastyczne o tyle, że po zmianie wysokości i/lub szerokości rodzica, będzie nadal działać.
#1: Flexbox Layout
Użycie flexboxa to moim zdaniem najlepszy sposób na rozwiązanie problemu. Wystarczy, że kontenerowi ustawimy następujące właściwości:
display: flex;
justify-content: center;
(wyśrodkowanie w poziomie)align-items: center;
(wyśrodkowanie w pionie)
To wszystko!.
Jedynym argumentem przeciwko użyciu flexboxa może być brak wsparcia w starszych wersjach przeglądarek. Jednak już na dzień dzisiajeszy tylko prawdziwe dinozaury branży nie wspierają flexboxa.
Aktualne wsparcie dla Flexible Box Layout:
#2: Grid Layout
Dla porządku na drugim miejscu musi znaleźć się użycia grida.
W zasadzie jest nawet prościej niż w przypadku flexboxa, bo zamiast dwóch właściwości justify-content i align-items możemy użyć skrótu place-items.
Wystarczy, że kontenerowi ustawimy następujące właściwości:
display: grid;
place-items: center;
(wyśrodkowanie w poziomie i w pionie: skrót od justify-items: center i align-items: center)
Lub dłuższa wersja:
display: grid;
justify-items: center;
(wyśrodkowanie w poziomie)align-items: center;
(wyśrodkowanie w pionie)
Skoro jest nawet łatwiej niż za pomocą flexboxa to dlaczego grid jest na drugim miejscu?
Po pierwsze, na dzisiaj ma trochę gorsze wsparcie przeglądarek niż flexbox. Być może gdy czytasz ten tekst to ten powód już nie ma racji bytu.
Po drugie Grid Layout to jest naprawdę potężna bestia. A jak to zazwyczaj bywa - potężne narzędzia (grid) są zazwyczaj bardziej skomplikowane od swoich słabszych kuzynów (flexbox).
W mojej opini, użycie grida tylko i wyłącznie w celu wyśrodkowania elementu, jest trochę jak strzelanie do natrętnego komara z bazuki zamiast zwyczajnie machnąć go starą gazetą 😁.
Żebyśmy się dobrze zrozumieli - grid wykona robotę bardzo dobrze, tylko zwyczajnie dla mnie to zbyt duży kaliber do tego celu.
Aktualne wsparcie dla Grid Box Layout:
#3: Duet position relative i absolute + top i left + transform
Czas na najmniej przyjemne rozwiązanie.
Najlepiej sięgnąć po nie gdy użytkownicy naszej strony internetowej lubują się w starszych wersjach przeglądarek - takich, które mają słabe wsparcie dla flexboxa lub nie mają go wcale.
Tak to wygląda finalnie:
Dla kwadratu ustawiamy position: absolute
dzięki czemu możemy w pełni kontrolować jego pozycję dzięki właściwościom
top
oraz left
.
Kontenerowi (rodzicowi kwadratu) musimy natomiast ustawić position: relative
, dzięki czemu nasz
kwadrat jest pozycjonowany względem niego a nie całego płótna przeglądarki (ang. viewport).
Jeżeli position relative i absolute nic ci nie mówią, to zachęcam do przeczytania artykułu:
Pozycja static, relative i absolute w CSS.
Transform
Dotąd było w miarę łatwo, ale nadszedł czas żeby wyjaśnić deklarację transform: translate(-50%, -50%);
.
Na chłopski rozum wydawać by się mogło, że ustawienie top: 50%;
i left: 50%;
powinno załatwić sprawę.
Niestety tak nie jest. Zobacz co się stanie jeśli pominiemy delkarację transform: translate(-50%, -50%);
:
Gołym okiem widać, że kwadrat nie jest wyśrodkowany względem rodzica.
Jest przesunięty za mocno w dół i za mocno w prawo. Dlaczego?
Otóż top: 50%;
oznacza, że kwadrat zostanie przesunięty w dół od górnej krawędzi rodzica o 50% jego wysokości (rodzica),
czyli w naszym przypadku będzie to przesunięcie 50% * 300px = 150px.
Kluczem do zrozumienia, jest fakt iż górna krawędź niebieskiego kwadratu faktycznie znajduje się dokładnie w środku wysokości szarego pola. Nam zależało jednak żeby to środek kwadratu był po środku, a nie jego górna krawędź.
Zatem co zrobić żeby tak się stało?
Należy kwadrat przesunąć w górę o połowę jego własnej wysokości.
Dokładnie to samo należy zrobić w poziomie - przesunąć kwadrat w lewo o połowę jego szerokości.
Taki efekt zapewni nam właśnie delkaracja transform: translate(-50%, -50%);
. Tutaj 50% nie odnosi się do rozmiaru
rodzica, a do rozmiaru samego kwadratu.
Dla uściślenia: pierwsze -50%
oznacza przesunięcie w poziomie (oś X), drugie w pionie (oś Y).
Podsumowanie
Poznałeś 3 najlepsze/najprostsze, według mnie, sposoby na wyśrodkowanie elementu w poziomie i pionie. Dla mnie najlepsze = najprostsze, ale niestety czasem brak wsparcia przeglądarki dla flexboxa może cię zmusić do użycia mniej przyjemnego i mniej oczywistego sposobu.
Dobra wiadomość jest taka, że już dzisiaj (2020 rok) brak wsparcia dla flexboxa jest marginalnym problemem. W dodatku czas działa na naszą korzyść i będzie tylko lepiej ✌️.