Technika clearfix, floatfix

W poprzedniej części kursu CSS poznaliśmy jeden z najpopularniejszych sposób, za pomocą którego możemy sprawić, aby dwa lub więcej elementów blokowych, np. elementów div, wyświetliło się obok siebie. Był to sposób z wykorzystaniem właściwości float. W pewnym momencie element div, w którym umieściliśmy inne elementy div wraz z właściwością float, przestał "widzieć" wysokość swoich dzieci i przez to jego wysokość wynosiła 0 (widzieliśmy tylko jego obramowanie).

Sytuacja ta została przedstawiona poniżej:

div - 1
div - 2

A tak wyglądał kod HTML omawianej sytuacji:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
    </div>

  </body>
</html>

W poprzedniej części kursu CSS poznaliśmy dwa najczęściej wykorzystywane sposoby na pozbycie się problemów ze wspomniana wysokością elementu rodzica. Były to sposoby, które w głównej mierze wykorzystywały właściwość clear oraz wartość both. Wspomniane sposoby zostaną jeszcze raz, pokrótce, przedstawione w tej części kursu CSS. Dowiemy się również o innych sposobach, które będą posiadały w sobie pewne ograniczenia. Tego typu techniki noszą nazwę clearfix lub, nieco rzadziej, floatfix.

Sposób 1
Dodatkowy element HTML z właściwością "clear" o wartości "both"

Sposób ten poznaliśmy w poprzedniej części kursu CSS. Polegał on na dodaniu dodatkowego blokowego elementu HTML, wraz z właściwością clear oraz wartością both, do zawartości elementu HTML, który posiadał wyłącznie elementy HTML z właściwością float:left; lub float:right; Wspomniany dodatkowy element HTML wraz z właściwością clear:both; należało umieścić bezpośrednio po elementach z właściwością float:left; lub float:right; ponieważ właściwość clear:both; zabrania unosić się elementom HTML nad danym elementem HTML, do którego została dodana właściwość clear:both; tylko w przypadku gdy elementy unoszące występują, w kodzie HTML, bezpośrednio przed elementem HTML z właściwością clear:both;

Kod dokumentu HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
      }

      #dziecko3 {
        clear:both;
        background-color:gold;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
      <div id="dziecko3">dodatkowy element - div</div>
    </div>

  </body>
</html>

Rezultat:

div - 1
div - 2
dodatkowy element - div

Jedyną wadą omawianego sposobu jest fakt, że nie zawsze potrzebujemy dodatkowego elementu HTML w naszym układzie elementów HTML, który będzie znajdował się w zaprezentowanym miejscu. Oczywiście moglibyśmy taki element pozostawić bez zawartości, jednak pustych elementów HTML nie należy używać w naszym kodzie HTML, bo jest to nieestetyczne. Jeden pusty element nikomu nie zaszkodzi, jednak ich większa ilość może spotkać się z opinią, że nasz kod HTML jest mało profesjonalny.

Sposób 2
Wykorzystanie selektora ":after" oraz właściwości "content" wraz z innymi właściwościami CSS

Sposób ten również poznaliśmy w poprzedniej części kursu CSS. Jest on bardzo podobny do sposobu pierwszego, lecz eliminuje on problem występowania dodatkowego elementu HTML w kodzie dokumentu HTML. Dodatkowy blokowy element HTML wraz z właściwością clear:both; jest tworzony za pomocą właściwości content oraz jest dodawany do końcowej zawartości danego elementu HTML za pomocą selektora :after

Kod dokumentu HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
      }

      .floatfix {
        zoom:1; /* dla IE < 8 */
      }

      .floatfix:after {
        content:'';
        display:block;
        clear:both;
      }
    </style>
  </head>

  <body>

    <div id="rodzic" class="floatfix">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
    </div>

  </body>
</html>

Rezultat:

div - 1
div - 2

Omawiany sposób ma jedną wadę, ponieważ selektor :after nie jest interpretowany przez przeglądarkę internetową Internet Explorer w wersji wcześniejszej niż 8, jednak tak naprawdę w dzisiejszych czasach mało kto korzysta z przeglądarki Internet Explorer 7.

Oczywiście istnieją sposoby, aby rozwiązać nasz problem również dla przeglądarki IE 7. Wystarczy dodać właściwość zoom wraz z wartością 1 do elementu rodzica unoszących się elementów HTML (zostało to uwzględnione w poprzednim kodzie HTML). Właściwość zoom:1; sprawi, że dany element HTML będzie posiadał swoje rzeczywiste rozmiary, czyli jego wartość szerokości oraz wysokości nie zostanie pomniejszona ani powiększona. Po dodaniu właściwości zoom:1; do elementu rodzica unoszących się elementów HTML, wysokość elementu rodzica zostanie "naprawiona". Czemu w tym wypadku tak się dzieje? To pytanie trzeba zadać twórcom "dziwnej" przeglądarki Internet Explorer 7 :)

Sposób 3
Właściwość "overflow" wraz z wartością "hidden" lub "auto"

Sposób ten polega na wykorzystaniu dodatkowych cech właściwości overflow, która w normalnych okolicznościach jest wykorzystywana po to, aby ukryć zawartość, która nie mieści się w granicy elementu HTML, jednak zyskuje ona dodatkową cechę działania, gdy dodamy ją do elementu rodzica wraz z wartością hidden lub auto, ponieważ sprawi ona, że wspomniany element HTML będzie reagował na swoją ewentualną unoszącą się zawartość, czyli na elementy HTML z właściwością float:left; lub float:right;

Kod dokumentu HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        overflow:hidden;
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
    </div>

  </body>
</html>

Rezultat:

div - 1
div - 2

Omawiany sposób ma jedną wadę, ponieważ w momencie gdy będziemy chcieli umieścić jakiś element HTML, który ma znaleźć się poza granicami elementu rodzica, to cześć takiego elementu HTML, która nie będzie mieścić się we wspomnianym elemencie rodzicu, zostanie ukryta.

Taka sytuacja została zaprezentowana poniżej:

div - 1
div - 2
inny element - div

Sposób 4
Element "rodzic" z właściwością "float"

Sposób ten polega na sprawieniu, aby element rodzic unoszących się elementów HTML stał się również elementem unoszącym się, np. poprzez dodanie do niego właściwości float:left;

Kod dokumentu HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        float:left;
        width:80%;
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
    </div>

  </body>
</html>

Rezultat:

div - 1
div - 2

Nasz problem został naprawiony, lecz od tej pory element rodzic jest unoszącym się elementem HTML, dlatego będzie on sprawiał te same problemy dla swojego własnego elementu rodzica. Dodatkowo musi on posiadać jakąś ustaloną wartość właściwości width, jeżeli nie chcemy, aby jego szerokość dopasowywała się automatycznie do jego zawartości.

Sposób 5
Ustalenie stałej wartości wysokości lub minimalnej wysokości dla elementu "rodzica"

W przypadku gdy potrafimy przewidzieć, że wszystkie dzieci elementu rodzica będą mieć taką samą wysokość, to możemy wykorzystać to, do ustalenia takiej samej wysokości dla elementu rodzica, jak również dla jego elementów dzieci. Efekt ten możemy uzyskać za pomocą właściwości height, min-height lub max-height, należy ją dodać do elementu rodzica oraz jego unoszących się dzieci. Dodatkowo, jeżeli chcemy, aby tekst umieszczony w elementach unoszących się, które są dziećmi, był wyśrodkowany w pionie, to należy dodać do wspomnianych elementów HTML właściwość line-height, a nie jedną ze wcześniej wymienionych przeze mnie właściwości CSS.

Kod dokumentu HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      #rodzic {
        background-color:black;
        border:3px dashed red;
        font-size:1.4em;
        height:50px;
      }

      #dziecko1 {
        float:left;
        width:40%;
        background-color:lightblue;
        line-height:50px;
      }

      #dziecko2 {
        float:left;
        width:30%;
        background-color:lightgreen;
        line-height:50px;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">
      <div id="dziecko1">div - 1</div>
      <div id="dziecko2">div - 2</div>
    </div>

  </body>
</html>

Rezultat:

div - 1
div - 2

Należy pamiętać, że w przypadku gdy zawartość, któregokolwiek z omawianych elementów HTML, przekroczy wartość wysokości, to taka sytuacja może spowodować niepożądane efekty.

Przykład:

zawartość tego elementu - div - nie mieści się w nim
div - 2

Podsumowanie

W tej części kursu CSS zostały zaprezentowane sposoby na "naprawę" wysokości elementu rodzica, który zawiera w sobie unoszące się elementy HTML, czyli takie elementy HTML, które posiadają właściwość float:left; lub float:right; W różnych sytuacjach należy korzystać z różnych sposobów na rozwiązanie wspomnianego problemu, jednak ogólnie zaleca się korzystanie ze sposobu drugiego.

W następnej części kursu CSS poznamy inne sposoby na wyświetlenie blokowych elementów HTML obok siebie.