Пока все активно делятся своими впечатлениями от 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)


  1. hamMElion
    21.06.2017 09:09
    +42


  1. vantoose
    21.06.2017 09:29
    +2

    После вашей статьи прочел вот эту https://habrahabr.ru/company/microsoft/blog/140715/
    Может кому тоже интересно будет.


    1. SelenIT3
      24.06.2017 19:49
      +1

      Возможно, хорошим свежим дополнением будет и это: http://css-live.ru/css/bolshaya-statya-pro-gridy-css-grid-layout.html


  1. pingvin0day
    21.06.2017 11:49

    Очень познавательно, благодарю!


    1. gprokofyeva
      21.06.2017 12:15

      Всегда пожалуйста!


  1. khim
    21.06.2017 12:32
    +5

    Круто! Ещё лет 10-15 и мы, наконец, получим то, что в TeX'е было 35 лет назад.

    Правда TeX не был интерактивным, так что кой-какие решения оттуда в CSS не перенести, но всё равно — поздравляю с оберетнием fil'а! Интересно когда добавят fill?


  1. AngReload
    21.06.2017 16:29
    +3

    У кого-нибудь кроме меня есть полосы прокрутки во фреймах CodePen?
    Я посмотрел, откуда они появляются и написал userstyle чтобы убрать их.


    @-moz-document domain("codepen.io") {
        #output:hover .background-image {
            transform: none;
        }
    
        body {
            font-size: 0;
        }
    }


    1. gprokofyeva
      21.06.2017 17:04

      Только в первых двух. Как и сказано в статье, они вызваны переполнением грида.


    1. gprokofyeva
      21.06.2017 17:07

      Или Вы о вертикальной прокрутке?


      1. AngReload
        21.06.2017 17:22
        +2

        Вот об этом:

        Также на начально экране Run Pen (с шестеренками), при наведении (в firefox) или при убирании курсора во время анимации (chrome).
        Сомневаюсь что это у всех есть: разработчики в этом случае CodePen это давно бы исправили.


        1. hdfan2
          22.06.2017 07:28

          Да, есть во всех трёх. Win, FF 54.


    1. 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;
          }
      }


  1. SuperKozel
    21.06.2017 19:40

    народ, а есть вообще какие-то сайты, где, ну скажем, очень хорошая верстка/дизайн на лезвии. А то вроде на хабре почитаешь, какие все крутые, про новые подходы. Вот тут, мол, мы все давно уже используем display:grid. А я такого сайта еще в жизни не видел, где используется. ну не видел, я когда мне что-то интересно на сайте, сразу лезу в дебаг панель, код смотреть. Ииии… нет, не видел.
    Какими веб-проектами заняты лучшие умы?


    1. gprokofyeva
      21.06.2017 20:03

      Я вот здесь посматриваю, чем заняты лучшие фронтенд-разработчики.


    1. gprokofyeva
      22.06.2017 00:16

      В этой статье разбираются примеры использования современных техник (можно прямо на их же сайте сам код посмотреть): Css Grid, CSS 3D, Web Animations API.


    1. bro-dev
      22.06.2017 07:49

      Хорошая верстка это не значит на лезвии. Я не консервативен но все равно всё новшества воспринимаю очень осторожно.


  1. gzhegow
    22.06.2017 02:32

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

    А пока оно «начинает поддерживаться все лучше и лучше» это тоже самое как продолжать использовать бутстрап, понимая, что его в принципе нельзя использовать в готовом уже сверстанном говнокодером проекте, ведь от стандарта там нет даже букв «ст», а постепенно повышающаяся поддерживаемость это как в той истории, где 20% андроидов упало сразу, 40% юзеров сидели на ИЕ, а начальник пользовался айфоном и остался недоволен.

    пс. пока для СЕО оптимизации нужно писать функцию «mk_ahref» на 50 строк кода, а перелинковка требует специалиста за пару косарей — это все бултыхание в лягушатнике.


    1. Finesse
      22.06.2017 04:59
      +1

      Расскажите, пожалуйста, как современность в вёрстке позволяет получить больше прибыли по сравнению с вёрсткой с большим покрытием.


      1. nullc0de
        22.06.2017 06:12

        Честно не понял, что он имел ввиду. Но если говорить про технологии, то современные технологии могут дать лучшую адаптивность и переносимость дизайна сайта с устройства на устройства, повысить интерактивность и обеспечить более комфортное чтение, что очень важно, так как рынок мобильных устройств быстро растет. Еще старые технологии могут замедлять отрисовку страницы. По этой же причине, считаю нужно разделять отдельно стили для современных устройств и делать отдельную версию сайта для совсем старых браузеров. Слава богу легаси браузеров сейчас не так много и ими можно пожертвовать, и можно использовать calc, vw, flexbox. А вот с display: grid и fr не все так гладко, поддерживают всего 70% браузеров, 1/3 рынка просто так не выкинишь, это реальное самоубийство для бизнеса… хотя сами технологии очень сладкие для разработчика…


        1. Finesse
          22.06.2017 07:01

          Адаптивные сайты можно спокойно делать уже очень давно, к тому же технология, с помощью которой делается адаптивность (CSS-media-запроы), обратно-совместима с браузерами, которые её не поддерживают.


          Еще старые технологии могут замедлять отрисовку страницы

          Можно пример?


          1. nullc0de
            22.06.2017 07:08

            Одними медиа запросами сыт не будешь… Сейчас довольно сложные динамически обновляемые сайты… Да и можно сократить медиа запросы и размер css, при помощи новых технологий… Читайте на здоровье https://developers.google.com/web/fundamentals/performance/rendering/
            Там например есть классический пример пример flexbox против float + %. И замедление может быть еще больше в этой связке, зависит от DOM и других стилей. Но еще конечно не правильное использование новых технологий, тоже может замедлить отрисовку. Но в этом виноват только разработчик, который не читает стандарты и рекомендации.


            1. gzhegow
              22.06.2017 09:31

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

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


              1. nullc0de
                22.06.2017 10:09

                Люди начинают пихать где попало и где не нужно, не понимая сам процесс происходящего и почему был принят сам стандарт… Старые технологии где-то имеют выигрыш, всегда надо четко понимать где это применимо, а где наоборот вредно… Тоже выравние по центру дива, можно сделать многими способами: через марджин, транслейт, флексбокс и у всех есть свои плюсы и минусы, и области применения…


        1. khim
          22.06.2017 13:07

          А вот с display: grid и fr не все так гладко, поддерживают всего 70% браузеров, 1/3 рынка просто так не выкинишь, это реальное самоубийство для бизнеса…
          Зависит от бизнеса, на самом деле. Если у вас сайт — приложение к оффлановому бизнесу и важно покрыть всех клиентов, то выкинуть 30% пользователей — самоубийство, если же они к вам именно из браузера и должны приходить, то увеличив удержание в два раза вы легко это 30% «потерянных» закроете.

          Но, понятно, такие вещи бизнес должен решать, не разработчик…


        1. SelenIT3
          24.06.2017 19:47
          +1

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


          С гридами нам повезло еще и в том, что все браузеры, поддерживающие их, поддерживают и supports(), так что легко применять стили для новых улучшений только там, где нужно (как учит на личном примере легендарный Эрик Мейер:).


  1. japan007
    22.06.2017 14:00

    а как у этого дела с кроссбраузерностью?


    1. gprokofyeva
      22.06.2017 14:14

      Вот здесь можно посмотреть. Работает только вместе с CSS Grid. В Edge и IE под частичной поддержкой гридов подразумевается то, что поддерживается старая версия спецификации, но в ней можно найти примеры использования fr, так что должно поддерживаться.


    1. gprokofyeva
      22.06.2017 18:02

      В этой статье разбираются примеры использования современных техник (можно прямо на их же сайте сам код посмотреть): Css Grid, CSS 3D, Web Animations API.

      Если посмотреть их сайт, голубой фон вверху страницы сделан через грид с использованием fr. Еще должны быть примеры у них, можно поискать. Сравнивала этот фон в разных браузерах, включая последний IE и Edge, отображается нормально.


      1. japan007
        23.06.2017 11:28

        Global 63.92% + 5.39% = 69.3%

        печальненько


        1. SelenIT3
          24.06.2017 20:03
          +3

          Всего три месяца назад было 0.0%. Мало какая новинка показывала такой темп проникновения:)


  1. SelenIT3
    24.06.2017 19:36
    +2

    о новой единице длины в CSS — fr (см. спецификацию).

    В этой фразе автор оригинала несколько поторопился: спецификация по ссылке определяет fr не как единицу длины, а как единицу новой размерности CSS — "гибкой длины" (в идеале, flex во флексбоксах тоже должен был быть этой же размерностью, но "хорошая мысля приходит опосля":). Поэтому единица fr имеет смысл только в контексте гридов, и ее нельзя комбинировать с единицами длины в calc(). Возможно, нюанс достаточно тонкий, но я уже видел, как люди на этом спотыкались, так что лучше сразу внести ясность.


  1. glebsky
    28.06.2017 08:40

    Интересная статья. Спасибо


    1. gprokofyeva
      28.06.2017 08:40

      Всегда пожалуйста!