image

Примечание: этот материал представляет собой свободный перевод статьи Джереми Томаса о том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.

Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian.

Причина, по которой автор использует Flexbox – это большое количество возможностей, которые он предоставляет:
— легкость в создании адаптивных столбцов;
— создание столбцов одинаковой высоты;
— возможность прижатия содержимого к низу контейнера.

Ну, поехали!

1. Начинаем с создания двух столбцов


Создание столбцов при помощи CSS всегда влекло за собой определенные трудности. На протяжении длительного времени для выполнения данной задачи широко использовались (и используются) float’ы и / или таблицы, но каждый из этих методов имел (и имеет) свои недостатки.

В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:

— написание более «чистого» кода: от нас лишь требуется создать контейнер с правилом display: flex;
— гибкость: мы можем изменять размер, растягивать и выравнивать столбцы путем изменения пары строк CSS;
— семантическая разметка;
— кроме того, с использованием Flexbox отпадает необходимость отменять обтекание во избежание непредсказуемого поведения лейаута.

Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один — 1/3 его часть.

<div class="columns">
  <div class="column main-column">
    2/3 column
  </div>
  <div class="column">
    1/3 column
  </div>
</div>

Здесь присутствуют два элемента:

— контейнер columns;
— два дочерних элемента column, один из которых имеет дополнительный класс main-column, который мы используем позже для того, чтобы сделать столбец шире.

.columns {
  display: flex;
}

.column {
  flex: 1;
}

.main-column {
  flex: 2;
}

Поскольку main-column имеет значение flex равное 2, то этот столбец займет в два раза больше места, чем второй.

Добавим немного визуального оформления и, в итоге, получим:

image
Кликните для просмотра в действии

2. Делаем каждый столбец flexbox-контейнером


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

Итак, нам необходимо, чтобы статьи:

— располагались вертикально внутри столбца-контейнера;
— занимали все доступное место.

Правило flex-direction: column, указанное для контейнера, вместе с правилом flex: 1, указанным для дочернего элемента, позволяет статье заполнить все свободное место по вертикали, при этом высота первых двух столбцов останется неизменной.

image
Кликните для просмотра в действии

3. Делаем контейнер из статьи


Теперь, чтобы еще больше расширить наши возможности, давайте представим каждую статью в виде flexbox-контейнера. Каждый такой контейнер будет содержать:

— заголовок;
— параграф;
— информационную панель с именем автора и количеством комментариев;
— какую-нибудь адаптивную картинку.

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

image

А вот и сам код:

<a class="article first-article">
  <figure class="article-image">
    <img src="">
  </figure>
  <div class="article-body">
    <h2 class="article-title">
      <!-- Заголовок -->
    </h2>
    <p class="article-content">
      <!-- Контент -->
    </p>
    <footer class="article-info">
      <!-- Информация -->
    </footer>
  </div>
</a>

.article {
  display: flex;
  flex-direction: column;
  flex-basis: auto; /* Устанавливает начальный размер элемента в зависимости от его содержимого */
}
 
.article-body {
  display: flex;
  flex: 1;
  flex-direction: column;
}
 
.article-content {
  flex: 1; /* Содержимое заполняет все оставшееся место, тем самым прижимая информационную панель к нижней части */
}

Элементы внутри статьи расположены вертикально благодаря использованию правила flex-direction: column.

Также мы применили свойство flex: 1 к элементу article-content, тем самым растянув его на все свободное место и прижав article-info к низу. Высота столбцов в этом случае не имеет значения.

image
Кликните для просмотра в действии

4. Добавляем несколько вложенных столбцов


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

<div class="columns">
  <div class="column nested-column">
    <a class="article">
      <!-- Содержимое статьи -->
    </a>
  </div>
 
  <div class="column">
    <a class="article">
      <!-- Содержимое статьи -->
    </a>
    <a class="article">
      <!-- Содержимое статьи -->
    </a>
    <a class="article">
      <!-- Содержимое статьи -->
    </a>
  </div>
</div>

Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс nested-column, а в CSS укажем:

.nested-column {
  flex: 2;
}

Теперь этот столбец будет вдвое шире второго.

image
Кликните для просмотра в действии

5. Делаем первую статью с горизонтальным лейаутом


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

.first-article {
  flex-direction: row;
}
 
.first-article .article-body {
  flex: 1;
}
 
.first-article .article-image {
  height: 300px;
  order: 2;
  padding-top: 0;
  width: 400px;
}

Свойство order в данном случае играет большую роль, поскольку оно позволяет изменять очередность HTML-элементов без изменения HTML-разметки. В действительности, article-image в коде идет перед элементом article-body, но ведет себя так, будто стоит после него.

image
Кликните для просмотра в действии

6. Делаем адаптивный лейаут


Теперь все выглядит так, как мы хотели, хотя и немного сплющено. Давайте исправим это, добавив нашему лейауту гибкости.

Одной из замечательных вещей в Flexbox является то, что достаточно удалить правило display: flex в контейнере для того, чтобы полостью отключить его (Flexbox), в то время, как остальные его свойства (такие, как align-items или flex) останутся рабочими.

В результате, мы можем активировать адаптивный лейаут, задействовав Flexbox только тогда, когда в этом будет необходимость.

Итак, мы собираемся удалить display: flex из селекторов .columns и .column, вместо этого «запаковав» их в медиа-запрос:

@media screen and (min-width: 800px) {
  .columns,
  .column {
    display: flex;
  }
}

Вот и все! На экранах с маленьким разрешением все статьи будут располагаться друг над другом, а на экранах с разрешением свыше 800 пикселей — в два столбца.

7. Добавляем завершающие штрихи


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

@media screen and (min-width: 1000px) {
  .first-article {
    flex-direction: row;
  }

  .first-article .article-body {
    flex: 1;
  }

  .first-article .article-image {
    height: 300px;
    order: 2;
    padding-top: 0;
    width: 400px;
  }

  .main-column {
    flex: 3;
  }

  .nested-column {
    flex: 2;
  }
}

Содержимое первой статьи выровнено по горизонтали: текст расположен по левой стороне, а картинка — по правой. Также, главный столбец теперь стал шире (75%). То же самое касается и вложенного столбца (66%).

А вот и финальный результат!

image
Кликните для просмотра в действии

Вывод


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

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


  1. Reeze
    31.10.2016 16:24
    +2

    Если статья про вёрстку и претендует на позитивную оценку, то хотя бы проверяйте эту самую вёрстку.
    Mozilla 49.0.2 на Windows.


    Делали/тестировали под Хром?


    1. Reeze
      31.10.2016 16:28

      Понял вас. Оказалось, что это перевод (примечание).


      1. Coldrain
        08.11.2016 11:59

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


    1. sashabeep
      31.10.2016 16:48

      Только что хотел вставить этот скрин, да


    1. Shannon
      31.10.2016 17:01

      Картинки через

      position: absolute;
      это чето немного не то

      В каментах уже предложили исправленную версию:
      http://codepen.io/anon/pen/LZVbNm


    1. alek0585
      31.10.2016 18:51

      Тоже самое под мак осью на файрфоксе.


  1. Aingis
    31.10.2016 17:23

    Статья для новичков конечно, но это лучше чем сто первая система сеток (которые уже не нужны).


    1. Alexufo
      31.10.2016 19:01
      +1

      а чем заменили?)


  1. seokirill
    31.10.2016 18:48
    -1

    на хабре про основы верстки оО?!


    1. limonte
      31.10.2016 19:53
      +5

      Да. Это хорошие основы.

      Я вытащил эту статью из песочницы и, судя по количеству звезд (?70 за два часа), не напрасно.


  1. Sulin
    31.10.2016 21:48
    +1

    IE 11 — всё развалилось, думаю даже нет смысла открывать на андроиде 4.0.1 или 4.1.
    К чему такие посты вообще делать.


    1. vshemarov
      31.10.2016 23:33

      1. fraky
        01.11.2016 11:39

        вот поэтому приходится еще помнить про float, table, etc ((


    1. Aingis
      01.11.2016 13:51

      В IE11 просто забыли прописать flex-basis: auto для .article-body и .article-content:

      .article-body,
      .article-content {
          flex: 1 0 auto;
      }
      


  1. ingumsky
    01.11.2016 13:53

    Скажите, пожалуйста, я правильно понимаю, что и раскладку а-ля masonry (блоки различной высоты и ширины) тоже достаточно просто можно реализовать с помощью flexbox?


  1. mtt
    01.11.2016 14:18

    Объясните мне, как вы вот это читаете?

    https://hsto.org/getpro/habr/post_images/837/80e/2aa/83780e2aa8bf1899c504aa9eae53a695.png

    Слева направо? Сверху вниз? Где новость более свежая? В какую сторону идет хронологическая сортировка?


    1. damat
      06.11.2016 17:49

      а это не надо читать… это просто чтобы рандомный контент круче выглядел
      PS тихо ненавижу эти новомодные «журнальные» лейауты