x
 
Юрий Мазурский
12 марта 2020
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Типовые решения в вёрстке

Я решил выпу­стить цикл сове­тов по моти­вам работ сту­ден­тов Школ бюро. Мы рас­смот­рим реше­ние типо­вых задач в вёрстке и най­дём ответы на самые про­стые вопросы, воз­ни­ка­ю­щие у новичков.

Типовые решения в вёрстке

В сего­дняш­нем совете свер­стаем про­стую шапку «в линию», кото­рая встре­ча­ется на огром­ном коли­че­стве сай­тов, в том числе на сайте бюро.

Макет шапки в Фигме:

Мы будем посте­пенно раз­би­рать шапку на общие блоки и идти вглубь, к отдель­ным элементам.

На самом верх­нем уровне у нас есть три сущ­но­сти: лого­тип, меню и теле­фон. Лого­тип все­гда лучше делать кар­тин­кой, даже если это про­сто какая‑нибудь над­пись. Это нужно, чтобы избе­жать про­блем, напри­мер с неза­гру­зив­ши­мися шриф­тами логотипа.

Наки­даем кар­кас буду­щей шапки в ХТМЛ:

<header>
  <div class="logo">
  </div>
  <div class="menu">
  </div>
  <div class="tel">
  </div>
</header>

Идём вглубь. Ста­вим изоб­ра­же­ние в СВГ с лого­ти­пом и делаем его ссыл­кой на глав­ную страницу:

<header>
  <div class="logo">
    <a href="/">
      <img src="logo.svg" width="60" height="60px" />
    </a>
  </div>
  <div class="menu">
  </div>
  <div class="tel">
  </div>
</header>

Меню по смыслу — вытя­ну­тый в линию спи­сок. Поэтому свер­стаем его списком:

<header>
  <div class="logo">
    <a href="/">
      <img src="logo.svg" width="60" height="60px" />
    </a>
  </div>
  <div class="menu">
    <ul>
      <li><a href="/products">Про­дук­ция</a></li>
      <li><a href="/services">Услуги</a></li>
      <li><a href="/blog">Блог</a></li>
      <li><a href="/contacts">Кон­такты</a></li>
    </ul>
  </div>
  <div class="tel">
  </div>
</header>

Номер теле­фона — тоже ссылка, по кото­рой можно позвонить:

<header>
  <div class="logo">
    <a href="/">
      <img src="logo.svg" width="60" height="60px" />
    </a>
  </div>
  <div class="menu">
    <ul>
      <li><a href="/products">Про­дук­ция</a></li>
      <li><a href="/services">Услуги</a></li>
      <li><a href="/blog">Блог</a></li>
      <li><a href="/contacts">Кон­такты</a></li>
    </ul>
  </div>
  <div class="tel">
    <a href="tel:88004000500">8 800 4000 500</a>
  </div>
</header>

Рас­по­ла­гаем все три основ­ных блока шапки в линию с помо­щью флекса:

header {
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-start;
  align-items: center;
}

Теперь раз­бе­рёмся с меню. Чтобы при­ве­сти его в поря­док, нужно:

  • обну­лить левый отступ у списка (по умол­ча­нию он все­гда задан встро­ен­ными сти­лями браузера),

  • вытя­нуть пункты меню в линию,

  • задать отступы между пунк­тами меню,

  • преду­смот­реть крас­ную плашку под актив­ным пунктом,

  • убрать стан­дарт­ные точки перед пунк­тами списка,

  • сти­ли­зо­вать ссылки.

Ещё нужно заста­вить меню зани­мать всё сво­бод­ное место и при­жи­мать номер теле­фона к пра­вому краю страницы.

Изу­чим макет. Отступы между пунк­тами меню — 40 пикселей:

Ширина отсту­пов от краёв плашки актив­ного пункта меню до тек­ста внутри неё — 10 пик­се­лей по бокам и по 8 пик­се­лей сверху и снизу. Плашку я спе­ци­ально сде­лал полу­про­зрач­ной, чтобы раз­гля­деть крас­ные цифры разметки:

Рас­сто­я­ние от лого­типа до меню — 40 пикселей:

Вытя­ги­ваем пункты меню в линию, уби­раем точки, обну­ляем отступы со всех сто­рон — они нам не нужны. Само меню должно зани­мать всё доступ­ное место — добав­ляем flex-grow:

.menu {
  flex-grow: 1;
}

.menu ul {
  display: flex;
  flex-flow: row nowrap;
  margin: 0;
  padding: 0;
  list-style: none;
}

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

Задаём отступы между пунк­тами меню. Ста­вим 20 пик­се­лей, а не 40, потому что по 10 с каж­дой сто­роны отъ­едает плашка каж­дого пункта меню. Нам нужно это учесть, чтобы ничего не дёр­га­лось при пере­клю­че­нии. У послед­него пункта нужно убрать отступ справа, чтобы он не мешался. Саму плашку будем делать у ссылки:

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

.menu li {
  margin-right: 20px;
}

.menu li:last-child {
  margin-right: 0;
}

.menu a {
  padding: 8px 10px;
}

Добав­ляем отступ справа от лого­типа в 30 пик­се­лей. В сумме с левым padding в 10 пик­се­лей, кото­рый задан у неви­ди­мой плашки пункта меню, будет 40:

.logo {
  margin-right: 30px;
}

Добав­ляем стили плашки актив­ного пункта меню. Тут можно пойти раз­ными путями: поста­вить класс active у li или у самого эле­мента с плаш­кой. Мы пой­дём вто­рым путём. Под­ра­зу­ме­ваем, что внутри li нахо­дится либо ссылка, либо какой‑нибудь эле­мент с клас­сом active:

.menu a,
.menu .active {  
  display: block;
  padding: 8px 10px;
}

.menu .active {
  color: #fff;
  background-color: #ff3d00;
  border-radius: 8px;
}

Сти­ли­зуем ссылки:

.menu ul {
  display: flex;
  flex-flow: row nowrap;
  margin: 0;
  padding: 0;
  font-size: 16px;
  line-height: 18px;
  list-style: none;
}

.menu a,
.menu .active {
  display: block;
  padding: 8px 10px;
  text-transform: uppercase;
  letter-spacing: .27em;
}

.menu a {
  color: #000;
  text-decoration: none;
}

Теперь при­ве­дём в поря­док номер телефона:

.tel {
  font-size: 20px;
  line-height: 24px;
}

.tel a {
  color: #000;
  text-decoration: none;
}

Всё отлично, кроме одной вещи —  базо­вые линии тек­ста меню и номера теле­фона не сов­па­дают из‑за раз­ной высоты блоков:

Опу­стим меню на пару пик­се­лей, чтобы совпадали:

.menu ul {
  display: flex;
  flex-flow: row nowrap;
  margin: 2px 0 0;
  padding: 0;
  font-size: 16px;
  line-height: 18px;
  list-style: none;
}

В блоке menu у нас нет ничего, кроме самого списка ul. Можно изба­виться от лиш­него div и дать класс menu сразу списку. Но мне больше нра­вится вари­ант заме­нить div.menu на nav.menu, так будет семантичнее.

С лого­ти­пом и теле­фо­ном при­мерно та же исто­рия, но ссылки — строч­ные эле­менты и ста­вить их рядом с блоч­ными не стоит. Поэтому оста­вим обёртки лого­типа и теле­фона как есть.

Мы пока не выбрали и никак не настро­или шрифты. В сле­ду­ю­щем совете раз­бе­рём раз­ные вари­анты под­клю­че­ния своих шриф­тов к странице.

Ито­го­вый резуль­тат можно посмот­реть на Код­пене.

Что ещё почитать

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Поделиться
Отправить

Комментарии

Андрей Ерес
12 марта 2020

За счёт letter-spacing у активного элемента правое поле стало больше.

Юрий Мазурский
12 марта 2020

Андрей, точно. Поправим это в следующем совете вместе с шрифтами.

Дима Шишикин
17 марта 2020

Для img лучше указывать alt.
Вместо div для меню можно использовать nav.
flex-flow: row nowrap; — лишний CSS, это значения по умолчанию.

Вместо
css .menu li { margin-right: 20px; } .menu li:last-child { margin-right: 0; }
можно
css .menu li + li { margin-left: 20px; }

Евгений Максименков
17 марта 2020

:not(:last-child) сократит код и избавит от переопределения значения.

Было
css .menu li { margin-right: 20px; } .menu li:last-child { margin-right: 0; }
Стало
css .menu li:not(:last-child) { margin-right: 20px; }

Евгений Удод
2 апреля 2020

Вёрстка получится крепче, если в меню вообще не учитывать последний пункт, а все пункты заверстать идентично:
css .menu li { margin-right: 10px; margin-left: 10px; }
При таком решении нет лишнего кода, к последнему пункту справа ничего не «прилипнет», в случае правок всё редактируется в одном месте.

Решение с выравниванием текста в 2 пикселя выглядит как magic number. Если у телефона и пунктов меню одинаковый размер шрифта, то для выравнивания по общей линии стоит задать и одинаковый line-height.


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

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

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

Вот такой веб 2.0.

Что делать, если меня, технического директора, потихоньку отстраняют от дел? Типовые решения в вёрстке. Почему не стоит использовать float 2 3 Как написать аккуратный код? Часть третья: заменяемость




Недавно всплыло

3 Что должен знать дизайнер об интерлиньяжах, полях, отступах, кеглях, выравниваниях и модульных сетках? 9 9 1