В CSS есть всего несколько техник центрирования элементов. Если их знать, то большинство задач решаются просто.
Горизонтальное
text-align
Для центрирования инлайновых элементов – достаточно поставить родителю text-align: center :
Для центрирования блока это уже не подойдёт, свойство просто не подействует. Например:
margin: auto
Блок по горизонтали центрируется margin: auto :
В отличие от width/height , значение auto для margin само не появляется. Обычно margin равно конкретной величине для элемента, например 0 для DIV . Нужно поставить его явно.
Значение margin-left:auto/margin-right:auto заставляет браузер выделять под margin всё доступное сбоку пространство. А если и то и другое auto , то слева и справа будет одинаковый отступ, таким образом элемент окажется в середине. Детали вычислений описаны в разделе спецификации Calculating widths and margins.
Вертикальное
Для горизонтального центрирования всё просто. Вертикальное же изначально не было предусмотрено в спецификации CSS и по сей день вызывает ряд проблем.
Есть три основных решения.
position:absolute + margin
Центрируемый элемент позиционируем абсолютно и опускаем до середины по вертикали при помощи top:50% :
Это, конечно, не совсем центр. По центру находится верхняя граница. Нужно ещё приподнять элемент на половину своей высоты.
Высота центрируемого элемента должна быть известна. Родитель может иметь любую высоту.
Если мы знаем, что это ровно одна строка, то её высота равна line-height .
Приподнимем элемент на пол-высоты при помощи margin-top :
При стандартных настройках браузера высота строки line-height: 1.25 , если поделить на два 1.25em / 2 = 0.625em .
Конечно, высота может быть и другой, главное чтобы мы её знали заранее.
Можно аналогично центрировать и по горизонтали, если известен горизонтальный размер, при помощи left:50% и отрицательного margin-left .
Одна строка: line-height
Вертикально отцентрировать одну строку в элементе с известной высотой height можно, указав эту высоту в свойстве line-height :
Это работает, но лишь до тех пор, пока строка одна, а если содержимое вдруг переносится на другую строку, то начинает выглядеть довольно уродливо.
Таблица с vertical-align
У свойства vertical-align, которое управляет вертикальным расположением элемента, есть два режима работы.
В таблицах свойство vertical-align указывает расположение содержимого ячейки.
Его возможные значения:
baseline Значение по умолчанию. middle , top , bottom Располагать содержимое посередине, вверху, внизу ячейки.
Например, ниже есть таблица со всеми 3-мя значениями:
Обратим внимание, что в ячейке с vertical-align: middle содержимое находится по центру. Таким образом, можно обернуть нужный элемент в таблицу размера width:100%;height:100% с одной ячейкой, у которой указать vertical-align:middle , и он будет отцентрирован.
Но мы рассмотрим более красивый способ, который поддерживается во всех современных браузерах, и в IE8+. В них не обязательно делать таблицу, так как доступно значение display:table-cell . Для элемента с таким display используются те же алгоритмы вычисления ширины и центрирования, что и в TD . И, в том числе, работает vertical-align :
Этот способ замечателен тем, что он не требует знания высоты элементов.
Однако у него есть особенность. Вместе с vertical-align родительский блок получает табличный алгоритм вычисления ширины и начинает подстраиваться под содержимое. Это не всегда желательно.
Чтобы его растянуть, нужно указать width явно, например: 300px :
Можно и в процентах, но в примере выше они не сработают, потому что структура таблицы «сломана» – ячейка есть, а собственно таблицы-то нет.
Это можно починить, завернув «псевдоячейку» в элемент с display:table , которому и поставим ширину:
Если дополнительно нужно горизонтальное центрирование – оно обеспечивается другими средствами, например margin: 0 auto для блочных элементов или text-align:center на родителе – для других.
Центрирование в строке с vertical-align
Для инлайновых элементов ( display:inline/inline-block ), включая картинки, свойство vertical-align центрирует сам инлайн-элемент в окружающем его тексте.
В этом случае набор значений несколько другой:
Это можно использовать и для центрирования, если высота родителя известна, а центрируемого элемента – нет.
Допустим, высота внешнего элемента 120px . Укажем её в свойстве line-height :
Работает во всех браузерах и IE8+.
Свойство line-height наследуется, поэтому надо знать «правильную» высоту строки и переопределять её для inner .
Центрирование с vertical-align без таблиц
Если центрирование должно работать для любой высоты родителя и центрируемого элемента, то обычно используют таблицы или display:table-cell с vertical-align .
Если центрируются не-блочные элементы, например inline или inline-block , то vertical-align может решить задачу без всяких таблиц. Правда, понадобится вспомогательный элемент (можно через :before ).
- Перед центрируемым элементом помещается вспомогательный инлайн-блок before , занимающий всю возможную высоту.
- Центрируемый блок выровнен по его середине.
Для всех современных браузеров и IE8 можно добавить вспомогательный элемент через :before :
В пример выше добавлено также горизонтальное центрирование text-align: center . Но вы можете видеть, что на самом деле внутренний элемент не центрирован горизонтально, он немного сдвинут вправо.
Это происходит потому, что центрируется весь текст, а перед inner находится пробел, который занимает место.
- Убрать лишний пробел между div и началом inner , будет
Центрирование с использованием модели flexbox
Данный метод поддерживается всеми современными браузерами.
- Не требуется знания высоты центрируемого элемента.
- CSS чистый, короткий и не требует дополнительных элементов.
- Не поддерживается IE9-, IE10 поддерживает предыдущую версию flexbox.
Итого
Обобщим решения, которые обсуждались в этой статье.
Для горизонтального центрирования:
- text-align: center – центрирует инлайн-элементы в блоке.
- margin: 0 auto – центрирует блок внутри родителя. У блока должна быть указана ширина.
Для вертикального центрирования одного блока внутри другого:
Если размер центрируемого элемента известен, а родителя – нет
Родителю position:relative , потомку position:absolute; top:50% и margin-top:- . Аналогично можно отцентрировать и по горизонтали.
Если нужно отцентрировать одну строку в блоке, высота которого известна
Поставить блоку line-height: . Нужны конкретные единицы высоты ( px , em …). Значение line-height:100% не будет работать, т.к. проценты берутся не от высоты блока, а от текущей line-height .
Высота родителя известна, а центрируемого элемента – нет.
Поставить line-height родителю во всю его высоту, а потомку поставить display:inline-block .
Высота обоих элементов неизвестна.
- Сделать элемент-родитель ячейкой таблицы при помощи display:table-cell (IE8) или реальной таблицы, и поставить ему vertical-align:middle . Отлично работает, но мы имеем дело с таблицей вместо обычного блока.
- Решение со вспомогательным элементом outer:before и инлайн-блоками. Вполне универсально и не создаёт таблицу.
- Решение с использованием flexbox.
Существует несколько принципиально отличающихся способов для того чтобы отцентрировать объект по вертикали с помощью CSS, однако сложность может быть в выборе правильного. Мы рассмотрим некоторые из них, а также сделаем небольшой сайт, используя полученные знания.
Вертикальное выравнивание по центру с помощью CSS достигается не так просто. Существует множество способов и не все работают во всех броузерах. Давайте рассмотрим 5 различных методов, а также "за" и "против" каждого из них. Пример.
1-ый способ
Этот метод предполагает, что мы устанавливаем некоторому элементу
Плюсы
- Контент может динамически изменять высоту (высота не определена в CSS).
- Контент не обрезается в случае, если для него недостаточно места.
Минусы
- Не работает в IE 7 и меньше
- Много вложенных тэгов
2-ой метод
Этот метод использует абсолютное позиционирование div-а, которому top устанавливается в 50%, а верхний отступ (margin-top) минус половине высоты контента. Это подразумевает, что объект должен иметь фиксированную высоту, которая определена в стилях CSS.
Поскольку высота фиксированная, вы можете установить overflow:auto; для div-а содержащего контент, таким образом, в случае если контент не будет влазить, то появятся скролл-бары.
Плюсы
- Работает во всех броузерах.
- Нет лишней вложенности.
Минусы
- Когда не достаточно места, контент пропадает (например, div находится внутри body, а пользователь уменьшил окна, в этом случае скролл-бары не появятся.
3-ий метод
В этом методе, мы обернём div с контентом другим div-ом. Установим ему высоту в 50% (height: 50%;), а нижний отступ половине высоты (margin-bottom:-contentheight;). Контент будет очищать float и выводиться по центру.
Плюсы
- Работает во всех броузерах.
- Когда недостаточно места (например, когда уменьшено окно) контент не обрезается, появятся скроллбары.
Минусы
- Думаю только один: что используется лишний пустой элемент.
4-ый метод.
Этот метод использует свойство position:absolute; для div-а с фиксированными размерами (шириной и высотой). Затем устанавливаем ему координаты top:0; bottom:0;, но поскольку у него фиксированная высота, то он не может растянуться и выравнивается по центру. Это очень похоже на общеизвестный метод горизонтального выравнивания по центру блочного элемента фиксированной ширины (margin: 0 auto;).
Плюсы
- Очень просто.
Минусы
- Не работает в Internet Explorer
- Контент будет обрезаться без скролл-баров, если не хватает места в контейнере.
5-ый метод
С помощью этого метода можно выровнять по центру одну строку текста. Просто устанавливаем высоту текста (line-height) равной высоте элемента (height). После этого строка будет выведена по центру.
Плюсы
- Работает во всех броузерах.
- Не обрезает текст, если он не влез.
Минусы
- Работает только с текстом (не работает с блочными элементами).
- Если текста больше чем одна строка, то выглядит очень плохо.
Этот способ очень полезен для небольших элементов, например чтобы вырвнять по центру текст в кнопке или в текстовом поле.
Теперь вы знаете как добиться вертикального выравнивания по центру, давайте сделаем простой web-сайт, который, в конце-концов будет выглядеть так:
Шаг 1
Всегда хорошо начинать с семантической разметки. Наша страница будет структурирована следующим образом:
- #floater (чтобы выровнять контент по центру)
- #centred (центральный элемент)
- #side
- #logo
- #nav (список
- )
Напишем следующую html-разметку:
Шаг 2
Сейчас мы напишем простейший CSS, для размещения элементов на странице. Вы должны сохранить этот код в файле style.css. Именно на него прописана ссылка в html-файле.
Перед тем как сделать наш контент выровненным по центру, необходимо для body и html установить высоту 100%. Так как высота считается без внутренних и внешних отступов (padding и margin), то мы устанавливаем их (отступы) в 0, чтобы не было скроллбаров.
Нижний отступ для элемента "floater"-а равен минус половине высоты контента (400px), а именно -200px;
Сейчас ваша страничка должна выглядеть приблизительно так:
Ширина элемента #centered 80%. Это делает наш сайт уже на маленьких экранах и шире на больших. большинство сайтов выглядит неприлично на новых широких мониторах в верхнем левом углу. Свойства min-width и max-width также ограничивают нашу страничку, чтобы она не выглядела слишком широкой или слишком узкой. Internet Explorer не поддерживает эти свойства. Для него надо установить фиксированную ширину.
Поскольку элементу #centered установлено position:relative, мы можем использовать абсолютное позиционирование элементов внутри него. Затем установим overflow:auto; для элемента #content, чтобы появлялись скроллбары, в случае если не будет помещаться контент.
Шаг 3
И последнее что мы сделаем, это добавим кое-какие стили, чтобы страничка выглядела немного привлекательнее. Давайте начнём с меню.
Первое что мы сделали, чтобы меню выглядело лучше, удалили маркеры, установив атрибут list-style:none, а также установили внутренние и внешние отступы, так как по умолчанию в разных броузерах они сильно различаются.
Обратите внимание, что затем мы указали чтобы ссылки отбражадись как блочные элементы. Теперь, при выводе, они растягиваются по всей ширине элемента в котором они расположены.
Другая интересная вещь, которую мы использовали для меню — это псевдо-классы :before и :after. Они позволяют вам добавить что-нибудь перед и после элемента. Это хороший способ добавлять иконки или символы, такие как стрелочка в конце каждой ссылки. Такой трюк не работает в Internet Explorer 7 и ниже.
Шаг 4
Ну и самое последнее, мы добавим в наш дизайн кое-какие втили для ещё большей красоты.
В этих стилях мы устанавливаем закруглённые углы для элемента #centered. В CSS3, за это будет отвечать свойство border-radius. Это пока что не реализовано некоторыми броузерами, разве только использовать приставки -moz и -webkit для Mozilla Firefox и Safari/Webkit.
Совместимость
Как вы уже наверное предположили, основной источник проблем совместимости — Internet Explorer:
- Элементу #floater обязательно надо установить ширину
- В IE 6 лишние отступы вокруг меню
Сегодня, уважаемый читатель, мы с вами разберемся с проблемой вертикального выравнивания в блоке div.
Скорее всего вы уже знаете о существовании замечательного свойства CSS vertical-align. И сам Бог велел нам пользоваться для вертикального выравнивания именно этим свойством (не зря же оно носит такое, говорящее само за себя, название).
Постановка задачи: Необходимо выровнять содержимое блока переменной высоты по центру относительно вертикали.
Теперь приступим к решению поставленной задачи.
И так, у нас есть блок, высота его может меняться:
Первое, что приходит в голову – это сделать следующий финт:
Есть все основания предполагать, что фраза Содержимое блока выровняется по центру высоты div-контейнера.
Но не тут-то было! Никакого ожидаемого выравнивания по центру таким образом мы не добьемся. А почему? Казалось бы все указано правильно. Оказывается вот в чем загвоздка: свойство vertical-align можно применять только для выравнивания содержимого ячеек таблиц или для выравнивания строчных элементов друг относительно друга.
По поводу выравнивания внутри ячейки таблицы, я думаю, все понятно. А вот другой случай со строчными элементами я поясню.
Вертикальное выравнивание строчных элементов
Предположим есть у вас строка текст, которая разбита строчными тегами на части:
Под строчным тегом понимается контейнер, появление которого не приводит к переносу содержимого на новую строку.
Действие же блочного тега приводит к переносу содержимого контейнера на новую строку.
Контейнер удобно использовать при задании части текста особого форматирования (выделение цветом, другим шрифтом и т.д.)
Для контейнеров применим следующие свойства CSS:
В результате строка текста будет иметь вот такой вид:
Это и есть ничто иное, как выравнивание строчных элементов по вертикали, и свойство CSS vertical-align с этой задачей прекрасно справляется.
Мы немного отвлеклись, теперь возвращаемся к нашей основной задаче.
Выравнивание по вертикали в div-контейнере
Не смотря ни на что, для выравнивания внутри div-контейнера мы будем использовать свойство vertical-align. Как я уже говорил, данное свойство можно использовать в случае выравнивания строчных элементов (этот случай мы подробно рассмотрели выше и для выравнивания в div-контейнере он нам не подходит); остается лишь использовать тот факт, что vertical-align работает для ячеек таблицы.
Как же мы сможем это использовать? У нас же нет таблицы, мы работаем с div-контейнером.
Ха, оказывается очень просто.
CSS-свойство display позволяет превратить наш блок div в ячейку таблицы, сделать это можно легко и непринужденно:
Пусть у нас есть div класса textalign:
Для данного блока указываем следующее CSS-свойство:
Эта CSS-инструкция чудесным образом превратит наш блок div в ячейку таблицы, визуально никак его не изменив. А для ячейки таблицы мы сможем применять свойство vertical-align в полной мере и будет работать желаемая центровка по вертикали.
Однако, все так просто закончится не может. У нас же есть замечательный браузер IE. Он не умеет работать со свойством display: table-cell (предлагаю вам ознакомится с табличкой, иллюстрирующей работоспособность данного CSS-свойства в разных браузерах на сайте htmlbook.ru). Поэтому нам придется идти на различные ухищрения.
Существует множество способов добиться выравнивания в div-контейнере для всех браузеров:
- Способ с применением дополнительного вспомогательного div-котнейнера
- Способ с использованием expression-а. Связан он с хитрым вычислением высот блоков. Без знания JavaScript тут не обойтись.
- Использование свойства line-height. Данный способ подходит только для вертикального выравнивания в блоке известной высоты, а значит в общем случае не применим.
- Использование абсолютного и относительного смещения содержимого в случае браузера IE. Мне этот способ кажется наиболее понятным и простым. Кроме того, он реализуем для div-контейнера переменной высоты. На нем мы остановимся подробнее.
Как вы понимаете, нам остается решить проблему вертикального выравнивания в IE, связанную с его непониманием свойства display: table-cell (ни IE6, ни IE7, ни IE8 с этим свойством не знакомы). Поэтому воспользовавшись условным комментарием специально для браузеров семейства IE мы укажем другие свойства CSS.
Условный комментарий
называется условным комментарием (будьте внимательны, вид условного комментария должен полностью соответствовать приведенному примеру, с точностью до пробела).
Инструкции, содержащиеся в подобном условном комментарии будут выполнены только в случае, если браузер, интерпретирующий данный код, принадлежит к семейству IE.
Таким образом, используя условный комментарий, мы сможем спрятать кусок кода от всех браузеров кроме IE.
Запомнили, пошли дальше.
Решение задачи
Из-за всей этой петрушки нам нужно будет снабдить наш HTML-код двумя дополнительными контейнерами. Вот каким образом будет выглядеть наш блок с текстом:
Для div-контейнера класса textalign задаются CSS-свойства, которые выравнивают его содержимое по вертикали для всех нормальных браузеров (кроме IE, разумеется):
И еще два свойства, которые задают ширину и высоту для блока:
Этого вполне достаточно для выравнивания содержимого контейнера по центру относительно вертикали, во всех браузерах кроме IE.
Теперь начинаем дописывать свойства, связанные с выравниванием для браузеров семейства IE (именно для них мы использовали дополнительные блоки div и span):
Обращаемся к тегу div внутри блока класса textalign. Для этого нужно указать сначала название класса, а потом, через пробел, тег, к которому мы обращаемся.
Такая конструкция означает: для всех тегов div внутри блока с классом textalign применить перечисленные свойства.
Если все оставить так как есть, то div-контейнер, который находится внутри блока textalign, будет позиционироваться относительно верхнего левого угла браузера. Нам же нужно, чтобы смещение на 50% по вертикали произошло относительно родительского блока. Для этого достаточно применить CSS-свойство position: relative блоку textalign. Об этих особенностях я подробно рассказываю в видеоуроке по работе с блоками div.
Соответственно, стили заданные для блока textalign видоизменяются:
Теперь левая верхняя точка текстового блока смещена вниз на 50%.
Для пояснения происходящего я нарисовал иллюстрацию:
Как видно из картинки, определенного прогресса мы добились. Но это еще не все! Верхняя левая точка желтого блока действительно сместилась на 50% вниз, относительно родительского (фиолетового) блока. Но нам-то нужно, чтобы на пятидесяти процентах высоты фиолетового блока находился центр желтого блока, а не его верхняя левая точка.
Теперь в ход пойдет тег span и его относительное позиционирование:
Тем самым, мы сместили желтый блок вверх на 50% его высоты, относительно начального положения. Как вы понимаете, высота желтого блока равна высоте центрируемого контента. И последняя операция со span-контейнером расположила наш контент посередине фиолетового блока. Ура!
Немного подшаманим
Перво-на-перво нам нужно спрятать петрушку от всех нормальных браузеров и открыть ее для IE. Сделать это можно, конечно же, при помощи условного комментария, не зря мы с ним знакомились:
Есть небольшая проблемка. Если центруемый контент слишком высокий, то это приводит к неприятным последствиям: появляется лишняя высота вертикальной прокрутки.
Решение проблемы: нужно добавить свойство overflow: hidden блоку textalign.
Детально познакомиться со свойством overflow можно в видеоуроке по работе с блоками div.
Окончательный вид CSS-инструкций для блока textalign имеет вид:
Прошу пардону, забыл упомянуть один важный момент. Если вы будите пытаться задавать высоту блока класса textalign в процентном соотношении, то у вас ничего не выйдет.
Центровка в блоке переменной высоты
Очень часто встречается необходимость задать высоту блока класса textalign не в пикселах, а в процентах от высоты родительского блока, и выровнять содержимое div-контейнера по середине.
Загвоздка в том, что для ячейки таблицы невозможно этого сделать (а ведь блок класса textalign превращается именно в ячейку таблицы, благодаря свойству display:table-cell).
В этом случае необходимо использовать внешний блок, для которого указано CSS-свойство display:table и уже для него задавать процентное значение высоты. Тогда вложенный в него блок, с CSS-директивой display:table-cell, благополучно унаследует высоту родительского блока.
Для того, чтобы в нашем примере реализовать блок переменной высоты, мы немного подредактируем CSS:
Классу textalign мы изменим значение свойства display с table-cell на table и убирем директиву выравнивания vertical-align: middle. Теперь мы смело можем изменить значение высоты с 500 пикселов на, например, 100%.
Таким образом, CSS-свойства для блока класса textalign будут иметь следующий вид:
Остается реализовать центрирование содержимого. Для этого div-контейнеру, вложенному в блок класса textalign (это тот самый желтый блок на рисунке), необходимо задать CSS-свойство display:table-cell, тогда он унаследует высоту в 100% от родительского блока textalign (фиолетовый блок). И нам ничто не помешает выровнять содержимое вложенного div-контейнера по центру свойством vertical-align: middle.
Получаем еще один дополнительный список CSS-свойств для блока div, вложенного в контейнер textalign.
Вот и вся хитрость. При желании, вы можете посмотреть на сверстанный блок переменной высоты с отцентрованным содержимым.
Дополнительную информацию по вертикальному выравниванию блока переменной высоты можно получить тут.