22. Pozycjonowanie elementów w CSS

> Dodaj do ulubionych

O rozmieszczeniu elementów HTML na stronie internetowej decyduje kilka czynników. Pierwszym z nich, branym pod uwagę przez przeglądarkę, jest to, jakiego rodzaju jest dany element. Zgodnie z modelem polowym CSS, element HTML może być śródliniowy lub blokowy. Każdy jest domyślnie przyporządkowany do jednej grupy i jeśli nie zostanie to zmienione za pomocą własności CSS display, zachowuje się zgodnie z obowiązującymi ją standardowymi zasadami.

Elementy blokowe, takie jak na przykład p czy div, tworzą w pamięci przeglądarki pola blokowe, które zajmują całą dostępną powierzchnię w poziomie i są układane jedno pod drugim. Z kolei elementy śródliniowe, na przykład span czy strong, tworzą tzw. pola śródliniowe, które są umieszczane obok siebie i zajmują tylko tyle miejsca, ile potrzeba na ich treść.

W obu przypadkach w grę wchodzą jeszcze dodatkowe czynniki, takie jak między innymi marginesy czy dopełnienie, które mogą zwiększać lub zmniejszać odstępy między elementami, ale to nie zmienia faktu, że elementy te są rozmieszczone w standardowy sposób.

Elementy ułożone według tych podstawowych zasad modelu polowego CSS znajdują się w układzie normalnym . Obowiązują w nim różne reguły, zgodnie z którymi elementy blokowe powinny być układane jeden pod drugim, jeśli dwa elementy blokowe stykają się górną i dolną krawędzią, to w miejscu ich styku dochodzi do scalenia marginesów, elementy śródliniowe domyślnie zajmują w poziomie tylko tyle miejsca, ile zajmuje ich zawartość itd.

Czasami jednak te podstawowe zasady są niewystarczające do uzyskania pożądanego efektu estetycznego na stronie. Projektant może chcieć, aby wybrany element na ekranie znajdował się w innym miejscu niż wskazywałoby na to jego umiejscowienie w kodzie HTML i w układzie normalnym. W takiej sytuacji należy skorzystać z technik pozycjonowania elementów w CSS.

Ich podstawę stanowi własność position oraz jej własności towarzyszące top, right, bottom, left (określające odpowiednio odległość od górnej, prawej, dolnej i lewej krawędzi i zbiorczo nazywane kierunkami fizycznymi) i z-index (określająca położenie elementu na osi 𝑧). Służą one do określania położenia wybranych elementów na stronie w odniesieniu do innych elementów (pozycjonowanie w układzie normalnym) lub względem czegoś innego (pozycjonowanie poza układem normalnym).

Pamiętaj tylko, że własność position służy do określania położenia indywidualnych elementów na stronie, a nie do podziału jej na sekcje czy do definiowania ogólnej struktury dokumentu. Do tego drugiego celu służą techniki tworzenia układów CSS, o których będzie jeszcze mowa w dalszej części tego kursu.

Za pomocą własności position elementy można pozycjonować na pięć następujących sposobów:

Każdy element, który ma własność position ustawioną na inną wartość niż static, jest elementem pozycjonowanym.

Oprócz tego istnieje jeszcze technika pozycjonowania elementów pływających. Opiera się ona na własnościach float i clear i jej opis także znajduje się tym rozdziale.

Zanim przejdziemy do omówienia każdego z wymienionych rodzajów pozycjonowania, zapoznaj się z poniższym przykładowym dokumentem HTML.


<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta  charset="utf-8">
    <title>Pozycjonowanie  elementów HTML w CSS</title>
    <style>
      body {
        width: 550px;
        border: 1px  solid green;
      }
      p {
        padding: 15px;
        margin:  10px;
        border:  1px solid lightpink;
      }
    </style>
  </head>
  <body>
    <h1>Pozycjonowanie  elementów HTML w CSS</h1>
    <p id="a">To jest pierwszy  akapit, który zawiera trochę ciekawej oraz <strong>bardzo  ważnej</strong> treści.</p>
    <p id="b">To jest drugi  akapit, w którym też znajduje się <em>niezwykle</em> zajmująca  <span>treść</span>.</p>
    <p id="c">W trzecim akapicie  dowiesz się naprawdę niesamowitych rzeczy na temat tworzenia stron  internetowych.</p>
    <p id="d">Z kolei po lekturze  czwartego akapitu będziesz posiadać już wysoce specjalistyczną wiedzę, która  odmieni Twoje życie.</p>
  </body>
</html>

Ten dokument w przeglądarce internetowej wygląda tak, jak na poniższym zrzucie ekranu.

Wygląd przykładowego dokumentu w przeglądarce internetowej

Zgodnie z modelem polowym CSS, elementy blokowe, p i h1, zajmują całe dostępne miejsce w poziomie i zostały ułożone jeden pod drugim, a elementy śródliniowe, span i strong, zajmują tylko tyle miejsca, ile potrzeba im na ich zawartość i zostały ułożone w jednej linii z tekstem oraz obok siebie nawzajem.

Teraz użyjemy własności position, aby trochę wśród nich „namieszać”. Zaczniemy od najprostszego przypadku, czyli pozycjonowania statycznego.

Pozycjonowanie statyczne

Pozycjonowanie statyczne (ang. static positioning) jest najprostsze, ponieważ jest to domyślny sposób pozycjonowania tożsamy ze standardowym rozmieszczeniem elementów w układzie normalnym. Aby je zastosować, należy własności position nadać wartość static:


position: static;

Jako że ta wartość jest domyślna, to normalnie nie ma potrzeby jej definiować, ale może się ona czasami przydać, aby przywrócić to ustawienie, gdy zostało zmienione gdzieś indziej.

W tym rodzaju pozycjonowania nie działają też własności kierunkowe (top, right, bottom i left ani ich logiczne odpowiedniki inset-block-start, inset-inline-start, inset-block-end oraz inset-inline-end) oraz z-index, a więc nie ma możliwości przenoszenia elementów poza ich domyślne położenie. Możliwość taką daje natomiast pozycjonowanie względne, które jest opisane w następnej kolejności.

Pozycjonowanie względne

Pozycjonowanie względne, zwane też relatywnym (ang. relative positioning) polega na ustalaniu położenia elementu na stronie w odniesieniu do jego normalnej pozycji. To znaczy, że najpierw przeglądarka umieszcza dany element w układzie normalnym (jakby był pozycjonowany statycznie), po czym przemieszcza go odpowiednio zgodnie z ustawieniami własności top, right, bottom i left.

Aby włączyć pozycjonowanie względne elementu, należy własności position nadać wartość relative:


position: relative;

Jednak sama ta czynność nie wystarczy, aby element w jakikolwiek sposób zmienił swoje położenie. Dodatkowo za pomocą własności top, right, bottom i left należy określić, o ile ma zostać przesunięty względem swojej statycznej pozycji.

Odnosząc się do naszego przykładowego dokumentu HTML, powiedzmy że chcemy przesunąć drugi akapit, o identyfikatorze b, o 100 pikseli w prawo i o 20 pikseli w dół. W tym celu własności left nadamy wartość 100px, a własności top – wartość 20px:


#b {
  position: relative;
  top: 20px;
  left: 100px;
}

Efekt dodania tej reguły do arkusza stylów w naszym dokumencie będzie taki:

Efekt pozycjonowania względnego position: relative

Zwróć uwagę, że pierwotny obszar zarezerwowany przez przeglądarkę dla pozycjonowanego względnie elementu pozostał nienaruszony, mimo że element ten już go nie zajmuje. W efekcie pozostało po nim puste miejsce na stronie.

Ponadto elementy pozycjonowane względnie mogą tworzyć tzw. kontekst stosowy.

Kontekst stosowy

Kontekst stosowy (ang. stacking context) to trójwymiarowy model rozmieszczenia elementów HTML na wirtualnej osi 𝑧. Można go sobie wyobrazić tak, jakby elementy na stronie były ułożone „jeden nad drugim” z punktu widzenia użytkownika.

W przypadku elementów pozycjonowanych statycznie, w układzie normalnym, pojęcie kontekstu stosowego nie ma znaczenia, ponieważ te elementy nie mogą na siebie wzajemnie nachodzić, w związku z czym nie istnieje problem tego, który z nich ma być na wierzchu, a który pod spodem.

Najłatwiej wyobrazić to sobie na konkretnym przykładzie. Poprzednio zastosowaliśmy pozycjonowanie względne do drugiego akapitu na naszej stronie, przez co częściowo przesłonił on akapit trzeci. Poniższy zrzut ekranu przedstawia ten sam przykład, tylko z dodanymi kolorami tła do interesujących nas elementów, aby lepiej było widać, o co chodzi.

Dwa elementy nachodzące na siebie
Akapit z zielonym tłem jest pozycjonowany względnie i nachodzi na akapit z różowym tłem, który jest pozycjonowany statycznie

Na tej ilustracji wyraźnie widać, że elementy tworzą „wirtualny stos”, w którym na wierzchu znajduje się element zielony, a pod spodem – element różowy.

A co zrobić, gdybyśmy chcieli, aby to element różowy był na wierzchu, a zielony na spodzie? Do ustawiania kolejności elementów na stosie służy własność z-index. Działa ona tylko z elementami pozycjonowanymi inaczej niż statycznie, więc aby zmienić kolejność na stosie naszych dwóch elementów, różowemu elementowi także musimy zdefiniować własność position o wartości innej niż static.

Jeśli chcemy tylko mieć możliwość panowania nad stosem bez zmiany pozycji i relacji z otoczeniem różowego akapitu, to możemy włączyć mu pozycjonowanie względne, nie definiując własności kierunkowych. W ten sposób zacznie on „obsługiwać” stos, ale nic poza tym się dla niego nie zmieni. Poniżej znajduje się odpowiedni kod CSS:


#b {
  position: relative;
  top: 20px;
  left: 100px;
  background-color: lightgreen;
}

#c {
  position: relative;
  background-color: lightpink;
}

Tak naprawdę już samo to wystarczy do uzyskania efektu, o który nam chodzi. Oba elementy są pozycjonowane względnie, jeden nachodzi na drugi i brak jeszcze jakichkolwiek ustawień związanych z kontekstem stosowym, w efekcie czego przeglądarka domyślnie umieści na wierzchu ten element, który znajduje się dalej w kodzie HTML.

Powiedzmy jednak, że chcemy mieć pełną samodzielną kontrolę nad rozmieszczeniem naszych elementów na osi 𝑧. W tym celu użyjemy własności z-index, która jako wartość przyjmuje liczbę całkowitą bez jednostki. Im większa ta liczba, tym wyżej na stosie („bliżej użytkownika”) zostaje umieszczony element. Jeśli więc chcemy, aby element zielony był na górze, a różowy na dole, to pierwszemu możemy przypisać własność z-index o wartości 1, a drugiemu – własność z-index o wartości 0.


#b {
  position: relative;
  top: 20px;
  left: 100px;
  z-index: 1;
  background-color: lightgreen;
}

#c {
  position: relative;
  z-index: 0;
  background-color: lightpink;
}

Zielony akapit znów będzie znajdował się na górze, jak na wcześniejszym zrzucie ekranu.

Oczywiście na stosie może znajdować się dowolna liczba elementów. Spójrz na poniższy zrzut ekranu:

Cztery elementy pozycjonowane względnie ułożone w stos

Są to akapity z poprzedniego przykładu, którym zdefiniowano pozycjonowanie względne i dodano kolory tła, aby lepiej było widać zajmowane przez nie powierzchnie. Poniżej znajduje się kod, za pomocą którego uzyskałem ten efekt:


#a {
  position: relative;
  background-color: lightyellow;
}

#b {
  position: relative;
  top: -70px;
  left: 80px;
  background-color: lightgreen;
}

#c {
  position: relative;
  top: -120px;
  left: 150px;
  background-color: lightpink;
}

#d {
  position: relative;
  top: -190px;
  left: 210px;
  background-color: lightblue;
}

Teraz za pomocą własności z-index zmienimy ułożenie tych elementów na stosie:


#a {
  position: relative;
  z-index: 4;
  background-color: lightyellow;
}

#b {
  position: relative;
  top: -70px;
  left: 80px;
  z-index: 2;
  background-color: lightgreen;
}

#c {
  position: relative;
  top: -120px;
  left: 150px;
  z-index: 1;
  background-color: lightpink;
}

#d {
  position: relative;
  top: -190px;
  left: 210px;
  z-index: 3;
  background-color: lightblue;
}

Obecnie nasze elementy są ułożone w sposób widoczny poniżej:

Rozmieszczenie elementów w kontekście stosowym za pomocą własności z-index

Jak widać, elementy zostały rozmieszczone na stosie zgodnie z ustawieniami ich własności z-index.

Pozycjonowanie absolutne

Pozycjonowanie absolutne, zwane też bezwzględnym (ang. absolute positioning), polega na ustaleniu położenia elementu w odniesieniu do najbliższego pozycjonowanego przodka (czyli zawierającego go elementu, który ma zdefiniowaną własność position o wartości innej niż static), a jeśli taki nie istnieje, to w odniesieniu do początkowego bloku zawierającego (ang. initial containing block), czyli bloku, który zawiera element główny dokumentu – mówiąc w uproszczeniu, taki element jest pozycjonowany względem krawędzi ekranu.

Elementy pozycjonowane absolutnie, w odróżnieniu od pozycjonowanych względnie, zostają wyjęte z układu normalnego. To znaczy, że nie pozostaje po nich puste miejsce na stronie. Elementy sąsiadujące w kodzie HTML z elementem pozycjonowanym absolutnie zachowują się tak, jakby go w ogóle w tym miejscu nie było, a więc jeśli znajdują się w kodzie za nim, to „wskakują na jego miejsce”.

Ponadto elementy pozycjonowane absolutnie nie zajmują maksymalnej dostępnej przestrzeni w poziomie, jak „zwykłe” elementy blokowe, tylko obkurczają się do rozmiaru znajdującej się w nich treści, oraz nie występuje w ich przypadku scalanie marginesów.

Aby pozycjonować element absolutnie, najpierw należy włączyć ten rodzaj pozycjonowania przez nadanie własności position wartości absolute, a następnie należy określić jego położenie za pomocą własności top, right, bottom i left.

Poniżej znajduje się prosty przykład, w którym element article zawiera element div umieszczony w jego dolnym prawym rogu.


article {
  position: relative;
  width: 250px;
  height: 150px;
  border: 3px solid green;
}

div {
  width: 50px;
  height: 30px;
  border: 3px solid maroon;
  position: absolute;
  right: 0;
  bottom: 0;
}

Efekt:

Efekt użycia własności position: absolute

Zwróć uwagę, że element article ma własność position ustawioną na relative. Bez tego ustawienia położenie zawartego w nim elementu div pozycjonowanego absolutnie zostałoby wyznaczone w odniesieniu do nadrzędnego elementu pozycjonowanego albo, gdyby taki nie istniał, w odniesieniu do początkowego bloku zawierającego (krawędzi okna przeglądarki).

Jeśli element pozycjonowany absolutnie ma zdefiniowane marginesy, to przesuwają element względem jego położenia ustalonego przez własności kierunkowe.

Ponadto elementy pozycjonowane absolutnie tworzą kontekst stosowy, jeśli mają własność z-index ustawioną na inną wartość niż auto.

Pozycjonowanie stałe

Pozycjonowanie stałe (ang. fixed positioning) ma wiele cech wspólnych z pozycjonowaniem absolutnym i jest uważane za jego rodzaj. W tym przypadku pozycjonowany element również zostaje wyjęty z układu normalnego, nie zajmuje miejsca wśród innych elementów i ma położenie ustalane przez własności kierunkowe.

Cechą odróżniającą element pozycjonowany stale od pozycjonowanego absolutnie jest to, że jego położenie jest ustalane w odniesieniu do początkowego bloku zawierającego, czyli w przypadku przeglądarek internetowych – do obszaru widoku (krawędzi okna przeglądarki). To oznacza, że taki element cały czas znajduje się tym samym miejscu, nawet jeśli strona jest przewijana.

Aby zastosować pozycjonowanie stałe do elementu, należy własności position nadać wartość fixed, a następnie określić jego położenie za pomocą własności kierunkowe. Technika ta jest stosowana na przykład do tworzenia „przyklejonych” do górnej lub dolnej krawędzi ekranu pasków nawigacyjnych, np.:


div {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 40px;
  z-index: 999999;
}

Ten kod tworzy element div o wysokości 32 pikseli i szerokości równej szerokości ekranu. Za pomocą pozycjonowania stałego został ustawiony w lewym górnym rogu ekranu i pozostanie tam przez cały czas, nawet po przewinięciu strony w dół. Własność z-index o bardzo wysokiej wartości została mu nadana po to, aby przez przypadek nie przesłonił go żaden inny pozycjonowany element.

Pozycjonowanie kleiste

Pozycjonowanie kleiste (ang. sticky positioning) łączy w sobie cechy innych rodzajów pozycjonowania: względnego, absolutnego i stałego. Polega ono na tym, że najpierw element jest pozycjonowany względnie w swoim kontenerze, a następnie jego położenie jest określane w obrębie tego kontenera, w odniesieniu do najbliższego elementu nadrzędnego obsługującego przewijanie, czyli najczęściej, mówiąc w uproszczeniu, elementu, którego zawartość spowodowała pojawienie się paska lub pasków przewijania.

Inaczej mówiąc, jeśli jakiś element, niech będzie aside, umieścimy na przykład w elemencie div i nadamy mu pozycjonowanie kleiste (za pomocą własności position o wartości sticky), to jego początkowe położenie zostanie określone względem jego pierwotnej pozycji w układzie normalnym:


<style>
body {
  height: 10000px;
  width: 10000px;
  padding: 20px;
  margin: 0;
}
div {
  border: 1px solid black;
  width: 300px;
  height: 200px;
  padding: 10px;
}

aside {
  position: sticky;
  width: 100px;
  background-color: lightpink;
}
</style>

<body>
  <div>
    <p>Jakaś treść...</p>
    <aside>Element przyklejony</aside>
    <p>Dalsza treść...</p>
  </div>
</body>

Efekt tego kodu będzie taki:

Efekt zastosowania position: sticky bez własności kierunkowych

W tym przykładzie element aside jest pozycjonowany kleiście w swoim kontenerze div, ale nie ma jeszcze zdefiniowanych własności kierunkowych, więc nie został w żadnym kierunku przesunięty. Przeglądarka umieściła go na pozycji początkowej w układzie normalnym. Ponadto ma określone kolor tła i szerokość, aby go było dobrze widać.

Reguła CSS dotycząca elementu div ma znaczenie estetyczne i pozwala dokładnie zaobserwować jego granice, co będzie ważne później.

Elementowi body nadaliśmy wysokość i szerokość aż 10000 pikseli, aby mieć pewność, że stronę będzie dało się przewijać w dwóch kierunkach, co pozwoli zaobserwować efekt przyklejenia elementu aside.

Wracając do elementu aside, teraz za pomocą własności top i left „przykleimy” go w odległości 70 pikseli od górnej oraz 100 pikseli od lewej krawędzi najbliższego elementu przewijanego (w naszym przypadku będzie to body).


aside {
  position: sticky;
  width: 100px;
  background-color: lightpink;
  top: 70px;
  left: 100px;
}

Efekt dodania tych dwóch deklaracji do naszego arkusza stylów jest następujący:

Efekt przesunięcia elementu pozycjonowanego kleiście

Element aside został przyklejony w odległości 70 pikseli od górnej i 100 od lewej krawędzi elementu body, ale to nie znaczy, że od razu znalazł się na tej pozycji. Dopóki nie przewiniemy strony, położenie tego elementu jest wyznaczone następująco:

  1. Przeglądarka sprawdza, czy zgodnie z układem normalnym górna krawędź elementu aside znajduje się dalej od górnej krawędzi elementu body niż wskazuje własność top.
  2. Jeśli tak, to przeglądarka odsuwa górną krawędź elementu aside od górnej krawędzi elementu body na odległość określoną przez własność top.
  3. Jeśli nie, to przeglądarka na razie nie przesuwa elementu aside w dół. Tak jest w przedstawionym przykładzie.
  4. Przeglądarka sprawdza , czy zgodnie z układem normalnym lewa krawędź elementu aside znajduje się dalej od lewej krawędzi elementu body niż wskazuje własność left.
  5. Jeśli tak, to przeglądarka odsuwa lewą krawędź elementu aside od lewej krawędzi elementu body na odległość określoną przez własność left. Tak jest w naszym przypadku.
  6. Jeśli nie, to przeglądarka na razie nie przesuwa elementu aside w lewo.

Teraz w odniesieniu do tak ustalonej pozycji położenie elementu aside będzie korygowane w obrębie kontenera (elementu div) w miarę przewijania strony. Będzie się on przemieszczał wraz ze swoim kontenerem, aż znajdzie się dokładnie w położeniu, w którym został przyklejony, czyli w odległości 70 pikseli od górnej krawędzi elementu body i 100 pikseli od lewej krawędzi elementu body.

Jednak zakres ruchu elementu przyklejonego jest ograniczony do jego kontenera. Kiedy przyklejony element „dotrze” do granicy swojego kontenera, przemieści się wraz z nim poza krawędź ekranu.

Inaczej mówiąc, element aside został przyklejony na danej pozycji w obrębie swojego bezpośredniego kontenera. Jeśli przewiniemy stronę w dół lub w prawo, to prawie cała jej treść będzie się normalnie przewijać. Natomiast element aside przemieści się na swoją docelową pozycję i pozostanie nieruchomy dopóki nie znajdzie się przy lewej lub górnej krawędzi swojego bezpośredniego kontenera. Kiedy to się stanie, zniknie z ekranu razem z tym kontenerem. Spójrz na poniższy zrzut ekranu.

Ustawienie position: sticky po przewinięciu strony

Przyklejony element cały czas znajduje się w tym samym miejscu w odniesieniu do elementu body, ale jego położenie względem elementu div, który został przewinięty wraz ze stroną, jest już inne. Znajduje się już przy jego dolnej i prawej granicy, więc dalsze przewijanie w tych samych kierunkach spowoduje, że w końcu on także zostanie przewinięty poza krawędź ekranu:

Ilustracja elementu przenoszonego poza krawędź ekranu przez przewijanie

Podsumowując, pozycjonowanie kleiste elementów w CSS obejmuje dwa składniki: element przyklejony i kontener elementu przyklejonego.

Element przyklejony to ten, który ma zdefiniowaną deklarację position: sticky (aside w naszym przykładzie).

Kontener elementu przyklejonego zawiera element przyklejony i stanowi obszar, w obrębie którego ten element może się unosić nad treścią. Kontenerem takim zawsze automatycznie staje się rodzic elementu pozycjonowanego kleiście.

Do dwóch powyższych składników można jeszcze dodać trzeci: najbliższy nadrzędny element obsługujący przewijanie, czyli ten element, w odniesieniu do którego będzie ustalona pozycja elementu przyklejonego w jego kontenerze.

Poniżej możesz wypróbować przedstawiony kod, aby sprawdzić, jak dokładnie to działa.

See the Pen Untitled by Łukasz Piwko (@shebangpl) on CodePen.

Pozycjonowanie pływające

Pozycjonowanie pływające ma bogatszą i bardziej zawiłą historię niż poprzednie rodzaje pozycjonowania. Początkowo technika ta miała służyć do umieszczania obrazów graficznych po lewej lub po prawej stronie w kolumnach tekstu tak, że tekst „opływał” go z jednej strony. To powszechnie stosowany zabieg estetyczny w książkach, gazetach i na stronach internetowych.

Ponieważ jednak w tamtych czasach nie istniały jeszcze takie technologie CSS, jak Flexbox czy Grid Layout, które zapewniają doskonałe narzędzia do definiowania układów rozmieszczenia elementów na stronie internetowej, projektanci musieli uciekać się do stosowania różnych sztuczek.

Bardzo szybko zauważono, że elementami pływającymi mogą być nie tylko obrazy, ale także inne elementy HTML na stronie. W związku z tym technikę tę zaczęto wykorzystywać do tworzenia całych układów stron, złożonych z kolumn umieszczonych obok siebie. Choć taki sposób używania elementów pływających był niezgodny z ich pierwotnym przeznaczeniem, i tak oznaczał krok naprzód w porównaniu z jeszcze starszymi metodami definiowania układów stron na bazie tabel HTML.

Obecnie rozwój technologii CSS i przeglądarek internetowych sprawił, że nie ma już potrzeby nadużywania elementów pływających, ani tym bardziej tabel. Do tworzenia układów stron służą technologie CSS Flexbox i Grid Layout, a elementami pływającymi znów powinny być przede wszystkim obrazy graficzne otoczone tekstem.

Jeśli ciekawią Cię stare techniki tworzenia układów stron na podstawie elementów pływających, to obszerny opis znajdziesz na stronie 101 porad na temat używania elementów pływających w CSS. Natomiast w tym artykule znajduje się opis poprawnego użycia technik pozycjonowania pływającego zgodnie z ich pierwotnym przeznaczeniem.

Tworzenie elementów pływających

Pozycjonowanie pływające różni się od poprzednich metod pozycjonowania tym, że nie opiera się na własności position, tylko na własności float. Sposób jej użycia jest bardzo prosty, a przedstawię go na przykładzie poniższej strony HTML.


<style>
body {
  width: 600px;
}
</style>
...
<h2>Dwaj poeci</h2>
<img src="balzac.webp" width="200" height="182">
<p>W epoce, gdy zaczyna się ta historia, prasa Stanhope'a i rulony do rozdzielania farby drukarskiej nieznane były jeszcze w małych drukarniach na prowincji. Mimo specjalności, dzięki której miasto to pozostaje w zetknięciu z typografią paryską, Angoul?me posługiwało się ciągle prasą drewnianą, któremu to instrumentowi język zawdzięcza wyrażenie "jęczenie prasy", obecnie bez zastosowania.</p>
<p>Zacofane drukarnie używały jeszcze poduszeczek skórzanych napojonych farbą, którymi tłocznik ręcznie pocierał czcionki. Ruchoma płyta, na której spoczywa forma pełna czcionek, była jeszcze z kamienia i usprawiedliwiała nazwę marmuru.</p>
<p>Pochłaniające wszystko prasy mechaniczne tak dalece wtrąciły już w zapomnienie ten system, któremu zawdzięczamy, mimo jego niedoskonałości, piękne wydawnictwa Elzewirów, Plantynów i Didotów, że trzeba nam wspomnieć tutaj nieco o starych narzędziach, do których Hieronim Mikołaj Séchard żywił zabobonne przywiązanie, odgrywają bowiem one swoją rolę w tej małej, a zarazem dużej opowiastce.</p>

Jeśli teraz skopiujesz ten kod do edytora HTML i otworzysz tę stronę w przeglądarce, to wszystkie elementy zostaną rozmieszczone zgodnie z zasadami układu normalnego, jeden pod drugim w kolejności występowania w kodzie źródłowym, jak widać na poniższym zrzucie ekranu.

Przykładowy dokument w podstawowej formie

Aby utworzyć element pływający, należy nadać mu własność float o odpowiedniej wartości. Powiedzmy, że w naszym przykładzie chcemy, żeby zdjęcie Honoriusza Balzaca „spłynęło” do lewej krawędzi kontenera (tu elementu body), aby tekst znalazł się po jego prawej stronie i pod nim. W tym celu musimy elementowi img nadać własność float o wartości left (dla prawej strony użylibyśmy wartości right), jak widać poniżej:


img {
  float: left;
}

Efekt dodania tej reguły CSS do naszego arkusza stylów będzie następujący:

Efekt zastosowania deklaracji float: left do elementu img

Obraz został umieszczony przy lewej krawędzi swojego kontenera, a tekst znalazł się po jego prawej stronie i pod nim. Jednak z powodu braku marginesów nie wygląda to zbyt atrakcyjnie. Dodamy więc jeszcze marginesy:


img {
  float: left;
  margin: 0 10px 10px 0;
}

Teraz tekst będzie odrobinę odsunięty od prawej i dolnej krawędzi obrazu, jak widać na poniższym zrzucie ekranu:

Efekt zdefiniowania marginesu elementowi pływającemu

Obejmowanie elementu pływającego przez kontener

Jak już pisałem, elementy pływające są wyjmowane z układu normalnego elementów na stronie i „unoszą się” nad nimi. Można to łatwo zaobserwować przez nadanie akapitom w naszym przykładzie koloru tła:


p {
  background-color: lightpink;
}

Efekt dodania tej reguły jest taki:

Wizualizacja pływania elementu pływającego nad innymi elementami

Widać, że obraz nakłada się na pola tworzone przez akapity, których treść została przesunięta tak, aby zrobić odpowiednią ilość miejsca dla elementu pływającego.

Może się jednak zdarzyć, że będziemy chcieli umieścić obraz tylko w jednym akapicie i będziemy chcieli, aby ten akapit obejmował go w całości, pozostawiając po prostu puste miejsce, jeśli treści jest niewystarczająca ilość. Powiedzmy na przykład, że obraz na naszej stronie chcemy umieścić w pierwszym akapicie:


<p id="pierwszy">
  <img src="balzac.webp" width="200" height="182">
  W epoce, gdy zaczyna się ta historia, prasa Stanhope'a i rulony do rozdzielania farby drukarskiej nieznane były jeszcze w małych drukarniach na prowincji. Mimo specjalności, dzięki której miasto to pozostaje w zetknięciu z typografią paryską, Angoul?me posługiwało się ciągle prasą drewnianą, któremu to instrumentowi język zawdzięcza wyrażenie "jęczenie prasy", obecnie bez zastosowania.
</p>

Wcześniej obraz znajdował się bezpośrednio w elemencie body, a teraz znajduje się w pierwszym elemencie p (o identyfikatorze pierwszy) i chcemy, aby akapit ten obejmował go w całości, nawet jeśli ilość zawartego w nim tekstu jest do tego niewystarczająca. Na razie na stronie nic się nie zmieni (będzie wyglądała identycznie, jak poprzednio), ponieważ element pływający nadal będzie wyjęty z układu normalnego, a akapit, w którym się znajduje, nie tworzy blokowego kontekstu formatowania.

Dawniej problem ten rozwiązywano przy użyciu różnych sprytnych sztuczek. Do najpopularniejszych z nich należała tzw. metoda clearfix, która w zależności od wersji polegała na odpowiednim ustawieniu własności overflow albo na dodaniu pseudoelementu ::after o odpowiednich właściwościach.

Obecnie nie ma już potrzeby stosować tych przestarzałych technik i wystarczy elementowi zawierającemu nadać własność display o wartości flow-root, która powoduje wytworzenie przez ten elementu blokowego kontekstu formatowania:


#pierwszy {
  display: flow-root;
}

Efekt dodania tej prostej deklaracji jest następujący:

Efekt dodania deklaracji display: flow-root

Jak widać, teraz pierwszy akapit w całości obejmuje znajdujący się w nim element pływający. Jest tak dlatego, ponieważ tworzy on samodzielny osobny blokowy kontekst formatowania, który stanowi coś w rodzaju kompletnej jednostki wśród innych elementów.

Czasami zdarza się też tak, że nie chcemy, aby wybrany element był wyświetlany obok elementu pływającego, tylko pod nim. W takiej sytuacji powinniśmy użyć własności clear.

Oczyszczanie pola

Wracając do podstawowej wersji naszego przykładu z elementem pływającym, tego bez deklaracji display: flow-root;, jeśli chcemy, aby treść pierwszego akapitu została umieszczona obok obrazka, a drugi akapit został przeniesiony pod niego, to temu drugiemu akapitowi powinniśmy nadać własność clear o wartości left. Takie ustawienie oznacza, że dany element nie może mieć elementów pływających po swojej lewej stronie:


<style>
img {
  float: left;
  margin: 0 10px 10px 0;
}

#drugi {
  clear: left;
}

</style>
...
<h2>Dwaj poeci</h2>

<p id="pierwszy"><img src="balzac.webp" width="200" height="182">W epoce, gdy zaczyna się ta historia, prasa Stanhope'a i rulony do rozdzielania farby drukarskiej nieznane były jeszcze w małych drukarniach na prowincji. Mimo specjalności, dzięki której miasto to pozostaje w zetknięciu z typografią paryską, Angouleme posługiwało się ciągle prasą drewnianą, któremu to instrumentowi język zawdzięcza wyrażenie "jęczenie prasy", obecnie bez zastosowania.</p>

<p id="drugi">Zacofane drukarnie używały jeszcze poduszeczek skórzanych napojonych farbą, którymi tłocznik ręcznie pocierał czcionki. Ruchoma płyta, na której spoczywa forma pełna czcionek, była jeszcze z kamienia i usprawiedliwiała nazwę marmuru.</p>

<p>Pochłaniające wszystko prasy mechaniczne tak dalece wtrąciły już w zapomnienie ten system, któremu zawdzięczamy, mimo jego niedoskonałości, piękne wydawnictwa Elzewirów, Plantynów i Didotów, że trzeba nam wspomnieć tutaj nieco o starych narzędziach, do których Hieronim Mikołaj Séchard żywił zabobonne przywiązanie, odgrywają bowiem one swoją rolę w tej małej, a zarazem dużej opowiastce.</p>

Teraz tylko treść pierwszego akapitu będzie „opływała” obraz z prawej strony. Natomiast drugi akapit zostanie umieszczony pod spodem, jak widać na poniższym zrzucie ekranu.

Efekt zastosowania deklaracji CSS clear: left

Własność clear przyjmuje wartości left, right (i ich logiczne odpowiedniki) oraz both działające w odniesieniu do elementów spływających do lewej, prawej lub jednych i drugich.

Autor: Łukasz Piwko