Главная » Статьи » Достижение вертикального выравнивания

Достижение вертикального выравнивания

Достижение вертикального выравнивания

От автора: инструменты для вертикального выравнивания в последнее время стали намного лучше. В первые годы работы в качестве дизайнера веб-сайтов я разрабатывал дизайн домашней страницы шириной 960 пикселей и выравнивал элементы по горизонтали на странице с помощью сетки из 12 столбцов. Появились медиа-запросы, которые потребовали серьезного психологического сдвига. Конечно, они решили некоторые значительные проблемы, но представили новые, например, работу с выравниванием, когда элементы переносятся или иным образом перемещаются в макете.

Давайте рассмотрим только один конкретный сценарий: «панель» с некоторыми кнопками на ней. Есть две группы этих кнопок, каждая из которых содержится внутри fieldset с legend. На большом экране все хорошо:

Достижение вертикального выравнивания

А вот очень простой метод CSS, который реализует этот макет, а также разбивает на две «строки» в мобильной контрольной точке:

.accessibility-tools fieldset { width: 48%; float: left; margin-right: 1%;
}


/* Mobile */
@media only screen and (max-width: 480px) { .accessibility-tools fieldset { width: 100%; }
}

На маленьком экране мы получаем следующее:

Достижение вертикального выравнивания

В этом проблема: отсутствие вертикального выравнивания. Предположим, мы хотим выровнять эти кнопки так, чтобы их края совпадали друг с другом.

Для начала мы могли бы использовать решения CSS с фиксированной шириной на основе пикселей, чтобы заставить элементы правильно выстраиваться в различных контрольных точках, используя такие магические числа:

/* Mobile */
@media only screen and (max-width: 480px) { legend { width: 160px; } button { width: 130px; }
}

Достижение вертикального выравнивания

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

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

Доступное пространство

Проблема с использованием медиа-запросов заключается в том, что они не принимают во внимание пространство вокруг элементов, которые выравниваются — это прекрасно продемонстрировано на этом изображении из «Священного альбатроса Flexbox» Хейдона Пикеринга:

Достижение вертикального выравнивания

Я действительно хочу, чтобы второй fieldset переносился под первый только тогда, когда он больше не может аккуратно умещаться в одном ряду.

Можем ли мы сделать это с помощью flexbox?

Ключевым преимуществом flexbox является его способность создавать элементы, которые реагируют на пространство вокруг них. Компоненты могут «растягиваться», чтобы заполнить дополнительное пространство, и сжиматься, чтобы поместиться в меньшее пространство.

В этой ситуации для свойства flex-wrap установлено значение wrap. Это означает, что только когда оба элемента fieldset больше не помещаются в одну строку, они будут перенесены на вторую строку.

.wrapper--accessibility-tools { display: flex; flex-wrap: wrap;
}

Свойство flex-wrap имеет три доступных значений. Значение по умолчанию — nowrap, оставлять элементы в одной строке. Значение wrap позволяет элементам переноситься на несколько строк. Затем есть wrap-reverse, что позволяет элементам переноситься, но — подождите — в обратном порядке (это странно: когда элементы переносятся, они помещаются над предыдущей строкой).

Использование flexbox позволяет макету не быть таким жестким, но значение min-width по-прежнему необходимо для устранения проблемы вертикального выравнивания. Итак: близко, но не совсем то.

Может ли сетка нам помочь?

CSS Grid — это самый первый модуль CSS, созданный специально для решения текущих проблем макета, с которыми сталкиваются веб-дизайнеры и разработчики. Это не прямая замена flexbox; скорее два модуля обычно очень хорошо работают вместе.

Как и flexbox, сетка может использоваться, чтобы каждый

мог занимать столько места, сколько ему нужно. Мы можем использовать ключевые слова auto-fill и auto-fit (в пределах функции repeat()) для того, чтобы элементы сетки распределялись на несколько строк без необходимости медиа-запросов. Используем auto-fit:

.wrapper--accessibility-tools { display: grid; grid-template-columns: repeat(auto-fit, 450px); grid-gap: 10px;
}

Как и в примере с флекс-бокс, мне все еще нужно установить абсолютное значение для ширины метки, чтобы выравнивать элементы fieldset по мере их укладки.

Другой подход с сеткой

CSS Grid также позволяет элементам реагировать на их содержимое с помощью гибких треков сетки. В дополнение к другим значениям длины, таким как проценты, относительные единицы или пиксели, CSS Grid принимает дробные единицы (fr), 1fr занимает одну часть доступного пространства, 2fr занимает две части доступного пространства и так далее. Создадим здесь две равных колонки:

.wrapper--accessibility-tools { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 10px;
}

Также есть функция minmax(), создающая треки сетки, которые растягиваются в доступном пространстве, но не сжимаются меньше указанного размера.

.wrapper--accessibility-tools { display: grid; grid-template-columns: minmax(auto, max-content) minmax(auto, max-content); grid-gap: 10px;
}

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

Достижение вертикального выравнивания

Это происходит потому, что при добавлении в контейнер display: grid только прямые дочерние элементы этого контейнера становятся элементами сетки. Это означает, что используемые нами внутренние единицы измерения размеров относятся только к элементам в одной сетке.

Использование подсетки

Чтобы действительно достичь моей цели, мне нужно, чтобы кнопки и метки реагировали на элементы в контейнерах родственной сетки. CSS Grid Level 2 включает функцию подсетки. Хотя мы всегда могли вкладывать сетки, элементы в каждом контейнере сетки были независимыми. С помощью subgrid мы можем настроить вложенные (дочерние) сетки, которые используют треки родительских сеток.

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

Достижение вертикального выравнивания

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

Достижение вертикального выравнивания

Каждая карта в этом примере по-прежнему охватывает три трека рядов, но эти ряды теперь определены в родительской сетке, что позволяет каждой карточке занимать одинаковое количество вертикального пространства.

В примере, с которым мы работали, нам не нужно использовать ряды. Вместо этого нам нужно изменить размер колонок в зависимости от содержимого смежных сеток. Во-первых, давайте установим родительскую сетку, чтобы она содержала два элемента fieldset. Это похоже на код, который мы ранее рассматривали в демонстрации auto-fit.

.wrapper--accessibility-tools { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); grid-gap: 10px;
}

Затем мы размещаем каждую подсетку в родительской сетке.

.sub-grid { display: grid; grid-column: span 3; grid-template-columns: subgrid; align-items: center;
}

Достижение вертикального выравнивания

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

Достижение вертикального выравнивания

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

Достижение вертикального выравнивания

Достижение вертикального выравнивания

Совместимость с браузерами

Поддержка подсеток на момент написания не очень велика. Они поддерживаются только в Firefox 71+, хотя есть положительные сигналы от других браузеров. Запросы функций CSS могут использоваться для предоставления альтернативного стиля в Chrome и Edge.

Эти данные о поддержке браузерами взяты с Caniuse, где есть более подробная информация. Число означает, что браузер поддерживает эту функцию в этой версии и выше.

Достижение вертикального выравнивания

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

<fieldset class="accessibility-tools__colour-theme"> <div class="wrapper"></div>
</fieldset>

Макет CSS применяется к оболочке с набором полей с установленным display: contents.

.accessibility-tools fieldset { display: contents; border: 0;
}

Автор: Cathy Dutton

Источник: css-tricks.com

Редакция: Команда webformyself.