Я опубликовал в Твиттере вопрос о том, на какую тему, связанную с CSS, мне стоит написать очередную статью. Одна из идей, которая привлекла моё внимание, касалась процесса размышлений о реализации макета страницы средствами CSS. В этот процесс входили и раздумья о возможных способах решения задачи, и задавание множества вопросов, ответы на которые позволяют сделать всё правильно.



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

Пример №1: избавление от деталей


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


Дизайн-макет страницы

Здесь можно выделить следующие основные блоки:

  • Заголовок страницы, содержащий логотип и навигационные элементы.
  • Верхняя часть страницы.
  • Содержимое страницы с пошаговым описанием некоего процесса, представленного в виде нескольких карточек.

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


Разработчик надевает специальные очки и видит лишь основные блоки макета: заголовок, занимающий всю ширину страницы, верхнюю часть, содержимое которой выровнено по центру, основное содержимое, представленное четырьмя колонками заданной ширины

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

Вот как я размышляю о подобной странице:

  • Здесь имеется заголовок, занимающий всю ширину страницы. Такое ощущение, что его ширина соответствует ширине области просмотра. Кажется, что его содержимое не ограничено пределами некоего контейнера.
  • Содержимое верхней части страницы отцентровано по горизонтали. Кроме того, при его оформлении нужно будет настроить свойство max-width (абзац включает в себя две строки).
  • Основное содержимое страницы представлено в виде макета, состоящего из четырёх колонок (карточек), а весь раздел с основным содержимым помещён в контейнер.

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

Вот HTML-код:

<header></header>

<section class="hero">
  <!-- Элемент div, ограничивающий содержимое раздела -->
  <div class="hero__content"></div>
</section>

<div class="wrapper">
  <!-- 4-колоночный макет -->
  <section class="grid-4"></section>
</div>

Так как содержимое одного из разделов страницы организовано в 4 колонках, я решил использовать для реализации этого раздела Grid-макет. Технология CSS Grid отлично подходит для создания подобных макетов:

.wrapper {
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
  max-width: 1140px;
}

.hero__content {
  max-width: 700px;
  margin-left: auto;
  margin-right: auto;
}

.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

Это — то, как страница воспринимается через «очки», отсекающие детали и позволяющие видеть лишь самое главное. И я, кстати, ещё даже не задумывался об отзывчивом дизайне. У меня имеются вопросы, касающиеся деталей реализации некоторых компонентов, но пока я о них не думаю. О том, что это за вопросы, мы поговорим ниже.

Теперь, когда у вас уже должно сформироваться общее понимание моего подхода к дизайну, я приведу ещё несколько примеров подобного восприятия страниц. Это позволит вам лучше разобраться в том, о чём я рассказываю.

Пример №2: страница для вывода материалов статей


В данном примере мы рассмотрим страницу для вывода материалов статей. Вот пример такой страницы.


Страница для вывода материалов статей

Эта страница состоит из следующих основных блоков:

  • Заголовок сайта с навигационными элементами.
  • Заголовок статьи.
  • Изображение к статье.
  • Текстовое содержимое статьи.
  • Боковая панель.

Теперь, получив общее представление о странице, надеваем «очки» и изучаем через них макет страницы.


Изучение основных блоков страницы

Сейчас чётко видно то, что страница состоит из следующих основных компонентов:

  • Заголовок сайта, занимающий всю ширину области просмотра.
  • Заголовок страницы, содержащий название статьи и её описание. Он выровнен по левому краю страницы, при его оформлении нужно использовать свойство max-width.
  • Область, содержащая две колонки. Одна из них представляет основное содержание статьи, а вторая — боковую панель.
  • Содержимое статьи, выровненное по центру, при оформлении которого пригодится свойство max-width.

Поговорим об этих компонентах.

?Заголовок сайта и заголовок статьи



Заголовок сайта и заголовок статьи

При оформлении заголовка сайта и статьи нет нужды в использовании каких-то сложных механизмов создания макетов. Тут можно использовать обычным свойством max-width. Здесь, кроме того, стоит применить свойство padding с небольшими значениями, что позволит избежать слишком тесного примыкания друг к другу краёв элементов в областях просмотра небольшого размера.

.page-header {
  max-width: 50rem;
  padding: 2rem 1rem;
}

?Двухколоночная область



Нижняя часть страницы, состоящая из двух колонок

Основная часть страницы занимает всю ширину области просмотра за вычетом ширины боковой панели. Обычно боковые панели имеют фиксированную ширину. Для оформления этого раздела отлично подходит Grid-макет. Вот соответствующий CSS-код:

.page-wrapper {
  display: grid;
  grid-template-columns: 1fr;
}

@media (min-width: 800px) {
  grid-template-columns: 1fr 250px;
}

Ширина раздела с содержимым статьи должна быть ограничена шириной элемента-контейнера:

.inner-content {
  max-width: 50rem;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}

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

Продолжение примера №1: детали реализации раздела с основным содержимым



Этапы работы над разделом с содержимым страницы

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

?Многоколоночный макет


  • Возможны ли ситуации, в которых количество столбцов будет больше или меньше, чем в исходном примере? Если это так — тогда нам нужно найти ответ на вопрос о том, как выводить колонки, число которых меньше или больше трёх.
  • Нужно ли, чтобы все карточки имели бы одинаковую высоту? Этот вопрос особенно актуален в тех случаях, когда в некоторых карточках имеются очень длинные фрагменты текста.

?Заголовок раздела


  • Должен ли заголовок раздела размещаться отдельно от колонок? Возможны ли ситуации, в которых он занимает всю ширину области просмотра?

?Отзывчивый дизайн


  • Когда нужно сворачивать дочерние элементы раздела? Есть ли некое условие, наступление которого должно к этому приводить? И, если такое условие есть, нам нужно знать о том, что это за условие.

Вот несколько возможных подходов к реализации этого раздела. Что вы о них думаете? От того, кто занимается фронтенд-разработкой, ожидается то, что он учтёт в макете подобные пограничные случаи. Фронтенд-разработка — это не только умение воспроизвести в коде то, что нарисовал дизайнер, но и умение видеть и учитывать скрытые особенности страниц, проявляющиеся в особых случаях.


Разные варианты макета основного раздела страницы

Этот материал посвящён образу мыслей фронтенд-разработчика. Поэтому в детали реализации каждого из вышеприведённых макетов я вдаваться не могу. Но кое-что интересное об этом макете я, всё же, расскажу.

Обратите внимание на то, что в первом варианте макета имеется три карточки, а в третьем — две. Можно ли сделать так, чтобы CSS автоматически подстраивал параметры карточек при изменении их количества? То есть — чтобы ширина элементов увеличивалась бы в том случае, если их всего два?

Вот разметка страницы:

<div class="wrapper">
  <section class="steps">
    <div>
      <h2><font color="#3AC1EF">How it works</font></h2>
      <p>Easy and simple steps</p>
    </div>
    <div class="layout">
      <div class="layout__item">
        <article class="card"></article>
      </div>
      <div class="layout__item">
        <article class="card"></article>
      </div>
      <div class="layout__item">
        <article class="card"></article>
      </div>
    </div>
  </section>
</div>

Вот стили:

.steps {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 1rem;
}

@media (min-width: 700px) {
  .steps {
    grid-template-columns: 250px 1fr;
  }
}

.layout {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 1rem;
}

@media (min-width: 200px) {
  .layout {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
}

Здесь я воспользовался CSS-функцией minmax() и ключевым словом auto-fit. Этот подход полезен в тех случаях, когда количество элементов страниц может меняться. Вот видео, в котором показано поведение рассматриваемого макета в разных ситуациях.


Автоматическая настройка параметров карточек

Продолжение примера №1: детали реализации верхней части страницы



Работа над верхней частью страницы

Для создания этой части страницы нужно ответить на несколько групп вопросов.

?Изображение, используемое в верхней части страницы


  • Как должно быть представлено изображение? Является ли оно чем-то таким, что постоянно меняется? Задаётся ли это изображение с помощью CMS?
  • Что нужно применить для оформления изображения: HTML-элемент <img> или CSS-фон?
  • Какое соотношение сторон будет у изображения?
  • Нужно ли использовать несколько вариантов изображения, выбор одного из которых зависит от размеров области просмотра страницы?
  • Может ли вместо этого изображения использоваться видеоклип? У меня были случаи, когда клиенты, после того, как подобный раздел создавался в расчёте на вывод изображения, сообщали, что им в этом разделе нужно видео.

?Высота раздела


  • Какова минимальная высота верхней части страницы?

?Длина текстового содержимого


  • Нужно ли задавать максимальную длину для заголовка и описания раздела? Если да — тогда каковы минимальная и максимальная ширина содержимого, на которые должен быть рассчитан дизайн раздела?

?Расстояние между элементами


  • Как нужно подходить к настройке расстояния между элементами по вертикали?

?Выравнивание содержимого по центру раздела


  • Как именно нужно отцентровать содержимое раздела по горизонтали и по вертикали? При ответе на этот вопрос нужно учесть то, что нам заранее известна лишь ширина содержимого, а его высота неизвестна.

?Ограничение ширины содержимого


  • Ширину текста имеет смысл ограничить для того чтобы улучшить его читабельность. Какова идеальная ширина текста?

?Отзывчивый дизайн


  • Нужно ли менять размер шрифта в зависимости от ширины области просмотра страницы? Если да — тогда какими единицами измерения стоит пользоваться? Должны ли это быть единицы измерения, основанные на пикселях, или единицы измерения, связанные с областью просмотра? А, может быть, стоит воспользоваться CSS-функцией clamp()?

Ответы на эти вопросы зависят от особенностей конкретного проекта. Эти ответы помогут понять то, как именно должен быть устроен анализируемый компонент, то, как именно его создавать. Иногда ответы на подобные вопросы находить нелегко. Но чем больше подобных вопросов задаёт себе фронтенд-разработчик — тем выше вероятность того, что он создаст качественное и стабильное решение.

Например, в работе над данным компонентом я решил уделить внимание расстоянию между элементами одного уровня. Для этого я воспользовался подходом, описанном в этом материале. А именно, речь идёт об использовании CSS-переменной --flow-space для настройки расстояния между элементами.


Расстояние между элементами одного уровня

Вот HTML-код:

<section class="hero">
  <!-- Элемент div, ограничивающий содержимое-->
  <div class="hero__content flow">
    <h2><font color="#3AC1EF">Food is amazing</font></h2>
    <p>Learn how to cook amazing meals with easy and simple to follow steps</p>
    <a href="/learn">Learn now</a>
  </div>
</section>

Вот стили:

.flow > * + * {
  margin-top: var(--flow-space, 1em);
}

Итоги


Как видите, процесс разработки веб-страниц — это не только воссоздание дизайн-макетов средствами HTML и CSS, но и поиск ответов на вопросы, и размышления о том, как страница будет вести себя в различных ситуациях. Надеюсь, вы нашли в этом материале что-то такое, что вам пригодится.

Как вы организуете процесс превращения дизайн-макетов в работающие веб-страницы?