Пока все активно делятся своими впечатлениями от 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!
Комментарии (33)
vantoose
21.06.2017 09:29+2После вашей статьи прочел вот эту https://habrahabr.ru/company/microsoft/blog/140715/
Может кому тоже интересно будет.SelenIT3
24.06.2017 19:49+1Возможно, хорошим свежим дополнением будет и это: http://css-live.ru/css/bolshaya-statya-pro-gridy-css-grid-layout.html
khim
21.06.2017 12:32+5Круто! Ещё лет 10-15 и мы, наконец, получим то, что в TeX'е было 35 лет назад.
Правда TeX не был интерактивным, так что кой-какие решения оттуда в CSS не перенести, но всё равно — поздравляю с оберетниемfil
'а! Интересно когда добавятfill
?
AngReload
21.06.2017 16:29+3У кого-нибудь кроме меня есть полосы прокрутки во фреймах CodePen?
Я посмотрел, откуда они появляются и написал userstyle чтобы убрать их.
@-moz-document domain("codepen.io") { #output:hover .background-image { transform: none; } body { font-size: 0; } }
gprokofyeva
21.06.2017 17:04Только в первых двух. Как и сказано в статье, они вызваны переполнением грида.
gprokofyeva
21.06.2017 17:07Или Вы о вертикальной прокрутке?
AngReload
21.06.2017 17:22+2Вот об этом:
Также на начально экране Run Pen (с шестеренками), при наведении (в firefox) или при убирании курсора во время анимации (chrome).
Сомневаюсь что это у всех есть: разработчики в этом случае CodePen это давно бы исправили.
AngReload
21.06.2017 20:45+1Прошу прощения, если кто использовал код выше.
Рекомендую заменить селекторы на уникальные:
@-moz-document domain("codepen.io") { #the-body > #output:hover > .background-image { transform: none; } .codepen-embed-body { font-size: 0; } }
SuperKozel
21.06.2017 19:40народ, а есть вообще какие-то сайты, где, ну скажем, очень хорошая верстка/дизайн на лезвии. А то вроде на хабре почитаешь, какие все крутые, про новые подходы. Вот тут, мол, мы все давно уже используем display:grid. А я такого сайта еще в жизни не видел, где используется. ну не видел, я когда мне что-то интересно на сайте, сразу лезу в дебаг панель, код смотреть. Ииии… нет, не видел.
Какими веб-проектами заняты лучшие умы?gprokofyeva
22.06.2017 00:16В этой статье разбираются примеры использования современных техник (можно прямо на их же сайте сам код посмотреть): Css Grid, CSS 3D, Web Animations API.
bro-dev
22.06.2017 07:49Хорошая верстка это не значит на лезвии. Я не консервативен но все равно всё новшества воспринимаю очень осторожно.
gzhegow
22.06.2017 02:32Когда-нибудь вы просиживая штаны на хабре наконец изобретете сервис который будет в автоматическом режиме доказывать директорам предприятий, что современность важнее покрытия устройств, и тогда всем будет счастье.
А пока оно «начинает поддерживаться все лучше и лучше» это тоже самое как продолжать использовать бутстрап, понимая, что его в принципе нельзя использовать в готовом уже сверстанном говнокодером проекте, ведь от стандарта там нет даже букв «ст», а постепенно повышающаяся поддерживаемость это как в той истории, где 20% андроидов упало сразу, 40% юзеров сидели на ИЕ, а начальник пользовался айфоном и остался недоволен.
пс. пока для СЕО оптимизации нужно писать функцию «mk_ahref» на 50 строк кода, а перелинковка требует специалиста за пару косарей — это все бултыхание в лягушатнике.Finesse
22.06.2017 04:59+1Расскажите, пожалуйста, как современность в вёрстке позволяет получить больше прибыли по сравнению с вёрсткой с большим покрытием.
nullc0de
22.06.2017 06:12Честно не понял, что он имел ввиду. Но если говорить про технологии, то современные технологии могут дать лучшую адаптивность и переносимость дизайна сайта с устройства на устройства, повысить интерактивность и обеспечить более комфортное чтение, что очень важно, так как рынок мобильных устройств быстро растет. Еще старые технологии могут замедлять отрисовку страницы. По этой же причине, считаю нужно разделять отдельно стили для современных устройств и делать отдельную версию сайта для совсем старых браузеров. Слава богу легаси браузеров сейчас не так много и ими можно пожертвовать, и можно использовать calc, vw, flexbox. А вот с display: grid и fr не все так гладко, поддерживают всего 70% браузеров, 1/3 рынка просто так не выкинишь, это реальное самоубийство для бизнеса… хотя сами технологии очень сладкие для разработчика…
Finesse
22.06.2017 07:01Адаптивные сайты можно спокойно делать уже очень давно, к тому же технология, с помощью которой делается адаптивность (CSS-media-запроы), обратно-совместима с браузерами, которые её не поддерживают.
Еще старые технологии могут замедлять отрисовку страницы
Можно пример?
nullc0de
22.06.2017 07:08Одними медиа запросами сыт не будешь… Сейчас довольно сложные динамически обновляемые сайты… Да и можно сократить медиа запросы и размер css, при помощи новых технологий… Читайте на здоровье https://developers.google.com/web/fundamentals/performance/rendering/
Там например есть классический пример пример flexbox против float + %. И замедление может быть еще больше в этой связке, зависит от DOM и других стилей. Но еще конечно не правильное использование новых технологий, тоже может замедлить отрисовку. Но в этом виноват только разработчик, который не читает стандарты и рекомендации.gzhegow
22.06.2017 09:31Как по мне — сначала создали сложные динамически обновляемые сайты, потом офигели от медиазапросов, ну короче стандартизатор забухал.
В вебе постоянно такое — только стандартизатор водки, все программисты тут же начинают изобретать новую вещь, которая заставляет забыть все что было раньше. Обычно в лабораториях используют старые знания, но только не программисты.nullc0de
22.06.2017 10:09Люди начинают пихать где попало и где не нужно, не понимая сам процесс происходящего и почему был принят сам стандарт… Старые технологии где-то имеют выигрыш, всегда надо четко понимать где это применимо, а где наоборот вредно… Тоже выравние по центру дива, можно сделать многими способами: через марджин, транслейт, флексбокс и у всех есть свои плюсы и минусы, и области применения…
khim
22.06.2017 13:07А вот с display: grid и fr не все так гладко, поддерживают всего 70% браузеров, 1/3 рынка просто так не выкинишь, это реальное самоубийство для бизнеса…
Зависит от бизнеса, на самом деле. Если у вас сайт — приложение к оффлановому бизнесу и важно покрыть всех клиентов, то выкинуть 30% пользователей — самоубийство, если же они к вам именно из браузера и должны приходить, то увеличив удержание в два раза вы легко это 30% «потерянных» закроете.
Но, понятно, такие вещи бизнес должен решать, не разработчик…
SelenIT3
24.06.2017 19:47+1Не надо никого выкидывать, новинки можно добавлять понемногу в порядке Progressive Enhancement. Например, динозаврам можно выводить карточки товаров или превьюшки в галерее флоатами или инлайн-блоками (скучно по по левому краю, но ничего не развалится, ни один ослик не пострадает), а новым браузерам выровнять эти же карточки по красивой адаптивной сетке как-нибудь так.
С гридами нам повезло еще и в том, что все браузеры, поддерживающие их, поддерживают и
supports()
, так что легко применять стили для новых улучшений только там, где нужно (как учит на личном примере легендарный Эрик Мейер:).
japan007
22.06.2017 14:00а как у этого дела с кроссбраузерностью?
gprokofyeva
22.06.2017 14:14
gprokofyeva
22.06.2017 18:02В этой статье разбираются примеры использования современных техник (можно прямо на их же сайте сам код посмотреть): Css Grid, CSS 3D, Web Animations API.
Если посмотреть их сайт, голубой фон вверху страницы сделан через грид с использованиемfr
. Еще должны быть примеры у них, можно поискать. Сравнивала этот фон в разных браузерах, включая последний IE и Edge, отображается нормально.
SelenIT3
24.06.2017 19:36+2о новой единице длины в CSS — fr (см. спецификацию).
В этой фразе автор оригинала несколько поторопился: спецификация по ссылке определяет
fr
не как единицу длины, а как единицу новой размерности CSS — "гибкой длины" (в идеале,flex
во флексбоксах тоже должен был быть этой же размерностью, но "хорошая мысля приходит опосля":). Поэтому единицаfr
имеет смысл только в контексте гридов, и ее нельзя комбинировать с единицами длины вcalc()
. Возможно, нюанс достаточно тонкий, но я уже видел, как люди на этом спотыкались, так что лучше сразу внести ясность.
hamMElion