Хоризонтално и вертикално центриране на елемент с CSS

В този урок ще ви покажа как да центрирате един HTML елемент не само по хоризонтала, но и по вертикала. Ако тръгнете да се ровите из нета ще намерите много решения, които имат редица плюсове и минуси, но тук ще стане въпрос за най-лесния и бърз начин да го сторите.

На повечето от вас е ясно, че за да центрираме един елемент по хоризонтала (било то div, span, a, ul и пр.) е необходимо да му задаем ширина и margin: 0 auto. В някои по-специални ситуации, наложени от по-специални браузъри, трябва да добавим text-align: center и така нещата се получават, но в 99% от случаите ви е необходимо само margin: 0 auto. По-интересното е как да центрирате елемента по вертикалата, така че да стои винаги в средата на браузъра (или родителския елемент, ако пожелаете). Основният проблем идва от различните резолюции, на които се гледа сайтът. Точно за това ни трябва нещо универсално, което не е свързано с условности и изчисляване на безкрайни комбинации.

За примера днес ще направим нещо съвсем простичко, за да ви стане напълно ясно за какво говоря. Ще използваме един div, който ще центрираме спрямо екрана. Няма да пишем никакъв javascript. Изображения също не съм ползвал, тъй като, както казах се стремя да е максимално опростено.

Стъпка 1: HTML

Тук ни трябва само един div, който съм кръстил “centered”. Всичко останало е стандартно и е написано, за да го копирате и да имате валиден документ.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<title>Хоризонтално и вертикално центриране на елемент с CSS</title>
</head>
<body>	
	<div id="centered"></div>
</body>
</html>

Стъпка 2: CSS

Вече имаме създаден div и нашата задача е да го центрираме, като за целта ще ползваме абсолютното позициониране. За хората, които не са наясно какво е това ще поясня с две думи. В CSS има няколко типа позициониране – relative, absolute, fixed и static. За основите им може да прочетете тук. В нашия случай ни интерсува поведението на relative и absolute. По принцип когато един елемент е абсолютно позициониран, то той излиза от нормалния “поток” на HTML-a, ако мога да така да се изразя и обикновено застава над всички в горния ляв ъгъл на екрана. Сега вие може да го местите където си пожелаете, благодарение на свойствата top, left, bottom и right. Това е страхотно, нали? Да, но на различните резолюции, елементът не винаги е там, където трябва да бъде. Тук в помощ идва релативната позиция. Когато един div е позициониран релативно и в него има друг div, но вече абсолютно позициониран, то абсолютният се води по поставените граници от релативния. Така например ако имате Facebook икона в лявата колона, но искате я да позиционирате малко извън нея, трябва да зададете position: relative на лявата колона, за да може иконата да се води по нея, а не според екрана. В нашия случай обаче ни е нужно точно обратното – трябва да позиционираме спрямо екрана, ето защо не пишем допълнителни релативни div-ове. Напишете следния код.

body { margin: 0; padding: 0; background: #FFF; }

#centered {
	width: 300px;
	height: 300px;
	position: absolute;
	top: 50%;
	left: 50%;
	margin-top: -150px;
	margin-left: -150px;
	background: #888;
	border: 1px solid #444;
}

За body, настройките са стандартни, така че не им обръщаме внимание и се концентрираме на “centered”. Виждате, че съм задал ширина и височина на div-a, както и бекграунд и бордър, само за да видим къде е. След това добавям position: absolute, за да го позиционирам спрямо екрана и казвам да бъде на 50% (половината) отгоре и отляво. Така обаче позиционирам външните краища на div-a, а не самия център. Даже си поиграх малко да ви го илюстрирам по-добре. Приемете, че бялото пространство е браузъра.

Vertically & Horizontally Centering a DIV, Fig. 1

Както виждате от фигурата това съвсем не е център. За целта трябва посредством отрицателни стойности на марджина да “избутаме” или по-точно върнем div-a нагоре и наляво. За да намерим центъра му трябва да разделим страните му на две, т.е. 300px/2 = 150px. В случая имам квадрат, така че и двата марджина са с една и съща стойност, но важното е да запомните, че страните се делят на две… то си е и логично всъщност. Сега добавете отрицателните марджини към кода, за да получим желания резултат.

#centered {
	width: 300px;
	height: 300px;
	position: absolute;
	top: 50%;
	left: 50%;
	margin-top: -150px;
	margin-left: -150px;
	background: #888;
	border: 1px solid #444;
}

Имаме си напълно центриран div. Изтествайте, като минимизирате браузъра и го поразтеглите насам-натам.

Vertically & Horizontally Centering a DIV, Fig. 1

Това е цялата философия. На този принцип може да си направите Login скрийн или пък да вадите важни съобщения… общо взето приложенията са много и ще го усетите с времето.

Урочето стана малко по-дълго от очакваното, защото се засилих да обяснявам по-подробно нещата и поне се надявам да сте разбрали всичко. Ако има въпроси питайте, ще се радвам да помогна.

Коментари (11)

  1. Отговор March 1, 2010 / 11:24 Pavel Ivanov

    супер много яко обяснено … евала!

  2. Отговор November 25, 2011 / 00:12 Пламен

    Прочетох урока и много други, само че не е точно това, което търся.Ако влезеш в сайтът ми http://laminat-sofia.com/ ще видиш две менюта, произхождащи от един css код, разположени над и под картинката.Менютата и картинката се намират в една клетка от таблица и докато картинката се влияе от html командата align="center", то менютата не.И понеже хоризонталното css меню е винаги подравнено наляво заради float: left, така се получава грозно разминаване между менюта и картинка, идеята е да ги подравня наравно в центъра едно под друго.
    ПП – В css менюто имам включени margin:0 auto; и text-align:center, но ефект няма.Самият код е:

    .menu {
    margin:0 auto;
    text-align:center;
    width:96.5px;
    height:20px;
    padding:2px 20px; /*задаваме вътрешните отстъпи*/
    letter-spacing:0.5px; /*разстояние между буквите*/
    border:1px solid #000000; /*задаваме рамка на бутона*/
    display:block;
    float: left;
    overflow:hidden;
    text-decoration:none; font-family:font-family:verdana;
    font-weight:bold; /*форматиране на текста,в случая текста ще бъде удебелен*/
    color:#000000; /*цвят на текста в нормално състояние*/
    background:url(button2.jpg); /*задаваме фон на бутона в нормано състояние*/
    }

    .menu:hover {
    color:CC0000; /*цвят на текста когато сме посочили бутона*/
    background:url(button3.jpg);
    }

  3. Отговор November 25, 2011 / 11:01 Joro

    Ами то твоето няма много общо с урока :).
    Иначе на .menu му разкарай float: left; и display го направи display: inline-block;

  4. Отговор November 25, 2011 / 16:01 Пламен

    Центрира се менюто, което беше най-важното и за което много ти благодаря, но има ли начин разстоянието между клетките да изчезне?

  5. Отговор November 25, 2011 / 16:24 Joro

    Между другото от .menu махни и overflow: hidden;
    За да нямаш разстояние между бутоните има няколко варианта.

    Вариант 1:
    Трябва да нямаш празни пространства между <a> елементите в html-a. Т.е. те НЕ трябва да бъдат така:
    <a href="ceni.html" target="_blank" class="menu">Цени</a>
    <a href="otstupki.html" target="_blank" class="menu">Отстъпки</a>
    Трябва да бъдат директно едно след друго:
    <a href="ceni.html" target="_blank" class="menu">Цени</a><a href="otstupki.html" target="_blank" class="menu">Отстъпки</a>

    Вариант 2:
    На <td>-то, което държи въпросните менюта му задаваш font-size: 0; след което на .menu добавяш font-size: 14px;

    Има още доста решения, но те изискват по-генерална промяна на кода. Може да има и нещо още по-елементарно, но в момента се сещам за тези.
    Успех! 🙂

  6. Отговор November 26, 2011 / 02:23 Пламен

    Човек, ти си факир!Да не говорим, колко бързо ми отговори.Много съм ти благодарен!

  7. Отговор December 13, 2011 / 19:04 Емо

    Много ми беше полезно това разяснение,тъй като съм начинаещ уебаджия.Но скоро гледах едни уроци за CSS в които съветват да не присъстват заедно в един див примерно "margin/padding и width/height".Трябвало да присъстват или само едните или само другите.Сега съм малко объркан,понеже в този пример се дават заедно,че и "top/bottom" присъства.В крайна сметка кое е ПРАВИЛНОТО КОДИРАНЕ?

  8. Отговор December 13, 2011 / 19:14 Joro

    Няма такова нещо. Всяко пропърти (margin, padding, width, height, color, position и т.н.) може да бъде слагано на всеки елемент… въпросът е кога е нужно и кога не :). Рядко някой може да ти каже какво да ползваш и какво не. Може примерно width да не е нужно при неговото решение, но при нечие друго да е. Така че всичко е според зависи 🙂

  9. Отговор December 13, 2011 / 20:38 Емо

    Мерси за бързият отговор.В момента правя едно сайтче,но има един странен(поне за мен) проблем.Единият от дивовете със снимка в него се показва с около 10 рх по нагоре в ИЕ и опера,докато в мозила и хром е както трябва.Странното е,че сайта е валиден ,без грешки и предупреждения…Дали не е повлияло начинът ми на позициониране ,защото използвам големи отрицателни стойности на margin -600рх и повече…Ако не е уместно да питам тук се извинявам и изтрий въпросът ми.

  10. Отговор December 13, 2011 / 22:05 Joro

    Честа грешка на начинаещите е да мислят, че щом нещо е валидно, то е правилно :). Валидноста просто потвърждава, че в кодът няма грешки, но не проверява логиката.
    Иначе щом ползваш отрицателни стойности и то в такива гигантски стойности, определено нещо не е наред. По-добре почети пак за позиционирането и изобщо как се игражда лейаут и започни отначало. Стартът е труден, но не бива да се отказваш, защото после е още по-забавно :).
    Ето линк към другия проект, който поддържам (макар да е в застой в момента) – http://fridaycode.net/

  11. Отговор June 23, 2013 / 15:59 Боби

    Много добре обяснено, даже и забелязах нещо ново за мен. Аз не знам много за css, но досега ми се струваше, че когато body background цвета е бял, няма нужда да се дефинира защото май си е такъв по подразбиране. Явно не съм била права.

Contact
captcha