Пока все активно делятся своими впечатлениями от CSS-гридов, я не слышал, чтобы кто-то столь же много говорил о новой единице длины в CSS — fr (см. спецификацию). И теперь, когда браузеры все лучше начинают поддерживать ее, я думаю, пора взглянуть на то, как ее можно использовать в сочетании с этой техникой вёрстки, поскольку это дает нам ряд преимуществ. Главные из них — это более понятный и удобный в сопровождении код.
Прежде чем мы начнём, давайте посмотрим, как мы обычно создаём гриды в CSS. В приведенном ниже примере мы создаем грид из четырёх столбцов с одинаковой шириной:
<div class="grid">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
.grid {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-column-gap: 10px;
}
Если вы никогда не использовали функцию repeat() в качестве значения свойства grid-template-columns, позвольте представить вам одну из самых изящных фич CSS-грида! Это краткая запись. По сути, она позволяет нам более кратко описывать повторяющиеся значения. Вместо этого мы могли бы написать grid-template-columns: 25% 25% 25% 25%;, но удобнее использовать repeat(), особенно когда вы определяете ширину через довольно длинное выражение minmax().
Синтаксис выглядит следующим образом:
repeat(количество столбцов/строк, нужная нам ширина столбца);
Но, на самом деле, здесь есть пара проблем.
Во-первых, для использования этой функции CSS, нам нужно было провести небольшой расчёт. Нам пришлось подсчитать, сколько мы получим, если общую ширину грида (100%) разделим на нужное число столбцов (4). Мы получили 25%. В этом примере расчёт довольно прост и не создает проблем, но и в более сложных примерах мы можем полностью избежать необходимости что-то рассчитывать и позволить браузеру сделать это за нас. У нас есть функция calc(), так что мы могли бы написать следующее: repeat(4, calc(100% / 4), но даже это немного странно, и в любом случае здесь есть еще одна проблема…
Вторая проблема связана с переполнением. Так как мы установили для каждого столбца ширину в 25% и задали grid-column-gap в 10px, весь грид становится шире 100%. Не этого ожидаешь, набирая выше приведённый код, но именно так работают процентные значения. На самом деле, мы здесь как бы говорим: «нужно установить для каждого столбца значение 25% от ширины области просмотра и расстояние в 10px между ними». Это немногим отличается от наших ожиданий, но вызывает большую проблему с вёрсткой.
Ненароком мы создали горизонтальную прокрутку:
И именно здесь нам поможет единица fr.
Единица fr («дробная часть») может использоваться при создании гридов так же, как любая другая единица длины в CSS, как %, px или em. Давайте подредактируем наш код и попробуем задать новое значение:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
}
Результат будет таким же, как и в приведённом ранее примере, так как в данном случае мы задаём каждому из четырех столбцов ширину, равную одной дробной части (которая составляет 1/4 или 25%). Но! Мы избавились от переполнения на оси x, так как если мы определяем для каждого столбца ширину, равную 1fr, эти 10px учитываются автоматически и вычитаются из конечной ширины столбца.
Вы наверно, недоумеваете, почему, чёрт возьми, нужно учиться использовать эту новую единицу CSS, если можно обойтись процентами или пикселями? Что ж, давайте рассмотрим более сложный пример CSS-грида и выясним, почему использование fr это все же лучший вариант. В новом примере предположим, что мы хотим, чтобы после блока навигации слева располагался грид из двенадцати столбцов, который выглядел бы следующим образом:
Это довольно типичная практика для многих UI. Использование fr в таких случаях избавляет нас от необходимости создавать отдельный грид или возиться с расчётами через calc(). Ведь если бы мы не прибегли к fr в приведённом выше примере, нам бы пришлось выполнить следующий расчёт:
ширина каждого столбца = ((ширина видимой области — ширина панели навигации)/число столбцов) * 1%
Это, конечно, можно было бы провернуть, но на это даже смотреть сложно без слёз. Кроме того, если бы нам нужно было изменить ширину блока навигации, то пришлось бы снова проводить подобный расчёт. Вместо этого fr предлагает нам крайне приятный глазу и максимально понятный код:
.grid {
display: grid;
grid-template-columns: 250px repeat(12, 1fr);
grid-column-gap: 10px;
}
Здесь мы задаём первому столбцу фиксированную ширину в пикселях, а затем создаем ещё 12 отдельных столбцов. Для каждого из них определяется ширина в одну «дробную часть свободного пространства» (дословная формулировка в спецификации). Но теперь нет нужды в безумных расчётах! Код достаточно понятный, и если мы изменим ширину левого блока навигации, ширина столбцов справа скорректируется автоматически.
Нам не пришлось тратить много сил и времени на то, чтобы сделать наш интерфейс более удобным в сопровождении. Также мы сделали наш код более понятным для будущих разработчиков, которых ещё ждёт много другой работы.
Чем делятся наши коллеги
Хорошего результата можно добиться, используя fr вместе с другими единицами длины. Представьте фиксированный сайдбар и основную область контента, которая занимает оставшуюся часть пространства: grid-template-columns: 200px 1fr;. Легко!
Вот хороший пример использования нескольких единиц с Alligator.io:
.container {
/* ... */
grid-template-columns: 1fr 1fr 40px 2fr;
grid-template-rows: 100px 200px 100px;
/* ... */
}
Рэйчел Эндрю делится видео о единице fr:
Анна Монус предлагает замечательную статью об этой единице:
«Вы можете использовать единицу fr также вместе с другими единицами длины CSS. В примере ниже я использовала для моего грида соотношение 60% 1fr 2fr».
Да здравствует единица fr!
Автор: gprokofyeva