Что если бы вы могли построить сложный css лейаут в считанные минуты? Flexbox — это новый лейаут CSS верстки, который позволяет легко построить динамические макеты. С Flexbox выравнивание по вертикали, блоки с одинаковой высотой, перестановка и направление становится проще простого.



Есть популярный миф, что flex еще не готов к использованию. Но это не так! У 93% людей сейчас запущен браузер, поддерживающий flexbox. Это лучше, чем поддержка для HTML5.

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

Первая сторона


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

Давайте начнем с HTML.

<div class="first-face">
  <span class="pip"></span>
</div>

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



Сначала нужно сказать браузеру, что
 .firtst-face
это flexbox контейнер
.first-face {
  display: flex;
}




На вид ничего не изменилось, но под капотом поменялось многое.



Сейчас
.first-face
имеет главную ось по горизонтали. Основная ось может быть как вертикально, так и горизонтальной, но по умолчанию она горизонтальная. Если бы мы добавили еще одну точку на сторону, оно бы отображалась справа от первой. Контейнер также имеет вертикальную ось. Вспомогательная ось всегда перпендикулярна к главной оси.

Свойство
justify-content
определяет выравнивание вдоль главной оси. Поскольку мы хотим, чтобы точка выравнивалась по центру, относительной главной оси, мы будем использовать значение
center

.first-face {
  display: flex;
  justify-content: center;
}




Т.к главной осью является горизонтальная, точка теперь находится по центру родительского элемента.

Свойства
align-items
определяет, как элементы располагаются вдоль горизонтальной оси. Ведь мы хотим, чтобы точка располагалась в центру вдоль этой оси, мы будем использовать значение
center
, как и ранее.
.first-face {
  display: flex;
  justify-content: center;
  align-items: center;
}





Именно так, точка теперь в центре!

Двигаемся дальше


На второй грани кубика первая точно располагается в левом верхнем углу, а вторая — в правом нижнем. Это довольно просто сделать, используя flexbox.

И снова давайте начнем с разметки и базового css:

<div class="second-face">
  <span class="pip"></span>
  <span class="pip"></span>
</div>

.second-face {
  display: flex;
}



Теперь у нас есть две точки рядом друг с другом. На сей раз впритык, мы хотим, чтобы точки располагались на противоположных сторонах грани. Есть специально значение для
justify-content
, которое позволит нам сделать это:
space-between
.

Свойство
space-between
равномерно заполняет пространство между flex элементами. Поскольку есть только две точки, оно отталкивает их друг от друга.

.second-face {
  display: flex;
  justify-content: space-between;
}



Вот где мы столкнулись с проблемой. В отличие от предыдущего случая, мы не можем использовать
align-items
, поскольку это будет влиять на обе точки. К счастью, flexbox включает в себя
align-self
. Это свойство позволяет выравнивать отдельные элементы Flex-контейнера вдоль поперечной оси именно то, чего мы хотели! Значение, которое мы хотим установить для этого свойства- это
flex-end
.

.second-face {
  display: flex;
  justify-content: space-between;
}

.second-face .pip:nth-of-type(2) {
  align-self: flex-end;
}


Выглядит хорошо!

Горизонтальные и Вертикальные Вложенности


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

Есть две вещи в flexbox, которые спасут нас: Flex-контейнеры могут иметь контент по вертикали и горизонтали, и Flex контейнеры могут быть вложенными.

С этих пор наша разметка будет включать столбцы.

<div class="fourth-face">
  <div class="column">
    <span class="pip"></span>
    <span class="pip"></span>
  </div>
  <div class="column">
    <span class="pip"></span>
    <span class="pip"></span>
  </div>
</div>




Поскольку мы хотим, чтобы два столбца были по разные стороны баррикад, давайте двигаться и использовать
justify-content: space-between
, как мы это делали раньше.

.fourth-face {
  display: flex;
  justify-content: space-between;
}



Далее нам необходимо сделать так, чтобы столбцы стали flexbox контейнерами. Может показаться, что они уже такие, но помните, что мы еще не установили display: flex. Мы можем использовать свойство
flex-direction
, чтобы задать направление главной оси столбцу.

.fourth-face {
  display: flex;
  justify-content: space-between;
}

.fourth-face .column {
  display: flex;
  flex-direction: column;
}



С виду ничего не изменилось, но столбцы теперь flex контейнеры. Обратили внимание, как мы воткнули flex контейнер непосредственно во внутрь другого flex контейнера? Это нормально! flexbox не волнует, если контейнеры являются вложенными.

Заключительным этапом является пространство между точками внутри столбцов. Поскольку главная ось вертикальна, мы можем снова использовать
justify-content
.

.fourth-face {
  display: flex;
  justify-content: space-between;
}

.fourth-face .column {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}



Заключение


Мы создали 3 грани, и этих знаний должно хватить, чтобы сделать еще 3.

Ссылка на оригинал статьи

Комментарии (36)


  1. PatapSmile
    08.06.2015 11:16
    -6

    Укажите, что это — перевод.


    1. meam Автор
      08.06.2015 11:21
      +9

      В песочнице нельзя указать, что это перевод


  1. SelenIT2
    08.06.2015 11:18
    -1

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


    1. MaximChistov
      08.06.2015 11:29
      +2

      >топики-переводы желательно оформлять соответствующим образом
      в песочнице с этим проблемы)


      1. SelenIT2
        08.06.2015 11:32
        +1

        Признаю, но совсем проигнорировать оригинал — тоже как-то через край, имхо…


        1. meam Автор
          08.06.2015 11:36

          Я бы рад оформить, как перевод, но только могу оставить ссылку в конце статьи. Забыл сделать это при первой публикации.


        1. SelenIT2
          08.06.2015 15:23
          +3

          Прошу учитывать признание выше, прежде чем минусовать меня). На момент написания коммента ссылки на оригинал действительно не было.


  1. glagola
    08.06.2015 11:21
    +2

    Судя по can i use, на данный момент, flexbox в РФ поддерживают 85.13% (с префиксами) и 72.34% (без префикса).


    1. meam Автор
      08.06.2015 11:23

      В оригинальной статье, автор берет глобальные данные


      1. glagola
        08.06.2015 11:25
        +2

        Это не критика, а дополнение поста в контексте русских реалий.


        1. Serator
          08.06.2015 11:49

          В обоих статистиках не учитывается то, что префиксные реализации от части реализуют старые спецификации flex'ов, лишь частично совместимые с нынешним стандартом.


          1. SelenIT2
            08.06.2015 12:00

            Префиксы префиксам рознь. В Сафари (десктопных и мобильных) с префиксом поддерживается именно нынешний стандарт. Вот старые андроиды — да, понимают только свой антиквариат… но сколько их, тех старых андроидов..:)


    1. SelenIT2
      08.06.2015 11:31

      При этом доля совсем неподдерживающих (IE9- и т.п.) среди отображаемых — навскидку никак не больше 5% в сумме. Парадокс? Где же прячутся оставшиеся 10%? В той статистике непропорционально много IE6? Это архаичные браузеры симбиана?


      1. meam Автор
        08.06.2015 11:43

        Если нажать «Showing all», то можно увидеть еще мобильные браузеры


        1. SelenIT2
          08.06.2015 11:54

          А вот и таблица неучтенных браузеров (внизу). В частности, там есть Яндекс-Браузер, доля которого для России составляет целых 6% (еще 6% к тем 85%). По другим сходу проверять не стал, но в любом случае цифра 85% выходит очень сильно заниженной…


    1. SelenIT2
      08.06.2015 15:26

      С учетом не отображаемого в статистике statcounter.com (и соотв-но caniuse) Яндекс-браузера и т.п. «эндемиков» рунета, это очень заниженная оценка. Реальные цифры скорее всего ближе как минимум к 91% и 78% соответственно.


    1. Novitsky
      05.07.2015 06:16

      А подскажите, пожалуйста, где по вашей ссылке написано про Россию? Я что-то не нашел упоминания.


      1. glagola
        05.07.2015 13:23

        image


        1. Novitsky
          05.07.2015 14:38

          Странно, а у меня почему-то нет этих данных


          1. glagola
            05.07.2015 14:41

            Хороший вопрос) не нашел ни одного dropdown'a с выбором страны, видимо нужно зайти на сайт с ip из России


            1. Novitsky
              05.07.2015 15:00

              Вот я тоже не нашел.
              Захожу из России. На других сайтах Москва определяется без проблем.


  1. PragmaticProgrammer
    08.06.2015 15:29

    Спасибо автору за перевод!

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

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


    1. SelenIT2
      08.06.2015 15:57

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


      1. PragmaticProgrammer
        08.06.2015 16:21

        Да, второй вариант, пожалуй — то что нужно (со скрываемыми элементами).


        1. cmepthuk
          09.06.2015 08:09
          +1

          Посмотрите этот пост, вам должно понравиться


  1. dom1n1k
    08.06.2015 18:40
    +3

    Есть популярный миф, что flex еще не готов к использованию. Но это не так! У 93% людей сейчас запущен браузер, поддерживающий flexbox.

    А недостающие 7% — это совсем не мало.
    Многие не понимают, что в словосочетании graceful degradation ключевое слово — первое. То есть можно спокойно жертвовать укарашательствами, но каркас, основной лейаут страницы — это святое. Он должен быть железобетонный.
    Свойствами типа box-shadow можно было пользоваться даже при поддержке 50%. Но если свойство потенциально способно поломать вёрстку — надо трижды подумать.


    1. SelenIT2
      08.06.2015 22:45

      Святое — это читабельность текста и нажимабельность ссылок/кнопок. Для древних IE на убогих музейно-офисных мониторах с разрешением меньше, чем у современных мобильников, няшные глянцевожурнальные колонки — именно что украшательства. Если чистый читаемый неперекошенный текст будет скромно выводиться в одну колонку, как в мобильной версии, и это будет быстро открываться и быстро прокручитваться к заветной кнопочке «заказать» — узники юзеры такого окружения будут куда счастливее, чем после созерцания нескольких минут плясок float-ов…


      1. dom1n1k
        08.06.2015 23:05

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


        1. SelenIT2
          08.06.2015 23:57

          А с чего бы нормальным аккуратным блокам в логичном порядке без лютых отрицательных отступов и т.п. хаков вдруг превратиться в нередсказуемое месиво только от того, что колонка стала одна?

          Сами менюшки и т.п., кстати, в тех же старых IE могут работать еще и не хуже:)


    1. TiGR
      08.06.2015 23:03

      В ряде ситуаций можно сделать вполне graceful degradation при помощи modernizr и display: table-cell и подобных трюков.


      1. dom1n1k
        08.06.2015 23:11
        +1

        То есть поддерживать 2 параллельные версии верстки? Оно-то можно, но смысл? Я лучше одну, пусть и не самую передовую с точки зрения новых стандартов. (Поймите правильно — я не говорю, что флексбокс не нужен вообще. Но я применяю его не очень часто и с осторожностью).

        Что же касается модернайзера, то я придерживась мнения, что опять-таки, когда речь идет о критичной части верстки (лейауте) — недопустимо завязывать его на JS. Все должно работать на голом CSS. Дополнительные рюшечки, вторичные функции — да, пожалуйста.
        Оговорка — речь идет именно о сайтах, web apps — конечно, отдельная песня, там от JS никуда не денешься.


        1. TiGR
          09.06.2015 09:30
          +1

          Пользователей без JS в 2015 году пренебрежительно мало, гораздо меньше, чем пользователей без flexbox (сильно меньше одного процента) — по моим сайтам где-то 0,1%. Даже Opera Mini на устройствах Symbian поддерживает JS в нужном объёме для работы modernizr. А большинству, кто его не поддерживает (то есть роботам) как-то фиолетово на вёрстку. Нужно понимать, что с годами этот процент значительно уменьшился по мере роста числа пользователей интернет и развития технологий безопасности в браузерах, так что отключение JS стало почти лишено смысла даже для людей, беспокоящихся о безопасности.

          А если пользователь в 2015 году отключает JS, то он ССЗБ и знает на что идёт. А если у человека паранойя, то нужно лечиться, а не потворствовать заболеванию, отключая JS.


          1. dom1n1k
            09.06.2015 13:50

            Вот жаль что-то не могу найти, но сравнительно недавно тут была отличная статья, почему может не быть JS. И там было перечислено гораздо больше вариантов, чем один только ссзб.
            Самое банальное — он может быть, но с большим лагом.


          1. dom1n1k
            09.06.2015 16:53

            Во, нагуглил: frontender.info/everyone-has-js
            Мне казалось, что статья была на самом Хабре, но она тут только упоминалась в одном из дайджестов.


            1. TiGR
              09.06.2015 19:02

              Вопрос тут не в том, что может вызывать это. А в том, каков процент посетителей, реально с этим сталкивающимися? Часть того, что там упоминается относится также и к CSS. Не использовать CSS? Или делать вёрстку опираясь на то, чтобы она и без CSS была нормально рабочей? Или встраивать базовый CSS в страницу?

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


              1. dom1n1k
                09.06.2015 19:11
                +1

                Понятно, что проблема в сети. И понятно, что решить её на 100% не в наших силах.
                Но стремиться сгладить её насколько это возможно — можно и нужно.