Научный консалтинг
Главная
Контакты
Номер телефона
Как мы работаем
Гарантии
Условия
Цены

Последнее обновление:

Как отцентрировать блочный элемент html

С одной стороны, вроде бы, немало публикаций на подобную тему. Причина их появления, на самом деле, заключается в том, что вертикальное центрирование блочных (да инлайновых - тоже) элементов в языке html, по сути, на редкость не продумано.

Единственное, что делается более-менее просто – это горизонтальное центрирование инлайновых элементов (при помощи свойства CSS text-align: center ). Остальное – отнюдь нетривиально. Дело в том, что вертикальное центрирование, в отличие от горизонтального, не было предусмотрено в спецификации CSS в качестве универсального способа. Поэтому приходится несколько исхитряться.

Например, как отцентирировать блочный элемент вертикально? Без использовнаия javascript, имеется в виду.

К сожалению, вертикальное центрирование почему-то невозможно непосредственно в блоках типа block, inline-block, так как свойство vertical-align: middle не работает в блоках подобного типа, оно предназначено лишь для блоков, имеющих отношение к таблицам. Т.е. это – теги table, а также блоки, имеющие свойства display: table-cell.

На самом деле, способов центрирования, вроде как, немало. Однако, согласитесь, лучше, во-первых, не распыляться и пользоваться ОДНИМ, но универсальным. Во-вторых, очень многие способы, предлагаемые на сайтах, НЕ являются универсальными, в частности, по причине необходимости задания ширины и/или высоты блока.

Что же, рассмотрим пример кода html, позволяющий выполнить как горизонтальное, так и вертикальное центрирование для произвольных размеров центрируемых блоков. Поставим следующую задачу. Необходимо отцентрировать картинку (тег img) в обоих направлениях и при этом еще и наложить ее на другую картинку – большего размера. Конечно, это можно было бы сделать в одной из графических программ, типа GIMP, но, попробуем справиться с этим средствами html+CSS:


<div style=" border: solid darkblue; position: relative; ">
   <img src="process_zakaza.png" alt="Процесс - 1" style="width: 100%"/>

   <div style="position: absolute;   top: 0; left: 0;   height: 100%; width: 100%; display: block;   border: solid darkmagenta">
       <div style="display: table; height: 100%; ">
           <div style="display: table-cell; width: 1px"></div>
           <div style="display: table-cell;  vertical-align: middle; width: 100%; text-align: center; border: solid darkgreen">
           <img src="arrows_yellow.png" alt="Процесс - 2" style="display: inline-block;  width: 63%; border: dashed darkorange"/>
           </div>
           <div style="display: table-cell; width: 1px"></div>
       </div>
   </div>
</div>


Итак, что видим:


Процесс - 1
Процесс - 2


Границы всех блоков показаны только для наглядности. Скорее всего, в реальной верстке они не понадобятся и тогда их можно убрать.

Вначале задается тег для первой картинки, которая имеет более высокие размеры (картинка, содержащая четыре синих круга). После чего поверх нее рисуется блок div со свойством position: absolute (имеющий границу пурпурного цвета), причем этот блок растягивается по ширине и длине родительского блока (имеющего границу темно-синего цвета) при помощи свойств top: 0; left: 0; height: 100%; width: 100%. Отметим, что иногда можно встретить вариант margin: 0 auto, что тоже работает.

Блок с границей пурпурного цвета необходим лишь для того, чтобы внутри него осуществлять центрирование. По сути, вместо него может фигурировать любой другой блок - все зависит от особенностей верстки конкретной вебстраницы.

Далее – задаются теги, имеющие структуру таблицы. Алгоритм расчета ширины, высоты, местоположения элементов внутри них является таким же, как и для настоящих таблиц, т.е. тех, которые задаются тегами table, tr, td.

При помощи свойств display: table, display: table-cell задаем таблицу.

Обратите внимание, что присутствуют, по сути, фиктивные теги, имеющие вид

<div style="display: table-cell; width: 1px"></div>

Это сделано для того, чтобы в образовавшейся таблице было ровно три ячейки. Правая и левая ячейки имеют ширину, равную 1рх (к сожалению, установление ширины, равной нулю, не дает возможности достигнуть необходимого эффекта), т.е., по сути, незаметны на странице. Тогда как средняя (центральная) ячейка имеет ширину, равную 100% (т.е. занимает практически всю ширину таблицы, за исключением двух пикселей).

Кстати, вполне можно воспользоваться псевдоэлементами :before и :after для задания правой и левой ячеек таблицы.

Этим и достигается эффект горизонтального центрирования содержимого средней ячейки получившейся таблицы (со свойством display: table-cell).

Отметим, что вместо таблицы для горизонтального центрирования можно было бы использовать и блоки с иными свойствами, например, display: inline-block, но, к сожалению, это не подходит для вертикального центрирования.

В отношении же последнего, так как мы имеем дело с таблицей, работает свойство vertical-align: middle. Как уже говорилось, к сожалению, оно работает только для табличных, инлайновых и инлайн-блочных элементов (и для настоящих таблиц). Но, к сожалению, не внутри блочных.

Однако, ничего не мешает расположить внутри блока со свойством display: table-cell любое количество других элементов, в том числе, и блочных. Вы можете убедиться в этом, поместив непосредственно за тегом (или вместо него)

<img src="arrows_yellow.png" alt="Процесс - 2" style="display: inline-block;  width: 63%; border: dashed darkorange"/>

какой-нибудь блочный элемент (т.е. такой, у которого установлено display: block). Он отцентрируется вместе с картинкой – как по вертикали, так и по горизонтали.

Конечно, данный способ имеет два (и только два) небольших недостатка:

  1. Требуется добавление двух фиктивных тегов, имеющих ширину 1рх. Согласно существующей в настоящее время (теоретической) концепции, не должны добавляться дополнительные теги исключительно ради оформления. Однако… ведь дополнительные теги точно также добавляются практически во всех известных способах вертикального центрирования (будь то использование псевдоэлементов или еще что). Поэтому, по сути, это нельзя назвать недостатком. В разумных случаях приходится добавлять дополнительные теги ради разметки и повышения качества оформления – ничего в этом принципиально страшного нет, главное – не переборщить и соблюдать стандарты, т.е. чтобы верстка была правильной (валидной).
  2. Каждый из двух дополнительных тегов «съедает» по одному пикселю. Однако, размер в два лишних пикселя, вероятно, не отнимет много места (при разрешении современных дисплеев от 500рх). Если, конечно, не потребуется горизонтально центрировать несколько десятков (или сотен) элементов, расположенных на одном уровне. Однако, в подобных случаях целесообразно обернуть такие элементы отдельным блоком (одним или несколькими) div и проводить центрирование именно его (их). А не каждого их элементов по отдельности.

За исключением упомянутых недостатков, предлагаемый способ является универсальным. Он не требует указания конкретной высоты и/или ширины ни одного из центрируемых блоков. Так что, на наш взгляд, ВЕЗДЕ, где возникает необходимость центрирования, можно пользоваться только им.

Управление положением элементов

Однако, элемент (в вышеприведенном коде – картинка) можно не только центрировать, но и сдвигать на разные расстояния относительно родительского. Причем, расстояния могут выражаться как в процентах по отношению к размерам родительского блока, так и в фиксированном виде – в пикселях.

Например, мы хотим сдвинуть картинку в вертикальном направлении не на 50% (что означает ее центрирование), а, скажем, на меньшее расстояние.

Для этой цели следует варьировать свойства top: 0; left: 0;   height: 100%; width: 100%. В частности, чтобы сдвинуть картинку от верхнего края родительского блока не на 50%, а меньше, то следует записать, например:

top: 15%; left: 0;   height: 85%; width: 100%;

Сделав указанные изменения, получим:


Процесс - 1
Процесс - 2

Видим, что синие круги вместе с окаймляющей их темно-синего цвета остались на месте, тогда как пурпурная и зеленые границы (в верхних частях) опустились на 15%, вместе с ними опустилась и вторая картинка (наложенная на ту, на которой изображены круги).

Т.е. вторая картинка (граница которой обозначена пунктирной оранжевой линией), и вправду, опустилась не точно в середину, а чуть ниже.

При это она, как положено, центрирована как по вертикали, так и по горизонтали в пределах блока с зеленой границей.

Записав вместо

<div style="display: table-cell;  vertical-align: middle; width: 100%; text-align: center; border: solid darkgreen">

немного иначе:

<div style="display: table-cell;  vertical-align: top; width: 100%; text-align: center; border: solid darkgreen">

получим следующую картину:


Процесс - 1
Процесс - 2

Т.е. оранжевый блок прижался к верхней части пурпурно-зеленой границы.

Аналогичным образом можно осуществлять и изменение горизонтального местоположение этого блока.

Таким образом, варьируя указанные параметры – вручную или при помощи javascript – можно разместить картинку с оранжевой границей в любом месте блока с кругами (впрочем, вполне можно также разместить ее и за пределами этого блока). Тем самым, в самом деле, данный метод является практически универсальным.

А, может, display: flex ?...

Да, в самом деле, его использование существенно облегчает и центрирование, и ряд других вещей. Но, на наш взгляд, данное свойство еще НЕ следует применять в настоящее время (2017 г.). Потому как еще есть много пользователей, которые пользуются старыми браузерами. Например, я, автор настоящей статьи, вполне себе использую Firefox 24. Однажды я попытался было установить новый (на тот момент) FF51, но, поиспользовав его пару дней, СНЕС его и все, что с ним было связано. Полностью удалил его с компьютера, т.е., включая ВСЕ следы в системном реестре.

Причина тому – очень медленная скорость загрузки и работы. А FF24 открывается, кстати, даже быстрее, чем пресловутый Microsoft Word. Хотя, этот браузер, наверное, на порядок сложнее последнего. Имея при этом открытыми более 50 вкладок. Поэтому со свойством flex стоит все же повременить. А вот лет через 5…7, да, можно начинать потихоньку его применять. То же касается, на наш взгляд, и всех остальных новых технологий. Которые, да, можно и нужно применять, но только в качестве ДОПОЛНИТЕЛЬНЫХ возможностей. Попутно – тестируя эти самые возможности. Но, уж никак не в качестве основной (а то и – единственной) технологии.

А, может, ну их, эти «старые» браузеры?

Э, нет. Не ну. Вообще, я много раз обращал внимание на одну простую вещь: чем больше сайт использует разного рода «технологий», чем в большей мере он напичкан разными «современными решениями» (не работающими в браузерах более ранних версий), тем он, как правило, бесполезнее – с точки зрения контента, т.е. информации, которую можно там почерпнуть, узнать. Поэтому, собственно говоря, практически никогда не бывает обидно, что некоторые сайты при помощи Firefox 24 или Internet Explorer 9 отображаются немного некорректно, а то и вовсе не отображаюся: ну и ладно, лучше по-быстрому закрыть страницу и поискать в сети другой, более приспособленный для пользователей, сайт. Тем более, что, как уже говорилось, скорее всего, на нем будет больше интересной и полезной информации - не стоит и время тратить.

Причина тому, на наш взгляд, банальна: чем больше владелец и администрация сайта заботятся о пользователях, тем более качественным и интересным будет сайт. Но, при этом, естественно, они не станут отсекать от своего сайта всех тех, кто по тем или иным причинам не перешел на «новые» браузеры. Напротив, они приложат все возможные усилия, чтобы КАЖДОМУ пользователю обеспечить максимальный уровень удобства, пользы и комфорта при работе с сайтом.

Тем же, кто хочет замолвить слово о «необходимости развитии вебтехнологий», хочется напомнить одну простейшую вещь. Все-таки, сайты - для пользователей. А не пользователи – для сайтов или их разработчиков. Да, именно так, а не иначе. Посему, стоит применять такие и только(!) такие технологии, которые устраивают как можно большее количество пользователей. Которые, уж по крайней мере, не мешают им. А необязательно такие, которые разработчики сайта считают новыми, прогрессивными, современными и т.д. Поэтому, со свойством flex – лучше бы подождать как-нибудь до лучших времен. Используя вместо него, к примеру, вышеприведенный код. Если же кому приспичило, как говорится, использовать именно flex (если уж совсем жизни нет без него), так тогда уж следует проэмулировать его средствами javascript - для обеспечения требуемой функциональности сайта в браузерах более ранних версий).


Комментарии:
Петр01.06.2019 21:26РедактироватьУдалить
Данный способ не совсем универсальный. Дело в том, что рисунки имеют, как ни крути, определенные размеры. И именно под них подстраиваются высоты, в частности. Имею в виду, рисунок с синими кружками. Это то же самое. как если бы это был див с height="сколько-то рх"
Всего комментариев: 1
Пожалуйста, не забудьте ознакомиться с правилами оставления комментариев.



Подписаться на комментарии на этой странице

Мы можем выполнить

Другие услуги
Интересная и полезная
информация