Центриране на div

от Fuedo - Уеб дизайн енциклопедия

Направо към: навигация, търсене

Много често се налага да се центрира даден div било то хоризонтално, било то вертикално. Хоризонталното центриране е доста просто докато това изобщо не важи за вертикалното. Тук ще ви покажа как да центрирате и по двата начина.

Хоризонтално центриран div

Хоризонталното центриране на div може да бъде доста досаден проблем за начинаещите, а и не само за начинаещите програмисти. Всъщност то е доста просто като го разберете.
Да предположим, че имате следния код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>3 columns, liquid width, content</title>
    <style type="text/css">
      body{
        background:#fff;
      }
      #container{
        width:700px;
        height:200px;
        background:red;
        border:1px solid #000;
      }
    </style>
  </head>
  <body>
    <div id="container">
      container
    </div>
  </body>
</html>

Искате да позиционирате div-а в центъра? Това всъщност е доста просто. Добавяте margin:0 auto; към #container и така примера става:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>3 columns, liquid width, content</title>
    <style type="text/css">
      body{
        background:#fff;
      }
      #container{
        width:700px;
        height:200px;
        background:red;
        border:1px solid #000;
        margin:0 auto;
      }
    </style>
  </head>
  <body>
    <div id="container">
      container
    </div>
  </body>
</html>

И дивът е центриран (:-). За съжаление нещата не са толкова чак толкова прости, колкото изглеждат. IE 5.х за Windows няма да го центрира. Свойството text-align се прилага по принцип на блокови елементи като параграф, div или таблица. Това кара всичкото инлайн съдържание на блоковият елемент да бъде подравнено в съответствие с посочената стойност на text-align. Въпреки това IE за Windows неправилно прилага това на всички елементи(блокови и инлайн). За това трябва да използваме този бъг който тези браузъри имат: т.е. добавяме към body text-align: center;. Тъй като text-align се наследява то текстът във всички деца на body(инлайн и блок левел елементи) ще бъде центриран. За това трябва да предефинираме text-align: center; като добавим text-align: left; в #container. Taka text-align: center; ще се приложи само на #container. Ето и докъде стигнахме:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>3 columns, liquid width, content</title>
    <style type="text/css">
      body{
        background:#fff;
        text-align: center;
      }
      #container{
        width:700px;
        height:200px;
        background:red;
        border:1px solid #000;
        margin:0 auto;
        text-align: left;
      }
    </style>
  </head>
  <body>
    <div id="container">
      container
    </div>
  </body>
</html>

Остана да споменем само едно последно нещо. Геко базираните браузъри(такива са Mozilla, Firefox, Netscape) при margin:0 auto; центрират дива, но го приемат толкова сериозно, че когато размерът на браузъра се намали повече от размерът на #container те продължават да центрират div-а. Това кара съдържанието да 'бяга' еднакво в двете посоки, но докато надясно може да се скролне и да се види, наляво не може да се види. За да решим този проблем, трябва да добавим min-width:700px;(ширина с размера на #container) към body. Друг способ за избягване на това поведение е добавянето на рамка (Пр. border:1px solid #000;) на #container. И така имаме финалният пример:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>3 columns, liquid width, content</title>
    <style type="text/css">
      body{
        background:#fff;
        text-align: center;
        min-width:700px;
      }
      #container{
        width:700px;
        height:200px;
        background:red;
        border:1px solid #000;
        margin:0 auto;
        text-align: left;
      }
    </style>
  </head>
  <body>
    <div id="container">
      container
    </div>
  </body>
</html>

Вертикално центриран div

Доскоро нямаше удобен начин за вертикално центриране, на кутии с нефиксирана височина. Когато се работи с таблици е наистина лесно да използваш valign="middle", но за съжаление такова животно в CSS няма. Наскоро Dušan Janovský написа статията Vertical Centering in CSS (Вертикално центриране с CSS) която сякаш реши проблема доста добре. Тук ще представя този метод за центриране, както и някои други които в някои случаи може да са по удобни, тъй като решението на Dušan Janovský не е семантично.

Дефиниране на проблема.

  1. Имаме област (например div) с позната височина
  2. Имаме вмъкнат в областта обект (обикновено дълъг текст вкаран в div) на които не знаем височината(неговото съдържание например се генерира от база данни)
  3. Искам да центрирам вертикално обектът
  4. без да използваме таблици

Идеята
Основното при това решение в IE: вътрешният обект е позициониран посредата на обвиващата област. След това се отмества нагоре с половината от височината си. Използва се грешната интерпретация на височината в IE (). Един допълнителен вмъкнат div е необходим за IE.

Решението за добре поддържащите стандартите браузъри(Mozilla, Opera, Safari и т.н.) е съвсем различно. Цялата област е представена като таблица(display:table; част от CSS). Вътрешният обект е представен като клетка от таблица (display: table-cell). Тук идва хитростта - възможно е да се използва vertical-align за table-cell елементи (IE игнорира тези свойства или не знае техните стойности).

Комбинираме двете решения за двата браузъра. Използваме хакът на Pixy с долната черта но със знакът #. Свойство започващо с долна черта се вижда от всички версии на IE освен IE7, свойство започващо с # се вижда и от IE7. Така написаното свойство остава скрито за другите браузъри.

Съвместимост
По долният код работи в IE5.0, 5.5 и 6.0, в Геко базираните браузъри(Mozilla, Firefox, Netscape 7), в Opera 7, Konqueror 3.3.1. (може би по-ниска версия също), и в Safari. Страницата може да се валидира като стандартен HTML/XHTML.

Разбираем код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Universal vertical center with CSS</title>
  <style>
    .greenBorder {border: 1px solid green;} /* Рамка за да се види резултата */
  </style>
</head>

<body>
  <div class="greenBorder" style="display: table; height: 400px; #position: relative; overflow: hidden;">
    <div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
      <div class="greenBorder" style=" #position: relative; #top: -50%">
        Някакъв текст<br>
        каквато и да е височина<br>
        каквото и да е съдържание, генерирано от база данни<br>
        всичко ще бъде вертикално центрирано.
      </div>
    </div>
  </div>
</body>
</html>

Да го направим структурирано и без хакове
Бележка: понастоящем долупосоченото решение не работи в IE7(standard mode), защото IE7 не разбира table стойностите в display свойството. За да работи трябва да използвате невалидиращото се решение отгоре, докато не се намери валиден хак и за IE7(или пишете в quirks mode). Примерът отгоре не е много приятен на външен вид но пък се надявам да е бил разбираем. Възможно е да го представим по различен начин, например:

<div id="outer">
    <div id="middle">
      <div id="inner">
        Някакъв текст<br>
        каквато и да е височина<br>
        каквото и да е съдържание, генерирано от база данни<br>
        всичко ще бъде вертикално центрирано.
      </div>
    </div>
  </div>

И валидният стил:

<style type="text/css">
#outer {height: 400px; overflow: hidden; position: relative;}
#outer[id] {display: table; position: static;}

#middle {position: absolute; top: 50%;} /* Само за IE */
#middle[id] {display: table-cell; vertical-align: middle; position: static;}

#inner {position: relative; top: -50%} /* Само за IE */
/* Незадължително: #inner[id] {position: static;} */
</style>

CSS2 селекторът #value[id] е еквивалентен на селекторът #value, но IE игнорира този тип селектори. В най-общи линии, синтаксисът *[foo] означава всеки елемент с атрибут foo. Всеки HTML елемент #something трябва да има id със стойност something. Това е основната идея -- #value[id] работи само в браузъри добре поддържащи стандартите(по подоен начин работи и .value[class]).

Лични инструменти