Przejdź do treści

Rozmiary - CSS

Szerokość i marginesy automatyczne

Co zrobić, aby szerokość i poziome marginesy dopasowywały się do sąsiednich elementów, tak aby wyświetlanie zawsze było poprawne? W jaki sposób wyśrodkować (wycentrować) tabelkę lub blok za pomocą CSS? Jak zbudować szkielet strony przy pomocy CSS?

Wstęp

Podanie wartości auto dla własności określającej szerokość elementu (width) lub jego marginesy (margin-left, margin-right) pozwala dopasować wybrany tą metodą wymiar w taki sposób, aby element poprawnie wyświetlił się w każdych warunkach. Poniżej znajdziesz opis wyznaczania szerokości i marginesów automatycznych dla różnych typów elementów w różnych przypadkach. Nie musisz od razu nauczyć się wszystkich zasad na pamięć, jednak wskazane jest przynajmniej przejrzenie poniższych opisów tak, aby w razie wątpliwości w przyszłości wiedzieć gdzie szukać wyjaśnienia.

Zdaję sobie sprawę, że przedstawione tutaj wzory i algorytmy obliczania pozycji mogą być mało mówiące i na początku trudne do przyswojenia. Dlatego raczej nie zalecam ślęczenia nad nimi teraz bez końca. Jeśli w przyszłości napotkasz problemy z wartością auto przypisaną dla szerokości lub poziomych marginesów, odszukaj ten rozdział, a następnie punkt, który odpowiada przypadkowi, z którym się będziesz borykać. Wtedy to już nie będzie "sucha" teoria, ale od razu zastosowanie praktyczne w konkretnym przykładzie, a więc dużo łatwiej będzie to sobie przyswoić.

Przed dalszą lekturą tego podrozdziału warto zwrócić uwagę na wartości domyślne, jakie przyjmują poszczególne własności, kiedy nie przypisze się im żadnych innych. Na przykład, jeżeli nie ustalimy marginesów elementu, przyjmą one wartości 0 (zero), co jest dosyć logiczne. To samo dotyczy marginesów wewnętrznych (padding) - przyjmują domyślną wartość zero. Jeżeli natomiast chodzi o szerokość, to domyślnie wcale nie przyjmuje wartości 100% - jak można by sądzić - ale auto. Zapamiętaj tę zasadę, bo dzięki temu unikniesz wielu nieporozumień.

Przedstawione poniżej punkty 1-6 oraz 9-10 obejmują również elementy pozycjonowane relatywnie.

1. Elementy inline, nie-zastępowane

Przykład: SPAN, B, I i inne (ale nie IMG, INPUT, TEXTAREA, SELECT, OBJECT, które są elementami zastępowanymi).

Własność width nie ma zastosowania (nie można jej przypisać). Podanie wartości auto dla left, right, margin-left lub margin-right oznacza przyjęcie dla nich ostatecznej wartości zero.

2. Elementy inline, zastępowane

Przykład: IMG, INPUT, TEXTAREA, SELECT, OBJECT.

Podanie wartości auto dla margin-left lub margin-right oznacza przyjęcie dla nich ostatecznej wartości zero. Jeżeli width i jednocześnie height są ustawione jako auto, wewnętrzna szerokość staje się ostateczną wartością szerokości elementu. Ponadto w CSS 2.1 jeśli width ma wartość auto, a height ma inną wartość, ostateczna wartość szerokości jest obliczana ze wzoru:

(szerokość wewnętrzna) * ( (ustawiona wysokość) / (wewnętrzna wysokość) )

co oznacza po prostu przeskalowanie elementu tak, aby zachował on swoje proporcje.

3. Elementy blokowe, nie-zastępowane

Przykład: DIV i inne.

Elementy takie muszą spełniać następujące równanie:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = szerokość bloku obejmującego

Jeżeli 'width' nie ma przypisanej wartości auto, a suma 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' (plus 'margin-left' lub 'margin-right' nieposiadające wartości auto) jest większa od szerokości bloku obejmującego, to każda wartość auto przypisana do 'margin-left' lub 'margin-right' jest traktowana jako zero (CSS 2.1).

Jeżeli wszystkie z powyższych własności mają przypisaną wartość auto, a kierunek tekstu (direction) jest ustawiony jako "ltr" (od lewej do prawej), to prawy margines zostanie dopasowany. W efekcie powinniśmy otrzymać blok, którego szerokość całego pudełka będzie się pokrywać z szerokością bloku obejmującego. W przypadku kierunku tekstu "rtl" (od prawej do lewej) to lewy margines zostanie dopasowany.

Jeżeli dokładnie jedna wartość jest przypisana jako auto, zostaje ona dopasowana tak, aby przedstawione równanie zostało spełnione, tzn. jego szerokość będzie dopełnieniem do brakującej szerokości bloku obejmującego, wynikającej z mniejszej wartości sumy pozostałych składników równania.

Przykład:

Po wpisaniu:
<div style="width: 600px">
	<div style="margin-left: auto; border-left: 5px solid red; padding-left: 10px; width: 400px; padding-right: 10px; border-right: 5px solid red; margin-right: 20px">...</div>
</div>
powinniśmy otrzymać na ekranie blok, którego lewy margines wynosi:
600 - 5 - 10 - 400 - 10 - 5 - 20 = 150 pikseli

UWAGA! W trybie Quirks interpretacja będzie zupełnie inna.


Jeżeli 'width' jest ustawione na auto, wszystkie inne wartości auto przyjmują ostateczną wartość zero, a szerokość zostaje dopasowana do pełnej szerokości bloku obejmującego.

Przykład:

<div style="width: 600px">
	<div style="margin-left: 20px; width: auto; margin-right: auto">...</div>
</div>
W tym przykładzie prawy margines uzyska wartość zero, natomiast ostateczna szerokość bloku wyniesie:
600 - 20 = 580 pikseli

Jeśli zarówno 'margin-left' jaki i 'margin-right' posiadają wartość auto, oznacza to, że ich ostateczna szerokość będzie taka sama. Pozwala to wyśrodkować w poziomie element względem krawędzi bloku obejmującego.

Przykład:

Następujący kod:
<div style="width: 600px">
	<div style="margin-left: auto; width: 400px; margin-right: auto">...</div>
</div>
Pozwala wycentrować wewnętrzny blok o szerokości 400px. Marginesy - lewy i prawy - uzyskają taką samą wartość ostateczną:
(600 - 400) / 2 = 100 pikseli

UWAGA! W trybie Quirks interpretacja będzie zupełnie inna.

Dla uzyskania analogicznego efektu również w trybie Quirks należy wpisać:
<div style="width: 600px; text-align: center">
	<div style="text-align: left; margin-left: auto; width: 400px; margin-right: auto">...</div>
</div>

Sposób ten jest przydatny np. do centrowania tabeli (względem elementu BODY stanowiącego blok obejmujący) zgodnie z zaleceniami CSS.

<html>
<head>...</head>
<body style="text-align: center">
	<table style="margin-left: auto; margin-right: auto; text-align: left">...</table>
</body>
</html>

4. Elementy blokowe, zastępowane

Przykład: IMG, INPUT, TEXTAREA, SELECT, OBJECT - z ustawionym stylem display: block.

Ostateczna wartość szerokości jest wyznaczana tak jak dla elementów "inline" zastępowanych (punkt 2). Następnie dla wyznaczenia marginesów zastosowane zostają reguły jak dla elementów "blokowych" nie-zastępowanych (punkt 3).

5. Elementy z oblewaniem (float) nie-zastępowane

Przykład: DIV, SPAN i inne (ale nie IMG, INPUT, TEXTAREA, SELECT, OBJECT, które są elementami zastępowanymi) - z ustawionym stylem float różnym od none.

Jeżeli margin-left lub margin-right jest ustawiony na auto, przyjmuje ostateczną szerokość zero. Ponadto w CSS 2.1 ustawienie auto dla width spowoduje określenie szerokości w sposób podobny jak to się dzieje dla komórek tabeli (CSS 2 określa w tym przypadku wartość zero):

min(max(preferowana najmniejsza szerokość, dostępna szerokość), preferowana szerokość)

Preferowana najmniejsza szerokość jest obliczana poprzez próbę przełamania wierszy w każdym możliwym miejscu, czyli po każdym wyrazie. Dostępna szerokość to poziomy rozmiar bloku obejmującego pomniejszony o marginesy, obramowanie, marginesy wewnętrzne i ewentualne paski przewijania elementu. Preferowana szerokość jest obliczana bez przełamywania wierszy, chyba że w kodzie znajduje się element <br>.

Z powyższego równania wynika w szczególności, że dwa bloki z oblewaniem, bez ustalonej szerokości lub z ustaloną wartością width: auto, mogą się ustawić obok siebie, o ile tekst i inne elementy w nich zawarte będą na tyle krótkie, że zmieszczą się w jednej linii bez potrzeby przełamywania wierszy.

Właściwość ta jest często wykorzystywana przy tworzeniu struktury strony w oparciu o CSS, np. do ustawienia obok siebie linków zgromadzonych w wykazie, aby utworzyć efekt zakładek nawigacyjnych itp.

Pamiętaj, że w przypadku ustawienia dwóch bloków obok siebie, nie zostanie dodana między nimi dodatkowa spacja w tekście. Aby oddalić od siebie takie bloki, można ustawić odpowiedni margines.

Przykład:

Poniższe bloki najprawdopodobniej ustawią się obok siebie, a nie jeden pod drugim (zależnie od rozmiaru czcionki i szerokości bloku obejmującego):
<div style="float: left">Blok 1</div>
<div style="float: left">Blok 2</div>
<div style="float: left">Blok 3</div>
Identyczny efekt:
<div style="float: left; width: auto">Blok 1</div>
<div style="float: left; width: auto">Blok 2</div>
<div style="float: left; width: auto">Blok 3</div>
Poniższe bloki ustawią jeden pod drugim:
<div style="float: left; width: 100%">Blok 1</div>
<div style="float: left; width: 100%">Blok 2</div>
<div style="float: left; width: 100%">Blok 3</div>
Poniższe bloki najprawdopodobniej ustawią się obok siebie, a nie jeden pod drugim:
<div style="float: left; width: 25%">Blok 1</div>
<div style="float: left; width: 50%">Blok 2</div>
<div style="float: left; width: 25%">Blok 3</div>

Oczywiście wartości szerokości bloków można podawać również w innych jednostkach długości, np. w pikselach.

Ostatni przykład, obok pozycjonowania, jest zwykle wykorzystywany do budowy szkieletu strony w oparciu o CSS, a nie tak jak robiło się kiedyś - w oparciu o odpowiednio sformatowane tabele.

Tworzenie szkieletu strony w oparciu o tabele zostało obmyślone w czasach, kiedy nie było jeszcze CSS lub był słabo wspierany przez przeglądarki. Wtedy był to jedyny sposób budowy bardziej wyszukanego układu treści. Obecnie interpretacja CSS w popularnych przeglądarkach jest już wystarczająca, aby ostatecznie porzucić stare nawyki projektowania struktury. Tabele służą do prezentacji danych tabelarycznych, a nie do tworzenia struktury strony.

Jeżeli w dowolnym bloku, przedstawionym w ostatnim przykładzie, znajdzie się element szerszy niż ustalony rozmiar poziomy, bloki mogą się ustawić jeden pod drugim, co zupełnie zepsuje cały układ strony.

Może się to zdarzyć, kiedy tekst nie będzie się mógł przełamać do następnej linijki z powodu wystąpienia niezwykle długiego wyrazu albo ustawienia blokady przełamania wierszy bądź kiedy wstawiony zostanie element z określoną dużą szerokością, jak np. obrazek. Aby do tego nie dopuścić, można dla wszystkich bloków ustawić dodatkowy styl overflow: hidden, co spowoduje przycięcie prawej części treści, która nie mieści się w wyznaczonej szerokości. Co prawda wtedy nie będzie można odczytać uciętej treści, ale układ strony nie zmieni się w sposób niekontrolowany.

6. Elementy z oblewaniem (float) zastępowane

Przykład: IMG, INPUT, TEXTAREA, SELECT, OBJECT - z ustawionym stylem float różnym od none.

Jeżeli margin-left lub margin-right jest ustawiony na auto, przyjmuje ostateczną szerokość zero. Ostateczna wartość dla width jest ustalana jak dla elementów "inline" zastępowanych (punkt 2).

7. Elementy pozycjonowane absolutnie, nie-zastępowane

Przykład: DIV, SPAN i inne (ale nie IMG, INPUT, TEXTAREA, SELECT, OBJECT, które są elementami zastępowanymi) - z ustawionym stylem position: absolute.

Elementy takie muszą spełniać następujące równanie:

'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = szerokość bloku obejmującego

Rozwiązanie tego równania uzyskuje się poprzez wykonanie podstawień w następującym porządku (CSS 2):

  1. Jeżeli 'left' jest ustawione na auto, a kierunek tekstu (direction) jest "ltr" (od lewej do prawej), zastąp wartość auto odległością od lewej krawędzi bloku obejmującego do lewej krawędzi marginesu (zewnętrznego) hipotetycznego pudełka, które wystąpiłoby, gdyby element był pozycjonowany statycznie (położenie spoczynkowe). Ustalona w ten sposób wartość będzie ujemna, jeśli hipotetyczne pudełko wychodzi poza lewą krawędź bloku obejmującego.
  2. Jeżeli 'right' jest ustawione na auto, a kierunek tekstu (direction) jest "rtl" (od prawej do lewej), zastąp wartość auto odległością od prawej krawędzi bloku obejmującego do prawej krawędzi marginesu (zewnętrznego) hipotetycznego pudełka (jak wyżej). Ustalona w ten sposób wartość będzie dodatnia, jeśli hipotetyczne pudełko wychodzi poza lewą krawędź bloku obejmującego.
  3. Jeżeli 'width' jest ustawione na auto, zastąp pozostałe wartości auto dla 'left' lub 'right' wartością zero.
  4. Jeżeli 'left', 'right' lub 'width' nadal posiada wartość auto, zastąp zerem wartości auto przypisane do 'margin-left' lub 'margin-right'.
  5. Jeżeli w tym punkcie obie własności: 'margin-left' i 'margin-right' mają nadal wartość auto, rozwiąż powyższe równanie dodając nowy warunek taki, że oba marginesy muszą uzyskać jednakową szerokość.
  6. Jeżeli w tym punkcie pozostała tylko jedna wartość auto, rozwiąż powyższe równanie dla tej wartości.
  7. Jeżeli w tym punkcie nadal nie można rozwiązać równania, zignoruj 'left' (jeśli kierunek tekstu jest "rtl") lub 'right' (jeśli kierunek tekstu jest "ltr") i rozwiąż równanie dla tej wartości.

8. Elementy pozycjonowane absolutnie, zastępowane

Przykład: IMG, INPUT, TEXTAREA, SELECT, OBJECT - z ustawionym stylem position: absolute.

Sytuacja jest podobna jak w poprzednim punkcie za wyjątkiem tego, że element posiada wewnętrzną szerokość. Sekwencja podstawiania do równania jest teraz następująca:

  1. Jeżeli 'width' jest ustawione na auto, podstaw wewnętrzną szerokość elementu.
  2. Jeżeli 'left' jest ustawione na auto, a kierunek tekstu (direction) jest "rtl" (od prawej do lewej), zastąp wartość auto odległością od prawej krawędzi bloku obejmującego do prawej krawędzi marginesu (zewnętrznego) hipotetycznego pudełka (jak wyżej). Ustalona w ten sposób wartość będzie dodatnia, jeśli hipotetyczne pudełko wychodzi poza lewą krawędź bloku obejmującego.
  3. Jeżeli 'right' jest ustawione na auto, zastąp pozostałe wartości auto dla 'left' lub 'right' wartością zero.
  4. Jeżeli 'left' lub 'right'auto zastąp zerem wartości auto przypisane do 'margin-left' lub 'margin-right'.
  5. Jeżeli w tym punkcie obie własności: 'margin-left' i 'margin-right' mają nadal wartość auto, rozwiąż powyższe równanie dodając nowy warunek taki, że oba marginesy muszą uzyskać jednakową szerokość.
  6. Jeżeli w tym punkcie pozostała tylko jedna wartość auto, rozwiąż powyższe równanie dla tej wartości.
  7. Jeżeli w tym punkcie nadal nie można rozwiązać równania, zignoruj 'left' (jeśli kierunek tekstu jest "rtl") lub 'right' (jeśli kierunek tekstu jest "ltr") i rozwiąż równanie dla tej wartości.

9. Elementy inline-block, nie-zastępowane

Przykład: Elementy z ustawionym stylem display: inline-block, ale nie IMG, INPUT, TEXTAREA, SELECT, OBJECT, które są elementami zastępowanymi.

Jeżeli width jest ustawione jako auto, spowoduje to określenie szerokości w sposób podobny jak to się dzieje dla komórek tabeli.

Dla margin-left lub margin-right ustawionych na auto zostają przyjęte ostateczne wartości równe zero.

10. Elementy inline-block, zastępowane

Przykład: IMG, INPUT, TEXTAREA, SELECT, OBJECT - z ustawionym stylem display: inline-block.

Tak samo jak dla elementów "inline" zastępowanych (punkt 2).

Komentarze

Zobacz więcej komentarzy

Facebook