- Направление и порядок элементов¶
- Свойство order¶
- Способы смены порядка вывода элементов с помощью CSS
- Цель
- Разметка
- Стили
- Методы упорядочивания колонок
- Метод №1: плавающие блоки
- Метод №2: позиционирование
- Метод №3: свойство direction
- Метод №4: трансформация
- Метод №5: флексбокс
- Метод №6: грид-раскладка
- Порядок исходников и визуальный порядок
- Заключение
Направление и порядок элементов¶
По умолчанию все элементы располагаются по порядку горизонтально, если места в строке больше нет, то элементы переносятся на следующую строку. Но с помощью свойства grid-auto-flow можно изменить направление элементов. Это свойство принимает два значения:
- row : значение по умолчанию, элементы располагаются в строку друг за другом, если места в строке не хватает, элементы переносятся на следующую строку
- column : элементы располагаются в столбик, если места в столбце не хватает, то элементы переходят в следующий столбец
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
html> head> meta charset="utf-8" /> meta name="viewport" content="width=device-width" /> title>Grid Layout в CSS3title> style> * box-sizing: border-box; > html, body margin: 0; padding: 0; > .grid-container height: 100vh; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); grid-auto-flow: row; > .grid-item text-align: center; font-size: 1.1em; padding: 1.5em; color: white; > .color1 background-color: #675ba7; > .color2 background-color: #9bc850; > .color3 background-color: #a62e5c; > .color4 background-color: #2a9fbc; > .color5 background-color: #4e342e; > style> head> body> div class="grid-container"> div class="grid-item color1">Grid Item 1div> div class="grid-item color2">Grid Item 2div> div class="grid-item color3">Grid Item 3div> div class="grid-item color4">Grid Item 4div> div class="grid-item color1">Grid Item 5div> div class="grid-item color4">Grid Item 6div> div class="grid-item color5">Grid Item 7div> div> body> html>
Свойство grid-auto-flow имеет значение row , поэтому элементы будут располагаться в строку.
Теперь изменим стиль grid-контейнера:
.grid-container height: 100vh; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); grid-auto-flow: column; >
После этого элементы будут располагаться в столбец
Свойство order¶
Свойство order позволяет задать порядок элементов. По умолчанию для каждого элемента в гриде это свойство имеет значение 0 . Поэтому элементы располагаются друг за другом как они определены в разметке html. Но мы можем переопределить этот порядок:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
html> head> meta charset="utf-8" /> meta name="viewport" content="width=device-width" /> title>Grid Layout в CSS3title> style> * box-sizing: border-box; > html, body margin: 0; padding: 0; > .grid-container height: 100vh; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); > .grid-item text-align: center; font-size: 1.1em; padding: 1.5em; color: white; > .last-item order: 1; > .first-item order: -1; > .color1 background-color: #675ba7; > .color2 background-color: #9bc850; > .color3 background-color: #a62e5c; > .color4 background-color: #2a9fbc; > .color5 background-color: #4e342e; > style> head> body> div class="grid-container"> div class="grid-item color1">Grid Item 1div> div class="grid-item color2 last-item"> Grid Item 2 div> div class="grid-item color3 last-item"> Grid Item 3 div> div class="grid-item color4">Grid Item 4div> div class="grid-item color1">Grid Item 5div> div class="grid-item color4">Grid Item 6div> div class="grid-item color5 first-item"> Grid Item 7 div> div> body> html>
Элементы с классом last-item имеет порядок 1 , поэтому они будут располагаться после других элементов, у которых порядок равен 0 или меньше.
Если же необходимо поставить одни элементы перед другими, то можно использовать отрицательное значение для свойства order . Так, у седьмого элемента порядок равен -1 , что меньше, чем у других элементов. Поэтому последний в разметке элемент по факту будет располагаться перед всеми элементами.
Способы смены порядка вывода элементов с помощью CSS
В этой статье мы рассмотрим несколько различных методов CSS для переупорядочения вывода элементов HTML.
Цель
Наша раскладка очень простая. В частности, на маленьких экранах (меньше 600px) она будет выглядеть так:
На средних экранах и больше (от 600px) кнопки будут выстраиваться в ряд:
Наша главная задача — поменять порядок кнопок на обратный.
Разметка
Разметка будет самая простая: просто элемент div , содержащий четыре кнопки:
Стили
На маленьком экране у всех кнопок будут одинаковые стили:
.boxes button < display: block; width: 100%; padding: 15px; border: none; margin-bottom: 5px; box-sizing: border-box; font-size: 1rem; text-align: center; text-decoration: none; background: gold; color: #000; >.boxes button:nth-of-type(even)
На больших экранах мы зададим width: 25% , остальные стили будут определяться методом CSS, который мы будем применять для задания обратного порядка кнопок.
@media screen and (min-width: 600px) < /* we skip this property in flexbox and grid methods */ width: 25%; /* more stuff here */ >
Наконец, у нас будут стили для состояния focus наших кнопок:
Таким образом, если мы будем использовать для навигации клавишу Tab, наши кнопки при фокусировке станут темно-красными.
Методы упорядочивания колонок
Теперь мы готовы проверить различные подходы CSS для вывода кнопок в реверсивном порядке при превышении областью видимости ширины в 599px.
Метод №1: плавающие блоки
Можно просто добавить блокам float: right , вот полные стили:
@media screen and (min-width: 600px) < .boxes button < float: right; width: 25%; >>
Метод №2: позиционирование
Альтернативным вариантом будет задание позиции элементам, относительной или абсолютной.
По первому варианту (с относительным позиционированием) мы зададим кнопкам, плывущим влево свойство position: relative и затем расставим их с помощью свойство left .
@media screen and (min-width: 600px) < .boxes button < position: relative; float: left; width: 25%; >.boxes button:nth-of-type(1) < left: 75%; >.boxes button:nth-of-type(2) < left: 25%; >.boxes button:nth-of-type(3) < left: -25%; >.boxes button:nth-of-type(4) < left: -75%; >>
Вторым вариантом (с использованием абсолютного позиционирования) мы зададим нашим кнопкам position: absolute , а с помощью свойства left разместим их более точно.
@media screen and (min-width: 600px) < .boxes < position: relative; >.boxes button < position: absolute; width: 25%; >.boxes button:nth-of-type(1) < left: 75%; >.boxes button:nth-of-type(2) < left: 50%; >.boxes button:nth-of-type(3) < left: 25%; >.boxes button:nth-of-type(4) < left: 0; >>
Метод №3: свойство direction
Менее очевиден подход на основе свойства direction — оно предназначено для смены направления чтения текста. В нашем случае мы задаем direction: rtl (справа налево) для элемента-обертки, что позволит сменить направление раскладки.
Примечание: для этого примера мы дадим нашим кнопкам поведение элементов таблицы, чтобы создать горизонтальную раскладку.
Вы можете видеть необходимые стили CSS ниже:
@media screen and (min-width: 600px) < .boxes < display: table; width: 100%; direction: rtl; >.boxes button < display: table-cell; width: 25%; >>
Стоит упомянуть, что если по каким-то причинам мы хотим также изменить направление текста в кнопках, мы можем включить специальное правило для того, чтобы направление символов юникода определялось свойством direction .
Метод №4: трансформация
Изящным решением будет оставить кнопкам float: left; и затем применить transform: scaleX(-1) к ним и их родителю. Задав отрицательные значения мы сделаем так, что трансформируемый элемент не масштабируется, а переворачивается по горизонтальной оси.
@media screen and (min-width: 600px) < .boxes < transform: scaleX(-1); >.boxes button < float: left; transform: scaleX(-1); width: 25%; >>
Мы также можем использовать для создания нужного порядка функцию трансформации rotate . Все, что нам надо добавить кнопкам и их родителю свойство transform: rotateY(180deg) .
@media screen and (min-width: 600px) < .boxes < transform: rotateY(180deg); >.boxes button < float: left; transform: rotateY(180deg); width: 25%; >>
Метод №5: флексбокс
Флексбокс это еще один способ изменения порядка колонок. В нашем примере мы используем два разных свойства флексбокса для создания нашей раскладки.
Первый подход это сделать родительский элемент кнопок флекс-контейнером и затем добавить flex-direction: row-reverse , вот так:
@media screen and (min-width: 600px) < .boxes < display: flex; flex-direction: row-reverse; >>
Второй вариант с флексбоксом состоит в использовании свойства order для определения порядка, в котором кнопки должны выводиться.
@media screen and (min-width: 600px) < .boxes < display: flex; >.boxes button:nth-of-type(1) < order: 4; >.boxes button:nth-of-type(2) < order: 3; >.boxes button:nth-of-type(3) < order: 2; >.boxes button:nth-of-type(4) < order: 1; >>
Метод №6: грид-раскладка
Многообещающим решением для расстановки элементов является раскладка на основе CSS Grid. Несмотря на крайне ограниченную поддержку в браузерах на момент написания статьи ее стоит попробовать. Учитывайте, что наш пример будет работать только в Chrome (по умолчанию эта возможность отключена, но ее легко активировать).
Не погружаясь глубоко в детали я опишу два способа с использованием CSS Grid.
Первый вариант это задание родительскому элементу кнопок свойства display: grid; и использование свойства grid-column для определения порядка вывода кнопок. В дополнение мы обеспечим попадание всех кнопок в один ряд путем прямого указания этого — grid-row: 1 .
@media screen and (min-width: 600px) < .boxes < display: grid; grid-template-columns: repeat(4, 1fr); >.boxes button < grid-row: 1; >.boxes button:nth-of-type(1) < grid-column: 4; >.boxes button:nth-of-type(2) < grid-column: 3; >.boxes button:nth-of-type(3) < grid-column: 2; >.boxes button:nth-of-type(4) < grid-column: 1; >>
Второй вариант использования CSS Grid похож на второй способ использования флексбокса. Мы зададим контейнеру свойство display: grid; , а затем используем свойство order для определения порядка вывода кнопок.
@media screen and (min-width: 600px) < .boxes < display: grid; grid-template-columns: repeat(4, 1fr); >.boxes button:nth-of-type(1) < order: 4; >.boxes button:nth-of-type(2) < order: 3; >.boxes button:nth-of-type(3) < order: 2; >.boxes button:nth-of-type(4) < order: 1; >>
Напомню, что для тестирования этого метода, вам надо активировать “Experimental Web Platform features” в Chrome.
Порядок исходников и визуальный порядок
Как было показано, мы можем использовать различные подходы CSS для смены порядка наших кнопок. Попробуем пройтись по нашим демо, используя клавиатуру (кликните на пен и нажмите клавишу Tab) для навигации по кнопкам. Вы заметите, что даже, если кнопка с номером 4 выведена первой, фокус сначала появляется на кнопке с номером 1, так как она расположена первой в DOM. То же случится, если мы протестируем наши демо со скринридером (я проводил тесты с NVDA).
Учитывая эту независимость порядка CSS от порядка DOM, нам надо быть крайне осторожными с частями страниц, порядок которых мы изменяем с помощью CSS. Например, свойство флексбокса order это один из наиболее гибких способов для переупорядочения элементов, согласно спецификации:
Авторы должны использовать order только для визуального, а не логического переупорядочивания контента. Попытка использовать order для логического порядка не сработает.
То же самое спецификация говорит о свойстве order CSS Grid.
Также как и с переупорядочиванием флекс-элементов, свойство order может использоваться только, когда визуальный порядок надо рассинхронизировать с порядком зачитывания и навигации — иначе надо менять исходники документа.
Примечание: если вы используете второй способ с флексбоксом в Firefox, то вы заметите, что навигация с клавиатуры работает отлично и фокус на средних экранах появляется сначала на кнопке №4. Такое поведение является багом.
Заключение
В этой статье мы проверили различные методы CSS для переупорядочивания элементов HTML. Конечно, не все из этих методов универсальны и перед тем, как выбрать нужный вам, вы должны учесть несколько вещей:
- Браузеры, которые вам надо поддерживать. Некоторые из перечисленных подходов не работают в старых версиях Internet Explorer (т.е. < 10).
- Степень сложности перестановки — это может быть что-то простое, как наш пример или что-то более сложное.