Привет, Хабр! У нас стартанул новый поток курса Frontend-разработчик, а я делюсь с вами небольшим чек-листом для фронтендера о том, как мыслить при создании макета, какие вопросы задавать себе самому. Смело кладите её в закладки, если хотите рассказать своему падавану джуну, с какой стороны подойти к дизайну макета, но не хотите тратить своё время на объяснение относительно несложных вещей.
![](https://habrastorage.org/r/w780q1/webt/cw/lm/az/cwlmaz1naeoksbeqnandibw79po.jpeg)
![](https://habrastorage.org/r/w780q1/webt/gd/mk/ni/gdmkniyud7sqnzt1lwaakxuijbe.jpeg)
Я спросил в Твиттере, о чём ещё в CSS я должен написать? Одно из привлёкших моё внимание предложений касается мышления при реализации макета на CSS. Оно включает размышления о возможных решениях и множество вопросов ради того, чтобы дизайн был правильным. Здесь я покажу мой подход к обдумыванию нового макета и то, как вы можете применить те же шаги в своей работе. Вы готовы? Давайте нырнём.
Первое, что я обычно делаю, — откладываю детали дизайна на потом. Это означает, что я выделяю основные части конкретного макета и начинаю размышлять сначала о них. Я знаю, что детали важны, но это временно, поэтому мы можем сначала сосредоточиться на деталях высокого уровня. Рассмотрим следующий пользовательский интерфейс:
![](https://habrastorage.org/r/w1560/webt/ef/qp/de/efqpderfjseegvlwalguenhe3j0.png)
В этой конструкции мы имеем следующее:
Может возникнуть соблазн начать думать сначала о мелких деталях, не на высоком уровне абстракции. Если бы меня попросили визуально упростить подход, я бы сказал, что фронтенд-разработчик должен носить очки, позволяющие видеть только элементы макета высокого уровня, вот так:
![](https://habrastorage.org/r/w1560/webt/oh/l2/p2/ohl2p2zpkswu-54emwwziuvypm8.png)
Обратите внимание, что в очках вы можете видеть только важные высокоуровневые компоненты пользовательского интерфейса. Такой подход поможет размышлять о том, как расположить компоненты, вместо того, чтобы думать о маленьких кусочках каждого компонента. Вот так размышляю я:
Теперь, когда я хочу работать над изложенным в коде, то делаю быстрый прототип, просто чтобы быстро увидеть прогресс.
Поскольку у нас есть раздел из 4 столбцов, для него я воспользуюсь CSS-сеткой (grid). Это идеальный вариант применения для неё.
Это был пример скорых размышлений «в очках». До сих пор я даже не задумывался об отзывчивом дизайне. У меня есть некоторые вопросы о деталях некоторых компонентов, но я не буду сейчас углубляться в них. Читайте об этом в разделе «погружение в детали» в конце статьи. Теперь, когда вы поняли идею, я приведу еще несколько примеров высокоуровневого мышления, чтобы вы могли лучше в нём разобраться.
В этом примере у нас есть макет страницы статьи. Вот пользовательский интерфейс, который содержит:
![](https://habrastorage.org/r/w1560/webt/qc/6j/rq/qc6jrqtto-gkzdbrswimmr0927e.png)
Теперь, когда у вас есть представление о том, как выглядит дизайн, давайте наденем очки, чтобы видеть только высокоуровневые элементы.
![](https://habrastorage.org/r/w1560/webt/v0/3g/33/v03g33cac1xnrb_o6_snbyt3sto.png)
Вот они:
![](https://habrastorage.org/r/w1560/webt/ag/qk/6z/agqk6z77ylaqiol_zu4m5sp3oo8.png)
Здесь нет необходимости применять какой-то метод компоновки. Простой max-width сделает свою работу. Обязательно добавьте горизонтальный внутренний отступ (padding), чтобы края элемента не прилипали к краям на небольших видовых экранах.
![](https://habrastorage.org/r/w1560/webt/os/yh/on/osyhonsznpar7-gspzixuinvyue.png)
Основной элемент (main) статьи занимает всю ширину видового экрана за вычетом ширины боковой панели. Обычно боковая панель должна иметь фиксированную ширину. Для этого идеально подходит CSS-сетка (grid).
Внутреннее содержание статьи должно ограничиваться внутри обёртки.
Теперь, когда вы получили представление о решениях высокого уровня, которые нужно принять при создании макета, следующий шаг — подумать о работе с каждым разделом в смысле дизайна.
В первом примере статьи я говорил, что мы погрузимся в детали позже. Этот момент настал.
![](https://habrastorage.org/r/w1560/webt/qz/b7/eb/qzb7ebwurbqswnhvxc6skhxva-i.png)
Вот несколько возможных ситуаций с этим разделом. Что вы думаете? Как фронтенд-разработчик вы должны учитывать такие крайние случаи. Речь идёт не только о создании пользовательского интерфейса без учёта таких скрытых мелочей.
![](https://habrastorage.org/r/w1560/webt/yj/ex/n0/yjexn0wssob_mkghjjbkr-ljt4k.png)
Я не буду вдаваться в подробности о том, каким должен быть код каждой вариации, поскольку статья сосредоточена на мыслительном процессе, но я горю желанием показать вам что-нибудь этакое. Обратите внимание, что в первом и третьем вариантах предыдущего макета у нас три шага, а не два. Можем ли мы сделать CSS динамическим, чтобы он обрабатывал ситуацию за нас? Я имею в виду увеличение числа шагов с двух до трёх.
Я воспользовался CSS-сеткой с
![](https://habrastorage.org/webt/qn/ao/aj/qnaoajeyylo1qgtwskmplcr3sa0.gif)
Первое, что я делаю, когда хочу построить новый раздел или компонент, — задаю себе много вопросов. Вот о чём я подумаю при создании раздела hero.
![](https://habrastorage.org/r/w1560/webt/_g/fz/et/_gfzety_huwysx_uxiwc9eguqos.png)
В зависимости от природы проекта, над которым вы работаете, вы должны найти ответы на эти вопросы. Это поможет определить, как должен быть построен компонент hero. Иногда бывает трудно получить ответ на каждый из этих вопросов, но, чем больше вы задаёте вопросов, тем выше вероятность получить хороший результат без ошибок.
В нашем компоненте я займусь расстоянием между дочерними элементами. Для этой задачи мне нравится пользоваться свойством flow-space. Я узнал о нём из блога Piccalil Энди Белла. Наша задача — предоставить расстояние между напрямую родственными элементами:
![](https://habrastorage.org/r/w1560/webt/wh/e8/oq/whe8oqncjpbtsvncsiaenlcpiuk.png)
Как вы уже видели, процесс реализации компонента состоит не только в том, чтобы сделать его точным соответствием дизайну, но и в том, чтобы спросить себя и подумать о крайних случаях. Я надеюсь, что вы научились чему-то из этой статьи. И не забывайте про промокод HABR, добавляющий 10% к скидке на баннере.
![image](https://habrastorage.org/r/w780q1/webt/t2/cd/65/t2cd65bi595swdzplnwezknnhkm.jpeg)
![](https://habrastorage.org/webt/cw/lm/az/cwlmaz1naeoksbeqnandibw79po.jpeg)
![](https://habrastorage.org/webt/gd/mk/ni/gdmkniyud7sqnzt1lwaakxuijbe.jpeg)
Я спросил в Твиттере, о чём ещё в CSS я должен написать? Одно из привлёкших моё внимание предложений касается мышления при реализации макета на CSS. Оно включает размышления о возможных решениях и множество вопросов ради того, чтобы дизайн был правильным. Здесь я покажу мой подход к обдумыванию нового макета и то, как вы можете применить те же шаги в своей работе. Вы готовы? Давайте нырнём.
Детали в сторону
Первое, что я обычно делаю, — откладываю детали дизайна на потом. Это означает, что я выделяю основные части конкретного макета и начинаю размышлять сначала о них. Я знаю, что детали важны, но это временно, поэтому мы можем сначала сосредоточиться на деталях высокого уровня. Рассмотрим следующий пользовательский интерфейс:
![](https://habrastorage.org/webt/ef/qp/de/efqpderfjseegvlwalguenhe3j0.png)
В этой конструкции мы имеем следующее:
- Заголовок/Навигация.
- Главная секция.
- Как это работает.
Может возникнуть соблазн начать думать сначала о мелких деталях, не на высоком уровне абстракции. Если бы меня попросили визуально упростить подход, я бы сказал, что фронтенд-разработчик должен носить очки, позволяющие видеть только элементы макета высокого уровня, вот так:
![](https://habrastorage.org/webt/oh/l2/p2/ohl2p2zpkswu-54emwwziuvypm8.png)
Обратите внимание, что в очках вы можете видеть только важные высокоуровневые компоненты пользовательского интерфейса. Такой подход поможет размышлять о том, как расположить компоненты, вместо того, чтобы думать о маленьких кусочках каждого компонента. Вот так размышляю я:
- Заголовок во всю ширину: похоже, что заголовок занимает всю ширину видового экрана и его содержимое внутри обёртки не ограничено.
- Содержимое элемента hero центрируется горизонтально, и обратите внимание, что для него нужно установить max-width (у абзаца две строки).
- Как это работает: это макет из 4 колонок, раздел в целом ограничен обёрткой.
Теперь, когда я хочу работать над изложенным в коде, то делаю быстрый прототип, просто чтобы быстро увидеть прогресс.
<header></header>
<section class="hero">
<!-- A div to constraint the content -->
<div class="hero__content"></div>
</section>
<div class="wrapper">
<!-- 4-columns layout -->
<section class="grid-4"></section>
</div>
Поскольку у нас есть раздел из 4 столбцов, для него я воспользуюсь 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);
}
Это был пример скорых размышлений «в очках». До сих пор я даже не задумывался об отзывчивом дизайне. У меня есть некоторые вопросы о деталях некоторых компонентов, но я не буду сейчас углубляться в них. Читайте об этом в разделе «погружение в детали» в конце статьи. Теперь, когда вы поняли идею, я приведу еще несколько примеров высокоуровневого мышления, чтобы вы могли лучше в нём разобраться.
Страница статьи
В этом примере у нас есть макет страницы статьи. Вот пользовательский интерфейс, который содержит:
- Заголовок.
- Заголовок страницы.
- Предпросмотр изображения для статьи.
- Содержание статьи.
- Боковую панель (справа).
![](https://habrastorage.org/webt/qc/6j/rq/qc6jrqtto-gkzdbrswimmr0927e.png)
Теперь, когда у вас есть представление о том, как выглядит дизайн, давайте наденем очки, чтобы видеть только высокоуровневые элементы.
![](https://habrastorage.org/webt/v0/3g/33/v03g33cac1xnrb_o6_snbyt3sto.png)
Вот они:
- Заголовок сайта, занимающий всю ширину страницы.
- Заголовок страницы, содержащий заголовок статьи и её описание, содержимое выровнено по левому краю с помощью max-width.
- Макет из двух колонок, содержащий основной (main) и боковой (sidebar) элементы.
- Внутреннее содержание статьи, которая центрирована горизонтально и имеет max-width.
Заголовок страницы статьи
![](https://habrastorage.org/webt/ag/qk/6z/agqk6z77ylaqiol_zu4m5sp3oo8.png)
Здесь нет необходимости применять какой-то метод компоновки. Простой max-width сделает свою работу. Обязательно добавьте горизонтальный внутренний отступ (padding), чтобы края элемента не прилипали к краям на небольших видовых экранах.
.page-header {
max-width: 50rem;
padding: 2rem 1rem;
}
Статья — основа и сайдбар
![](https://habrastorage.org/webt/os/yh/on/osyhonsznpar7-gspzixuinvyue.png)
Основной элемент (main) статьи занимает всю ширину видового экрана за вычетом ширины боковой панели. Обычно боковая панель должна иметь фиксированную ширину. Для этого идеально подходит CSS-сетка (grid).
.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;
}
Теперь, когда вы получили представление о решениях высокого уровня, которые нужно принять при создании макета, следующий шаг — подумать о работе с каждым разделом в смысле дизайна.
Погружение в детали
Как это работает
В первом примере статьи я говорил, что мы погрузимся в детали позже. Этот момент настал.
![](https://habrastorage.org/webt/qz/b7/eb/qzb7ebwurbqswnhvxc6skhxva-i.png)
Колонки
- Есть ли у нас случаи, когда число шагов может быть меньше или больше? Если да, как работать в такой ситуации?
- Нужно ли, чтобы столбцы были равны по высоте, особенно когда на карточке очень длинный текст?
Заголовок
- Нужно ли нам, чтобы раздел заголовка оставался в стороне? Или бывают случаи, когда он должна занимать всю ширину?
Адаптивный дизайн
- В какой ситуации нужно складыванием адаптировать к размеру дочерние элементы раздела? Есть ли у нас какой-то триггер складывания? Если да, то что это за триггер?
Вот несколько возможных ситуаций с этим разделом. Что вы думаете? Как фронтенд-разработчик вы должны учитывать такие крайние случаи. Речь идёт не только о создании пользовательского интерфейса без учёта таких скрытых мелочей.
![](https://habrastorage.org/webt/yj/ex/n0/yjexn0wssob_mkghjjbkr-ljt4k.png)
Я не буду вдаваться в подробности о том, каким должен быть код каждой вариации, поскольку статья сосредоточена на мыслительном процессе, но я горю желанием показать вам что-нибудь этакое. Обратите внимание, что в первом и третьем вариантах предыдущего макета у нас три шага, а не два. Можем ли мы сделать CSS динамическим, чтобы он обрабатывал ситуацию за нас? Я имею в виду увеличение числа шагов с двух до трёх.
<div class="wrapper">
<section class="steps">
<div>
<h2>How it works</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>v
</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
. Это полезно, когда количество карт может увеличиваться или уменьшаться. Смотрите видео ниже:![](https://habrastorage.org/webt/qn/ao/aj/qnaoajeyylo1qgtwskmplcr3sa0.gif)
Раздел hero
Первое, что я делаю, когда хочу построить новый раздел или компонент, — задаю себе много вопросов. Вот о чём я подумаю при создании раздела hero.
![](https://habrastorage.org/webt/_g/fz/et/_gfzety_huwysx_uxiwc9eguqos.png)
Изображение раздела
- Как изображение должно представляться? Это изображение меняется каждый день, или оно должно обновляться с помощью CMS?
- Должны ли мы использовать HTML или фон в CSS?
- Каково ожидаемое соотношение сторон изображения?
- Нужно ли использовать несколько размеров изображения в зависимости от размера видового экрана?
- Может быть, у нас не изображение, а видео? У меня бывали ситуации, когда после работы над изображением клиенты говорили, что вместо изображения нужно видео.
Высота раздела
- Какова минимальная высота раздела?
Длина контента
- Нужно ли устанавливать максимальную длину для заголовка и описания? Если да, то каковы минимум и максимум, с которыми дизайн должен работать?
Расстояние между элементами
- Как обрабатывать вертикальное расстояние?
Центрирование контента
- Как центрировать контент по горизонтали и по вертикали? С учётом того, что известна только ширина, но не высота.
Ограничение контента
- Ради повышения читабельности контент лучше ограничивать. Какова идеальная ширина ограничения?
Адаптивный дизайн
- Нужно ли менять размер шрифта в зависимости от ширины видового экрана? Если да, то что лучше использовать: пиксели — px, единицы видового экрана или функцию CSS clamp()?
В зависимости от природы проекта, над которым вы работаете, вы должны найти ответы на эти вопросы. Это поможет определить, как должен быть построен компонент hero. Иногда бывает трудно получить ответ на каждый из этих вопросов, но, чем больше вы задаёте вопросов, тем выше вероятность получить хороший результат без ошибок.
В нашем компоненте я займусь расстоянием между дочерними элементами. Для этой задачи мне нравится пользоваться свойством flow-space. Я узнал о нём из блога Piccalil Энди Белла. Наша задача — предоставить расстояние между напрямую родственными элементами:
![](https://habrastorage.org/webt/wh/e8/oq/whe8oqncjpbtsvncsiaenlcpiuk.png)
<section class="hero">
<!-- A div to constraint the content -->
<div class="hero__content flow">
<h2>Food is amazing</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);
}
И последнее
Как вы уже видели, процесс реализации компонента состоит не только в том, чтобы сделать его точным соответствием дизайну, но и в том, чтобы спросить себя и подумать о крайних случаях. Я надеюсь, что вы научились чему-то из этой статьи. И не забывайте про промокод HABR, добавляющий 10% к скидке на баннере.
![image](https://habrastorage.org/webt/t2/cd/65/t2cd65bi595swdzplnwezknnhkm.jpeg)
Eще курсы
- Обучение профессии Data Science
- Обучение профессии Data Analyst
- Курс по Machine Learning
- Продвинутый курс «Machine Learning Pro + Deep Learning»
- Курс «Математика и Machine Learning для Data Science»
- Профессия Этичный хакер
- Разработчик игр на Unity
- Курс по JavaScript
- Профессия Java-разработчик
- C++ разработчик
- Курс по аналитике данных
- Курс по DevOps
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
Рекомендуемые статьи
- Сколько зарабатывает дата-сайентист: обзор зарплат и вакансий в 2020
- Сколько зарабатывает аналитик данных: обзор зарплат и вакансий в 2020
- Как стать Data Scientist без онлайн-курсов
- 450 бесплатных курсов от Лиги Плюща
- Как изучать Machine Learning 5 дней в неделю 9 месяцев подряд
- Machine Learning и Computer Vision в добывающей промышленности
- Machine Learning и Computer Vision на обогатительных фабриках