Вертикальная перестановка блоков средствами CSS
- Марат Таналин
- Опубликовано:
- Обновлено:
- Краткое описание
- Кроссбраузерный способ полноценной вертикальной перестановки блоков произвольной высоты средствами CSS.
Современные браузеры — Flexbox
Произвольный порядок
В современных браузерах (в том числе Internet Explorer 11 и Edge) управлять визуальным порядком элементов можно с помощью CSS-свойства order
, являющегося частью механизма Flexbox. Блоки следуют в порядке возрастания значений свойства order
. Значением свойства order
должно быть целое число, которое может быть как положительным, так и отрицательным. Значение по умолчанию — 0
.
- HTML:
<div class="example">
<div class="a">Первый</div>
<div class="b">Второй</div>
<div class="c">Третий</div>
</div>- CSS:
.example {
display: flex;
flex-direction: column;
}
.example > .a {order: 3; } /* Отобразится третьим */
.example > .b {order: 2; } /* Отобразится вторым */
.example > .c {order: 1; } /* Отобразится первым */
Объявление display: flex
включает Flexbox для элемента-контейнера. Объявление flex-direction: column
задаёт вывод дочерних элементов контейнера друг под другом вместо горизонтального вывода, используемого во Flexbox по умолчанию.
Вертикальное положение переупорядочиваемых блоков является взаимозависимым: увеличение высоты любого из блоков приводит к автоматическому вертикальному сдвигу визуально следующих за ним блоков, в том числе при динамическом изменении высоты блоков, например, вследствие увеличения размера шрифта средствами браузера.
Обратный порядок
Если требуется просто вывести элементы в обратном порядке, можно использовать объявление flex-direction: column-reverse
для содержащего их контейнера без необходимости явно задавать расположение каждого элемента:
.example {
display: flex;
flex-direction: column-reverse;
}
Устаревшие браузеры — display: table
В браузерах, не поддерживающих Flexbox (IE 10 и ниже), вертикальный порядок следования блоков на HTML-странице можно изменить, придав им табличное представление при помощи CSS-свойств семейства display: table
. Вне зависимости от порядка расположения блоков в HTML-коде, «шапка» (display: table-header-group
) такой таблицы отображается в её верхней части, «подвал» (table-footer-group
) — в нижней, а основная часть таблицы (table-row-group
) — между ними.
.example {
display: table;
width: 100%;
}
.example > .a {display: table-footer-group; } /* Отобразится внизу псевдотаблицы */
.example > .b {display: table-row-group; } /* Отобразится посередине */
.example > .c {display: table-header-group; } /* Отобразится вверху */
Описанным образом можно изменять порядок до трёх соседних блоков. Дополнительно можно задействовать display: table-caption
(отображение блока в роли подписи к таблице) в сочетании с CSS-свойством caption-side
со значением top
или bottom
.
Метод работает в большинстве распространённых браузеров, в том числе в Internet Explorer начиная с версии 9 (IE8 — с оговорками, см. далее).
Internet Explorer 6, 7 и 8 — DOM
Устаревшие браузеры IE6 и IE7 не поддерживают CSS-свойства семейства display: table*
.
Кроме того, в IE8 в некоторых случаях наблюдается динамическая ошибка рендеринга: если перемещаемый блок содержит в себе псевдотабличные элементы (display: table*
) (проявление нюанса замечено только в этом случае), возможно спонтанное пропадание некорых ячеек (всегда разных и в разном количестве) псевдотаблицы при первичной отрисовке страницы.
Поэтому для IE8 и ниже можно отменить CSS-правила, придающие блокам табличный вид, и дополнительно переместить блоки в нужные позиции DOM-дерева HTML-документа уже с помощью JavaScript:
/**
* Перестраивает соседние элементы в DOM-дереве в заданном порядке.
* @param {Array} elems Соседние элементы в необходимом порядке.
*/
function reorderElements(elems) {
// http://tanalin.com/articles/css-block-order/
var count = elems.length;
if (!count) {
return;
}
var parent = elems[0].parentNode;
for (var i = count - 1; i >= 0; i--) {
parent.insertBefore(elems[i], parent.firstChild);
}
}
Определение возможностей браузера
Использовать разные стили для современных и устаревших браузеров можно путём определения возможностей браузера средствами JavaScript.
Определить, поддерживает ли браузер Flexbox, можно путём проверки существования свойства order
объекта, доступного через свойство style
корневого элемента документа (<html></html>
) — document.documentElement
.
Версию Internet Explorer можно определить путём проверки существования нестандартного объекта document.all
, доступного только в IE 10 и ниже, в сочетании с существованием или отсутствием одного из стандартных объектов.
if ('order' in document.documentElement.style) {
// Flexbox-совместимый браузер.
// Используем `order` или `flex-direction: column-reverse`.
}
else if (document.all && !document.addEventListener) {
// IE8 или ниже.
// Изменяем реальный порядок блоков в DOM-дереве средствами JS.
}
else {
// Браузер без поддержки Flexbox, в том числе IE 9/10.
// Используем `display: table`.
}