🔍 Начните печатать, чтобы искать по книге или перейти к нужной странице по номеру

Удобно листать не только прокруткой, но и клавишами‑стрелками:

между важными местами
Shift
между
разворотами
Васи­лий Полов­нёв, Игорь Пет­ров

ХТМЛ.
Вёрстка сайтов

Изда­тель­ство Бюро Гор­бу­нова
2021
Василий Половнёв, Игорь Петров

ХТМЛ.
Вёрстка сайтов

Издательство Бюро Горбунова
2021
удк 004.42
ббк З973.42
П52
Васи­лий Полов­нёв, Игорь Пет­ров
П52
ХТМЛ. Вёрстка сай­тов для дизай­не­ров, редак­то­ров и руко­во­ди­те­лей.—
М.: Изд‑во Бюро Гор­бу­нова, 2021

Эта книга — поша­го­вая инструк­ция по вёрстке сай­тов на язы­ках ХТМЛ и ЦСС. Вы узна­ете не только как свер­стать сайт, но и как опуб­ли­ко­вать его в интер­нете, настро­ить кра­си­вый шаринг в соц­сети и под­клю­чить системы аналитики.

Отдель­ный раз­дел книги посвя­щён работе с вер­сталь­щи­ком: как ста­вить задачи, полу­чать пред­ска­зу­е­мый резуль­тат и пра­вильно при­ни­мать и внед­рять вёрстку.

Оглавление

удк 004.42
ббк З973.42
П52
П52
Василий Половнёв, Игорь Петров
ХТМЛ. Вёрстка сайтов для дизайнеров, редакторов и руководителей.—
М.: Изд‑во Бюро Горбунова, 2021

Эта книга — пошаговая инструкция по вёрстке сайтов на языках ХТМЛ и ЦСС. Вы узнаете не только как сверстать сайт, но и как опубликовать его в интернете, настроить красивый шаринг в соцсети и подключить системы аналитики.

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

Оглавление

Знакомство с ХТМЛ

ХТМЛ‑файл в текстовом редакторе

Что такое веб‑страница

Любая веб‑стра­ница — это про­сто тек­сто­вый файл с осо­бой разметкой.

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

ХТМЛ‑файл в браузере

Если затем пере­та­щить этот файл в бра­у­зер, мы уви­дим стра­ницу с тек­стом, сей­час она выгля­дит про­сто и неприглядно.

Чтобы стра­ницу было удобно читать и изу­чать, её содер­жи­мое осо­бым обра­зом струк­ту­ри­руют и оформ­ляют. Сей­час раз­бе­рёмся, как это делают.

Редактировать ХТМЛ‑файлы можно в стандартной программе «Блокнот», но удобнее использовать более продвинутые текстовые редакторы. Например, несложный в освоении бесплатный редактор «Саблайм»

Знакомство с ХТМЛ

ХТМЛ‑файл в текстовом редакторе

Что такое веб‑страница

Любая веб‑страница — это просто текстовый файл с особой разметкой.

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

ХТМЛ‑файл в браузере

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

Чтобы страницу было удобно читать и изучать, её содержимое особым образом структурируют и оформляют. Сейчас разберёмся, как это делают.

Редактировать ХТМЛ‑файлы можно в стандартной программе «Блокнот», но удобнее использовать более продвинутые текстовые редакторы. Например, несложный в освоении бесплатный редактор «Саблайм»

Лайфхак: песочницы для кода

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

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

Самые популярные и простые в освоении песочницы: Кодпен и Код Сэндбокс

Лайфхак: песочницы для кода

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

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

Самые популярные и простые в освоении песочницы: Кодпен и Код Сэндбокс

Теги

Чтобы струк­ту­ри­ро­вать и офор­мить стра­ницу, её раз­ме­чают язы­ком ХТМЛ.

ХТМЛ‑раз­метка состоит из кон­тей­не­ров с содер­жи­мым — тегов. Текст поме­щают внутрь тега, между его откры­ва­ю­щей и закры­ва­ю­щей частями:

<h1>Заголовок</h1>
<p>Текст абзаца.</p>
<p>Текст второго абзаца.</p>

Про­сто отбить один абзац от дру­гого энте­рами, как в Ворде, не полу­чится — бра­у­зеры вос­при­мут эти энтеры как пробелы.

Назва­ние тега отра­жает его смысл. Напри­мер, h1 — heading 1 — заго­ло­вок пер­вого уровня.

Теги можно вкла­ды­вать друг в друга. Напри­мер, сде­лать жир­ный текст внутри абзаца или пункты внутри списка:

<p>По-настоящему <b>важные принципы</b>:</p>

<ul>
  <li>Не планировать впритык</li>
  <li>Сделать значит сдать</li>
  <li>Флекс — всегда боль</li>
</ul>

Есть теги, кото­рые не нужно закры­вать и в кото­рые нельзя ничего вло­жить. Напри­мер, тег пере­носа строки br:

<h1>
  Лев Николаевич Толстой. <br>
  Жизнь и взгляды
</h1>

Не закры­ва­ются теги кар­ти­нок и раз­ных интер­ак­тив­ных эле­мен­тов: видео, полей ввода, кно­пок. Все эти эле­менты мы раз­бе­рём дальше в книге.

Ещё в ХТМЛ есть ком­мен­та­рии. Это спе­ци­аль­ный текст, кото­рый не будет видно на стра­нице, только в коде. Раз­ра­бот­чики исполь­зуют ком­мен­та­рии в каче­стве под­ска­зок себе и дру­гим людям, рабо­та­ю­щим с кодом.

Ком­мен­та­рии пишут внутри кон­струк­ции <!-- … -->, это поз­во­ляет удобно пря­тать любые теги — доста­точно допи­сать вос­кли­ца­тель­ный знак и дефисы в начале и конце тега и он пре­вра­тится в ком­мен­та­рий, про­па­дёт со стра­ницы, при этом остав­шись в коде. На языке раз­ра­бот­чи­ков это назы­ва­ется «заком­мен­тить» — спря­тать кусок вёрстки.

<p>Автор: Галина Игнатова</p>

<!-- Менять код только с разрешения главреда! -->
<p>Издание «Валенсия», код агента 348187</p>

<!-- Источники, закомментить, когда ссылок нет  -->
<!-- ul>
  <li></li>
  <li></li>
</ul -->

Теги

Чтобы структурировать и оформить страницу, её размечают языком ХТМЛ.

ХТМЛ‑разметка состоит из контейнеров с содержимым — тегов. Текст помещают внутрь тега, между его открывающей и закрывающей частями:

<h1>Заголовок</h1>
<p>Текст абзаца.</p>
<p>Текст второго абзаца.</p>

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

Название тега отражает его смысл. Например, h1 — heading 1 — заголовок первого уровня.

Теги можно вкладывать друг в друга. Например, сделать жирный текст внутри абзаца или пункты внутри списка:

<p>По-настоящему <b>важные принципы</b>:</p>

<ul>
  <li>Не планировать впритык</li>
  <li>Сделать значит сдать</li>
  <li>Флекс — всегда боль</li>
</ul>

Есть теги, которые не нужно закрывать и в которые нельзя ничего вложить. Например, тег переноса строки br:

<h1>
  Лев Николаевич Толстой. <br>
  Жизнь и взгляды
</h1>

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

Ещё в ХТМЛ есть комментарии. Это специальный текст, который не будет видно на странице, только в коде. Разработчики используют комментарии в качестве подсказок себе и другим людям, работающим с кодом.

Комментарии пишут внутри конструкции <!-- … -->, это позволяет удобно прятать любые теги — достаточно дописать восклицательный знак и дефисы в начале и конце тега и он превратится в комментарий, пропадёт со страницы, при этом оставшись в коде. На языке разработчиков это называется «закомментить» — спрятать кусок вёрстки.

<p>Автор: Галина Игнатова</p>

<!-- Менять код только с разрешения главреда! -->
<p>Издание «Валенсия», код агента 348187</p>

<!-- Источники, закомментить, когда ссылок нет  -->
<!-- ul>
  <li></li>
  <li></li>
</ul -->

Скрыт 1 разворот
Скрыт 1 раз­во­рот

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

<img>

<p>
  Даблдекер на знаке.
  <a>
    Транспорт Лондона
  </a>
</p>
<img>

<p>
  Даблдекер на знаке.
  <a href="https://tfl.gov.uk/info-for/suppliers-and-contractors/design-standards">
    Транспорт Лондона
  </a>
</p>
<img src="https://bureau.ru/projects/book-html/files/london-bus.png">

<p>
  Даблдекер на знаке.
  <a href="https://tfl.gov.uk/info-for/suppliers-and-contractors/design-standards">
    Транспорт Лондона
  </a>
</p>
<img src="..."
  width="300px"
  height="80px">

<p>
  Даблдекер на знаке.
  <a href="...">
    Транспорт Лондона
  </a>
</p>
<img src="..."
  width="300px"
  height="80px"
  style="transform: rotate(-5deg) translateY(-3px)">

<p style="font-weight: 100">
  Даблдекер на знаке.
  <a href="...">
    Транспорт Лондона
  </a>
</p>

Свер­стаем кар­тинку и под­пись к ней со ссыл­кой на источ­ник изображения.

Атри­бут href задаёт адрес ссылки.

Чтобы кар­тинка появи­лась, нужно ука­зать атри­бут src.

Чтобы настро­ить раз­меры кар­тинки, исполь­зуют атри­буты width и height.

Самый про­дви­ну­тый атри­бут — style, в нём можно настро­ить что угодно. О нём рас­ска­жем позже.

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

Даблдекер на знаке. Транспорт Лондона

<img>

<p>
  Даблдекер на знаке.
  <a>
    Транспорт Лондона
  </a>
</p>
<img>

<p>
  Даблдекер на знаке.
  <a href="https://tfl.gov.uk/info-for/suppliers-and-contractors/design-standards">
    Транспорт Лондона
  </a>
</p>
<img src="https://bureau.ru/projects/book-html/files/london-bus.png">

<p>
  Даблдекер на знаке.
  <a href="https://tfl.gov.uk/info-for/suppliers-and-contractors/design-standards">
    Транспорт Лондона
  </a>
</p>
<img src="..."
  width="300px"
  height="80px">

<p>
  Даблдекер на знаке.
  <a href="...">
    Транспорт Лондона
  </a>
</p>
<img src="..."
  width="300px"
  height="80px"
  style="transform: rotate(-5deg) translateY(-3px)">

<p style="font-weight: 100">
  Даблдекер на знаке.
  <a href="...">
    Транспорт Лондона
  </a>
</p>

Сверстаем картинку и подпись к ней со ссылкой на источник изображения.

Атрибут href задаёт адрес ссылки.

Чтобы картинка появилась, нужно указать атрибут src.

Чтобы настроить размеры картинки, используют атрибуты width и height.

Самый продвинутый атрибут — style, в нём можно настроить что угодно. О нём расскажем позже.

Скрыто: «Знакомство с ЦСС» и «Веб-инспектор»
Скрыто: «Зна­ком­ство с ЦСС» и «Веб-инспек­тор»

1
Модули

1
Модули

Текстовые модули

Чтобы свер­стать тек­сто­вый модуль, нужно задать шрифт, настро­ить кегль, интер­ли­ньяж, начер­та­ние и вырав­ни­ва­ние. За шрифт отве­чает ЦСС‑свой­ство font-family, за кегль и интер­ли­ньяж — font-size и line-height. Раз­бе­рём их подробнее.

The only easy day
was yesterday

The only easy day
was yesterday

Текстовые модули

Чтобы сверстать текстовый модуль, нужно задать шрифт, настроить кегль, интерлиньяж, начертание и выравнивание. За шрифт отвечает ЦСС‑свойство font-family, за кегль и интерлиньяж — font-size и line-height. Разберём их подробнее.

The only easy day
was yesterday

The only easy day
was yesterday

Скрыто 6 разворотов
Скрыто 6 раз­во­ро­тов

В «рези­но­вой» вёрстке дизай­нер задаёт не только форму кон­тей­нера для тек­ста, но и пра­вила, по кото­рым она меня­ется в зави­си­мо­сти от раз­ме­ров окна и экрана.

Кегль экран­ного тек­ста обычно лежит в диа­па­зоне 12…16 пунк­тов, а интер­ли­ньяж — 1,2…1,4 от зна­че­ния кегля

Кегль и интерлиньяж

В ЦСС кегль зада­ётся свой­ством font-size, а интер­ли­ньяж — свой­ством line-height. Их зна­че­ния могут быть фик­си­ро­ван­ными — px, pt, in, cm, или отно­си­тель­ными — %, emrem:

body {
  font-size: 20px;
  /* Высота строки посчитается от кегля:
     20px * 1.25 = 25px */
  line-height: 1.25;
}

.sidenote {
  /* Кегль посчитается от кегля родителя:
     20px * 0.75 = 15px */
  font-size: .75em;
  /* Высота строки посчитается от кегля элемента:
     15px * 1.2 = 18px */
  line-height: 120%;
}

Обратите внимание: значения в рамочке в этой книге можно менять, попробуйте их подвигать

В «резиновой» вёрстке дизайнер задаёт не только форму контейнера для текста, но и правила, по которым она меняется в зависимости от размеров окна и экрана.

Кегль экранного текста обычно лежит в диапазоне 12…16 пунктов, а интерлиньяж — 1,2…1,4 от значения кегля

Кегль и интерлиньяж

В ЦСС кегль задаётся свойством font-size, а интерлиньяж — свойством line-height. Их значения могут быть фиксированными — px, pt, in, cm, или относительными — %, emrem:

body {
  font-size: 20px;
  /* Высота строки посчитается от кегля:
     20px * 1.25 = 25px */
  line-height: 1.25;
}

.sidenote {
  /* Кегль посчитается от кегля родителя:
     20px * 0.75 = 15px */
  font-size: .75em;
  /* Высота строки посчитается от кегля элемента:
     15px * 1.2 = 18px */
  line-height: 120%;
}

Обратите внимание: значения в рамочке в этой книге можно менять, попробуйте их подвигать

Скрыт 1 разворот
Скрыт 1 раз­во­рот

Лайфхак: em или rem?

И em, и rem — отно­си­тель­ные вели­чины. Раз­ница между ними в том, что em счи­та­ется отно­си­тельно кегля роди­тель­ского эле­мента, а rem — отно­си­тельно кор­не­вого. Сравните:

 20px
1.2em
20px×1.224px
0.625em 24px×0.62515px
0.8em
15px×0.812px
 20px
1.2rem
20px×1.224px
0.625rem
20px×0.62512.5px
0.8rem
20px×0.816px

Для неза­ви­си­мых ком­по­нен­тов лучше подой­дёт rem: не при­дётся бес­по­ко­иться, что роди­тель­ский эле­мент повли­яет на кегль в ком­по­ненте. Если вы, нао­бо­рот, хотите, чтобы вло­жен­ность вли­яла на кегль, берите em.

При исполь­зо­ва­нии rem кегль на кор­не­вом эле­менте (:root) лучше не зада­вать в пик­се­лях. Бра­у­зеры поз­во­ляют настро­ить базо­вый кегль тек­ста. Если задать кегль в пик­се­лях, эта настройка не сра­бо­тает, cла­бо­ви­дя­щим, воз­можно, при­дётся зумить страницу.

Вме­сто этого запом­ните, что кегль по умол­ча­нию во всех бра­у­зе­рах — 16 пик­се­лей, и зада­вайте базо­вый отно­си­тельно него. То есть, вме­сто font-size: 18px — font-size: 1.125em

Лайфхак: em или rem?

И em, и rem — относительные величины. Разница между ними в том, что em считается относительно кегля родительского элемента, а rem — относительно корневого. Сравните:

 20px
1.2em
20px×1.224px
0.625em 24px×0.62515px
0.8em
15px×0.812px
 20px
1.2rem
20px×1.224px
0.625rem
20px×0.62512.5px
0.8rem
20px×0.816px

Для независимых компонентов лучше подойдёт rem: не придётся беспокоиться, что родительский элемент повлияет на кегль в компоненте. Если вы, наоборот, хотите, чтобы вложенность влияла на кегль, берите em.

При использовании rem кегль на корневом элементе (:root) лучше не задавать в пикселях. Браузеры позволяют настроить базовый кегль текста. Если задать кегль в пикселях, эта настройка не сработает, cлабовидящим, возможно, придётся зумить страницу.

Вместо этого запомните, что кегль по умолчанию во всех браузерах — 16 пикселей, и задавайте базовый относительно него. То есть, вместо font-size: 18px — font-size: 1.125em

Скрыто 9 разворотов
Скрыто 9 раз­во­ро­тов

font-weight отве­чает за «жир­ность», вес начер­та­ния. Зада­ется в чис­лах от 100 до 900.

Кроме чис­ло­вых зна­че­ний под­дер­жи­ва­ются клю­че­вые слова: normal, bold, lighter и bolder.

normal — это обыч­ное начер­та­ние, сино­ним font-weight: 400

font‑weight: 400
font‑weight: normal

bold — жир­ное начер­та­ние, сино­ним font-weight: 700

font‑weight: 700
font‑weight: bold

Лучше исполь­зо­вать клю­че­вые слова, а не их чис­ло­вые зна­че­ния: их проще вос­при­ни­мать, не нужно запо­ми­нать маги­че­ские числа.

Жир­ность начер­та­ния отно­си­тельно роди­теля зада­ётся с помо­щью клю­че­вых слов lighter (полегче) и bolder (пожирнее):

font‑weight: lighter
font‑weight: bolder

lighterfont‑weightbolder
light100, lightregular
light200, lightregular
light300, lightregular
light400, regularbold
light500, regularbold
regular600, boldbold
regular700, boldbold
bold800, boldbold
bold900, boldbold

Как меняется начертание от lighter, bolder и font‑weight родителя

font-weight отвечает за «жирность», вес начертания. Задается в числах от 100 до 900.

Кроме числовых значений поддерживаются ключевые слова: normal, bold, lighter и bolder.

normal — это обычное начертание, синоним font-weight: 400

font‑weight: 400
font‑weight: normal

bold — жирное начертание, синоним font-weight: 700

font‑weight: 700
font‑weight: bold

Лучше использовать ключевые слова, а не их числовые значения: их проще воспринимать, не нужно запоминать магические числа.

Жирность начертания относительно родителя задаётся с помощью ключевых слов lighter (полегче) и bolder (пожирнее):

font‑weight: lighter
font‑weight: bolder

lighterfont‑weightbolder
light100, lightregular
light200, lightregular
light300, lightregular
light400, regularbold
light500, regularbold
regular600, boldbold
regular700, boldbold
bold800, boldbold
bold900, boldbold

Как меняется начертание от lighter, bolder и font‑weight родителя

Бюро­санс
Бюросайн

Бюросанс поддерживает тонкое, нормальное и жирное начертания. Бюросайн — вариативный шрифт, поддерживающий все начертания, включая промежуточные

Чтобы исполь­зо­вать какое‑то начер­та­ние, шрифт дол­жен его под­дер­жи­вать. В про­тив­ном слу­чае бра­у­зер под­бе­рёт бли­жай­шее под­хо­дя­щее начер­та­ние из тех, что доступны ему в шрифте.

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

Как и в обыч­ных шриф­тах для зада­ния «жир­но­сти» в вари­а­тив­ных шриф­тах нужно исполь­зо­вать font‑weight:
font-weight: 400

Бюросанс
Бюросайн

Бюросанс поддерживает тонкое, нормальное и жирное начертания. Бюросайн — вариативный шрифт, поддерживающий все начертания, включая промежуточные

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

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

Как и в обычных шрифтах для задания «жирности» в вариативных шрифтах нужно использовать font‑weight:
font-weight: 400

Скрыто 7 разворотов
Скрыто 7 раз­во­ро­тов

Ино­гда текст нужно допол­ни­тельно укра­сить: накло­нить, повер­нуть или рас­кра­сить. Для при­мера сти­ли­зуем заго­ловки. Нач­нём с разметки:

<h2>216 лекций, 97 часов</h2>
<p>…</p>

Настроим шрифт и начертание:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold; /* Жирное начертание */
  text-transform: uppercase; /* Буквы приводим к заглавным */
  letter-spacing: -.025em; /* Уменьшаем межбуквенное расстояние */
}

Доба­вим тень, обводку и поме­няем цвет текста:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  text-shadow: 5px 5px black; /* Добавляем чёрную тень, смещённую на 5 пк вправо-вниз */

  /* Добавляем двухпиксельную чёрную обводку буквам.
     
    Префикс -webkit- значит, что свойство пока не вошло
    в стандарты и работает в Хроме, Сафари, Эдже и Опере */
  -webkit-text-stroke: 2px black;
  color: white;
}

Иска­зим заголовки:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  text-shadow: 5px 5px black;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
}

Убе­рём тень, доба­вим под­за­го­ловку градиент:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
  /* linear-gradient — функция, генерирующая линейный градиент
    с заданным направлением, цветами и ключевыми точками */
  background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
}

Обре­жем гра­ди­ент по тексту:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
  background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
  -webkit-background-clip: text; /* Обрезаем фон по тексту */
  color: transparent; /* И меняем цвет текста на прозрачный */
}

45 лек­ций, 9 часов

45 лекций, 9 часов

Иногда текст нужно дополнительно украсить: наклонить, повернуть или раскрасить. Для примера стилизуем заголовки. Начнём с разметки:

<h2>216 лекций, 97 часов</h2>
<p>…</p>

Настроим шрифт и начертание:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold; /* Жирное начертание */
  text-transform: uppercase; /* Буквы приводим к заглавным */
  letter-spacing: -.025em; /* Уменьшаем межбуквенное расстояние */
}

Добавим тень, обводку и поменяем цвет текста:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  text-shadow: 5px 5px black; /* Добавляем чёрную тень, смещённую на 5 пк вправо-вниз */

  /* Добавляем двухпиксельную чёрную обводку буквам.
     
    Префикс -webkit- значит, что свойство пока не вошло
    в стандарты и работает в Хроме, Сафари, Эдже и Опере */
  -webkit-text-stroke: 2px black;
  color: white;
}

Исказим заголовки:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  text-shadow: 5px 5px black;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
}

Уберём тень, добавим подзаголовку градиент:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
  /* linear-gradient — функция, генерирующая линейный градиент
    с заданным направлением, цветами и ключевыми точками */
  background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
}

Обрежем градиент по тексту:

h2 {
  font-family: Roboto Condensed, sans-serif;
  font-weight: bold;
  text-transform: uppercase;
  -webkit-text-stroke: 2px black;
  color: white;
  transform: skew(0, -8deg);
  background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
  -webkit-background-clip: text; /* Обрезаем фон по тексту */
  color: transparent; /* И меняем цвет текста на прозрачный */
}

Скрыто: «Иллюстрации», «Таблицы» и ещё 1 глава
Скрыто: «Иллю­стра­ции», «Таб­лицы» и ещё 1 глава

Элементы ввода, или инпуты

В ХТМЛ‑фор­мах эле­менты ввода дают чело­веку вве­сти или уточ­нить дан­ные: поля, чек­боксы, радиокнопки, выпа­да­ю­щие списки и дру­гие эле­менты. Раз­ра­бот­чики назы­вают эле­менты ввода инпу­тами, потому что почти все­гда это тег input.

Инпуты отли­ча­ются типами — атри­бу­том type. Тип вли­яет на внеш­ний вид инпута и фор­ма­ти­ро­ва­ние вво­ди­мых данных.

Инпут с type="password" скроет вво­ди­мый текст, type="number" не даст вве­сти буквы, а type="date" пока­жет фор­мат ввода даты, а в неко­то­рых бра­у­зе­рах доба­вит кнопку вызова кален­да­рика. Фай­ло­вый инпут под­дер­жи­вает пере­тя­ги­ва­ние файла на себя, а инпут цвета откры­вает палитру выбора цвета.

Особ­ня­ком среди инпу­тов стоят чек­боксы, радиокнопки и выпа­да­ю­щие списки. Их вёрстка отли­ча­ется от вёрстки осталь­ных инпу­тов, поэтому далее мы раз­бе­рём их отдельно.

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

<input type="text">

type="text"

type="number"

type="password"

type="date"

type="datetime‑local"

type="time"

type="file"

type="color"

type="range"

Элементы ввода, или инпуты

В ХТМЛ‑формах элементы ввода дают человеку ввести или уточнить данные: поля, чекбоксы, радиокнопки, выпадающие списки и другие элементы. Разработчики называют элементы ввода инпутами, потому что почти всегда это тег input.

Инпуты отличаются типами — атрибутом type. Тип влияет на внешний вид инпута и форматирование вводимых данных.

Инпут с type="password" скроет вводимый текст, type="number" не даст ввести буквы, а type="date" покажет формат ввода даты, а в некоторых браузерах добавит кнопку вызова календарика. Файловый инпут поддерживает перетягивание файла на себя, а инпут цвета открывает палитру выбора цвета.

Особняком среди инпутов стоят чекбоксы, радиокнопки и выпадающие списки. Их вёрстка отличается от вёрстки остальных инпутов, поэтому далее мы разберём их отдельно.

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

<input type="text">

type="text"

type="number"

type="password"

type="date"

type="datetime‑local"

type="time"

type="file"

type="color"

type="range"

Скрыто: «Псевдоклассы» и «Псевдоэлементы :after и :before»
Скрыто: «Псев­до­классы» и «Псев­до­эле­менты :after и :before»

2
Расстановка

2
Расстановка

Позициони­ро­вание

Есть несколько спо­со­бов раз­ло­жить эле­менты по стра­нице: пози­ци­о­ни­ро­ва­ние, фло­аты, таб­лицы, флек­с­боксы и гриды. Мы посте­пенно раз­бе­рём их все, а нач­нём с самого про­стого — пози­ци­о­ни­ро­ва­ния свой­ством position.

По умол­ча­нию блоки выстра­и­ва­ются друг под дру­гом. С помо­щью position можно изме­нить это пове­де­ние и раз­ме­стить эле­мент в любом месте стра­ницы, задав ему коор­ди­наты свой­ствами top, right, left и bottom. Есть пять зна­че­ний свойства:

Static

Это зна­че­ние по умол­ча­нию, отсут­ствие какого‑либо пози­ци­о­ни­ро­ва­ния. Эле­менты про­сто выстра­и­ва­ются друг под другом.

Relative

Эле­мент с отно­си­тель­ным пози­ци­о­ни­ро­ва­нием сдви­га­ется со сво­его места, не влияя на поло­же­ние сосед­них элементов.

position: relative;
left: 6%;
top: 12%;

Absolute

Эле­мент с абсо­лют­ным пози­ци­о­ни­ро­ва­нием рас­по­ла­га­ется по задан­ным коор­ди­на­там, а из того места, где он был, удаляется.

position: absolute;
left: 6%;
top: 12%;

По умол­ча­нию эти коор­ди­наты отсчи­ты­ва­ются от окна. Но если у эле­мента есть роди­тель с position: relative или absolute, то коор­ди­наты будут отсчи­ты­ваться уже от него.

Fixed и sticky

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

position: sticky;
top: 18px;

Чаще всего исполь­зу­ется для «зали­па­ю­щих» эле­мен­тов. Напри­мер, с помо­щью position: sticky зали­пают иконки закладки и поиска в нашей книге. Ана­ло­гично рабо­тает и этот раз­во­рот: стра­ница с при­ме­ром зали­пает с position: sticky, а дру­гая прокручивается.

Позициони­ро­вание

Есть несколько способов разложить элементы по странице: позиционирование, флоаты, таблицы, флексбоксы и гриды. Мы постепенно разберём их все, а начнём с самого простого — позиционирования свойством position.

По умолчанию блоки выстраиваются друг под другом. С помощью position можно изменить это поведение и разместить элемент в любом месте страницы, задав ему координаты свойствами top, right, left и bottom. Есть пять значений свойства:

Static

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

Relative

Элемент с относительным позиционированием сдвигается со своего места, не влияя на положение соседних элементов.

position: relative;
left: 6%;
top: 12%;

Absolute

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

position: absolute;
left: 6%;
top: 12%;

По умолчанию эти координаты отсчитываются от окна. Но если у элемента есть родитель с position: relative или absolute, то координаты будут отсчитываться уже от него.

Fixed и sticky

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

position: sticky;
top: 18px;

Чаще всего используется для «залипающих» элементов. Например, с помощью position: sticky залипают иконки закладки и поиска в нашей книге. Аналогично работает и этот разворот: страница с примером залипает с position: sticky, а другая прокручивается.

position: relative

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

.dots { position: relative }
.dot { position: absolute } 

.top.left { top: 7px; left: 7px }
.top.right { top: 7px; right: 7px }
.bottom.left { bottom: 7px; left: 7px }
.bottom.right { bottom: 7px; right: 7px }

Важ­ный момент: абсо­лютно спо­зи­ци­о­ни­ро­ван­ный эле­мент будет отсчи­ты­вать свои коор­ди­наты от бли­жай­шего роди­теля с position: relative

.dots { position: relative }

.dot {
  position: absolute;
  top: 0;
  right: 0;
}

position: relative

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

.dots { position: relative }
.dot { position: absolute } 

.top.left { top: 7px; left: 7px }
.top.right { top: 7px; right: 7px }
.bottom.left { bottom: 7px; left: 7px }
.bottom.right { bottom: 7px; right: 7px }

Важный момент: абсолютно спозиционированный элемент будет отсчитывать свои координаты от ближайшего родителя с position: relative

.dots { position: relative }

.dot {
  position: absolute;
  top: 0;
  right: 0;
}
Скрыто 11 разворотов
Скрыто 11 раз­во­ро­тов

Упражнение: применение флексбокса

Пере­та­щите ЦСС‑свой­ства в селек­торы, чтобы пункты меню встали в ряд, а послед­ний пункт меню при­жался к пра­вому краю.


  
display: flex;
margin-left: auto;
nav {
}
nav li:last-child {
}

Вёрстка

Дизайн

Вёрстка

Дизайн

Упражнение: применение флексбокса

Перетащите ЦСС‑свойства в селекторы, чтобы пункты меню встали в ряд, а последний пункт меню прижался к правому краю.


  
display: flex;
margin-left: auto;
nav {
}
nav li:last-child {
}
Скрыт 1 разворот
Скрыт 1 раз­во­рот
Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

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

Нач­нём с раз­метки трех­ко­ло­ноч­ной страницы:

<header>
  <div>Логотип</div>
  …
</header>

<main>
  <article>
    <p>…</p>
  </article>
  
  <nav>
    <li>Навигация</li>
    …
  </nav>
  
  <aside>
    <div>Реклама</div>
    …
  </aside>
</main>

Пре­вра­тим шапку, содер­жи­мое и сайдбары во флекс‑кон­тей­неры и рас­кра­сим флекс‑эле­менты для наглядности:

header,
main,
aside,
nav {
  display: flex;
}

header > *,
article > *,
aside > *,
nav > * {
  min-height: 36px;
  padding: 9px;
  margin: 9px;
  background: #e5f5ff;
}

Обра­тите вни­ма­ние: по умол­ча­нию флекс‑эле­менты раз­ло­жи­лись в строку, flex-direction: row

Дадим стра­нице всю доступ­ную высоту, раз­ло­жим по вер­ти­кали и рас­тя­нем её содержимое:

body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

main {
  flex-grow: 1; /* Это заклинание заставляет <main> занять всё свободное пространство. Мы рассмотрим его чуть позже */
}

В левом сайдбаре раз­ло­жим эле­менты сверху вниз:

nav {
  flex-direction: column;
  justify-content: flex-start;
}

В пра­вом сайдбаре рав­но­мерно рас­пре­де­лим элементы:

aside {
  flex-direction: column;
  justify-content: space-between;
}

И поме­няем поря­док эле­мен­тов, чтобы колонка с нави­га­цией была слева:

nav {
  flex-direction: column;
  justify-content: flex-start;
  order: -1; /* И это свойство мы рассмотрим чуть позже */
}

По умол­ча­нию флекс‑эле­менты зани­мают столько места, сколько нужно их содер­жи­мому. Поэтому колонки с нави­га­цией и рекла­мой сжались.

Чтобы ширина коло­нок с нави­га­цией и рекла­мой не зави­села тек­ста, под­чи­ним вёрстку пяти­ко­ло­ноч­ной сетке. Зада­дим про­пор­ции, по кото­рым колонки и ста­тья делят сво­бод­ное место в 1:3:1:

nav {
  flex-direction: column;
  justify-content: flex-start;
  order: -1;
  flex-grow: 1;
  flex-basis: 0;
}

aside {
  flex-direction: column;
  justify-content: space-between;
  flex-grow: 1;
  flex-basis: 0;
}

article {
  flex-grow: 3;
  flex-basis: 0;
}
Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

Логотип
Новости
Проекты
О нас

Используя таблицу интегралов элементарных функций, получим: турбулентность волнообразна. Волна доступна. Теорема традиционно искажает неопровержимый вектор.

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

Начнём с разметки трехколоночной страницы:

<header>
  <div>Логотип</div>
  …
</header>

<main>
  <article>
    <p>…</p>
  </article>
  
  <nav>
    <li>Навигация</li>
    …
  </nav>
  
  <aside>
    <div>Реклама</div>
    …
  </aside>
</main>

Превратим шапку, содержимое и сайдбары во флекс‑контейнеры и раскрасим флекс‑элементы для наглядности:

header,
main,
aside,
nav {
  display: flex;
}

header > *,
article > *,
aside > *,
nav > * {
  min-height: 36px;
  padding: 9px;
  margin: 9px;
  background: #e5f5ff;
}

Обратите внимание: по умолчанию флекс‑элементы разложились в строку, flex-direction: row

Дадим странице всю доступную высоту, разложим по вертикали и растянем её содержимое:

body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

main {
  flex-grow: 1; /* Это заклинание заставляет <main> занять всё свободное пространство. Мы рассмотрим его чуть позже */
}

В левом сайдбаре разложим элементы сверху вниз:

nav {
  flex-direction: column;
  justify-content: flex-start;
}

В правом сайдбаре равномерно распределим элементы:

aside {
  flex-direction: column;
  justify-content: space-between;
}

И поменяем порядок элементов, чтобы колонка с навигацией была слева:

nav {
  flex-direction: column;
  justify-content: flex-start;
  order: -1; /* И это свойство мы рассмотрим чуть позже */
}

По умолчанию флекс‑элементы занимают столько места, сколько нужно их содержимому. Поэтому колонки с навигацией и рекламой сжались.

Чтобы ширина колонок с навигацией и рекламой не зависела текста, подчиним вёрстку пятиколоночной сетке. Зададим пропорции, по которым колонки и статья делят свободное место в 1:3:1:

nav {
  flex-direction: column;
  justify-content: flex-start;
  order: -1;
  flex-grow: 1;
  flex-basis: 0;
}

aside {
  flex-direction: column;
  justify-content: space-between;
  flex-grow: 1;
  flex-basis: 0;
}

article {
  flex-grow: 3;
  flex-basis: 0;
}
Скрыто 5 разворотов
Скрыто 5 раз­во­ро­тов

Чтобы лучше понять флексбоксы, проведём аналогию с авто лейаутом из Фигмы

Стрелки в левой колонке отвечают за направление главной оси:

  • flex‑wrap: wrap

  • flex‑direction: row

  • flex‑direction: column

Расстояние между элементами задаётся с помощью gap

Отступы снаружи элементов задаются с помощью свойств контейнера:

  • padding‑left и padding‑right

  • padding‑top и padding‑bottom

Выравнивание задаётся комбинацией свойств:

  • justify‑content: flex‑start; align‑items: flex‑start
  • justify‑content: center; align‑items: flex‑start
  • justify‑content: flex‑end; align‑items: flex‑start
  • justify‑content: flex‑start; align‑items: center
  • justify‑content: center; align‑items: center
  • justify‑content: flex‑end; align‑items: center
  • justify‑content: flex‑start; align‑items: flex‑end
  • justify‑content: center; align‑items: flex‑end
  • justify‑content: flex‑end; align‑items: flex‑end

flex‑wrap: wrap

flex‑direction: row

flex‑direction: column

gap

padding‑left и padding‑right

padding‑top и padding‑bottom

justify‑content: flex‑start; align‑items: flex‑start

justify‑content: center; align‑items: flex‑start

justify‑content: flex‑end; align‑items: flex‑start

justify‑content: flex‑start; align‑items: center

justify‑content: center; align‑items: center

justify‑content: flex‑end; align‑items: center

justify‑content: flex‑start; align‑items: flex‑end

justify‑content: center; align‑items: flex‑end

justify‑content: flex‑end; align‑items: flex‑end

Чтобы лучше понять флексбоксы, проведём аналогию с авто лейаутом из Фигмы.

Стрелки в левой колонке отвечают за направление главной оси:

  • flex‑wrap: wrap
  • flex‑direction: row
  • flex‑direction: column

Расстояние между элементами задаётся с помощью gap

Отступы снаружи элементов задаются с помощью свойств контейнера:

  • padding‑left и padding‑right
  • padding‑top и padding‑bottom

Выравнивание задаётся комбинацией свойств:

  • justify‑content: flex‑start; align‑items: flex‑start
  • justify‑content: center; align‑items: flex‑start
  • justify‑content: flex‑end; align‑items: flex‑start
  • justify‑content: flex‑start; align‑items: center
  • justify‑content: center; align‑items: center
  • justify‑content: flex‑end; align‑items: center
  • justify‑content: flex‑start; align‑items: flex‑end
  • justify‑content: center; align‑items: flex‑end
  • justify‑content: flex‑end; align‑items: flex‑end
Скрыто 20 разворотов
Скрыто 20 раз­во­ро­тов

С помо­щью grid-auto-columns и grid-auto-flow можно собрать адап­тив­ные колонки, рав­но­мерно деля­щие доступ­ное пространство:

.cols {
  display: grid; /* Включаем гриды */
  grid-auto-columns: minmax(100px, 1fr); /* Пусть неявные колонки равномерно делят свободное пространство, сохраняя минимальную ширину в 100 пк */
  grid-auto-flow: column; /* Пусть невлезающие элементы выстраиваются в колонки */
  gap: 18px; /* Задаём межколонник в 18 пк */
  height: 100%; /* Растягиваем колонки по высоте */
}
<div class="cols">
  <div>Первая колонка</div>
  …
  <div>Четвёртая колонка</div>
</div>

<div class="cols">
  <div>Первая колонка</div>
  <div>Вторая колонка</div>
</div>

<div class="cols">
  <div>Первая колонка</div>
  …
  <div>Пятая колонка</div>
</div>
Пер­вая колонка
Вто­рая колонка
Тре­тья колонка
Чет­вёр­тая колонка
Пер­вая колонка
Вто­рая колонка
Пер­вая колонка
Вто­рая колонка
Тре­тья колонка
Чет­вёр­тая колонка
Пятая колонка
Первая колонка
Вторая колонка
Третья колонка
Чет­вёр­тая колонка
Первая колонка
Вторая колонка
Первая колонка
Вторая колонка
Третья колонка
Чет­вёр­тая колонка
Пятая колонка

С помощью grid-auto-columns и grid-auto-flow можно собрать адаптивные колонки, равномерно делящие доступное пространство:

.cols {
  display: grid; /* Включаем гриды */
  grid-auto-columns: minmax(100px, 1fr); /* Пусть неявные колонки равномерно делят свободное пространство, сохраняя минимальную ширину в 100 пк */
  grid-auto-flow: column; /* Пусть невлезающие элементы выстраиваются в колонки */
  gap: 18px; /* Задаём межколонник в 18 пк */
  height: 100%; /* Растягиваем колонки по высоте */
}
<div class="cols">
  <div>Первая колонка</div>
  …
  <div>Четвёртая колонка</div>
</div>

<div class="cols">
  <div>Первая колонка</div>
  <div>Вторая колонка</div>
</div>

<div class="cols">
  <div>Первая колонка</div>
  …
  <div>Пятая колонка</div>
</div>
Скрыто 2 разворота
Скрыто 2 раз­во­рота

Meet Dynamic Island

48MP Main camera

The mastermind behind it all

A battery that’s all in, all day.

Film like a Pro.

Shaky shots, stable video

Always‑On display

Tougher than any smartphone glass

Water resistance

Emergency SOS via satellite

A camera in a class by itselfie.

Если в каче­стве зна­че­ний grid‑column или grid‑row задать auto, бра­у­зер сам решит, что делать с эле­мен­том и его пози­цией: эле­менты раз­ме­стятся в том же порядке, что и в коде, зани­мая по одной ячейке. Но если исполь­зо­вать auto / span N, то эле­мент зай­мёт N коло­нок или строк, начи­ная с теку­щего места. Так можно полу­чить «пли­точ­ную вёрстку», в кото­рой поря­док и раз­меры эле­мен­тов опре­де­ля­ются их раз­мет­кой. Напри­мер, как на про­мо­стра­ни­цах Эпла.

Чтобы свер­стать похо­жие этажи, вклю­чим гриды, зада­дим направ­ля­ю­щие и вве­дём четыре вари­а­ции плиток:

.grid {
  display: grid; /* Включаем раскладку гридами  */
  grid-template-columns: 1.85fr 1fr 1.85fr; /* Задаём резиновые направляющие для колонок: первая и третья в 1,85 раза больше центральной */
  grid-auto-rows: 320px; /* Задаём автоматические направляющие для строк: каждые 320 пикселей */
  gap: 20px; /* Задаём межстрочник и межколонник в 20 пк */
  background: #161617;
}

.tile {
  padding: 15px;
  border-radius: 15px;
  background: #000;
  color: #ffb6ff;
}

/* «Плитка» на одну ячейку */
.tile-1-cols-1-rows {
  grid-column: auto / span 1;
  grid-row: auto / span 1;
}

/* Плитка на одну колонку и две строки */
.tile-1-cols-2-rows {
  grid-column: auto / span 1;
  grid-row: auto / span 2;
}

/* Плитка на две колонки и одну строку */
.tile-2-cols-1-rows {
  grid-column: auto / span 2;
  grid-row: auto / span 1;
}

/* Плитка на 2 колонки и 2 строки */
.tile-2-cols-2-rows {
  grid-column: auto / span 2;
  grid-row: auto / span 2;
}
<div class="grid">
  <div class="tile tile-2-cols-2-rows">
    <h2>Meet Dynamic Island</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>48MP Main camera</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>The mastermind behind it all</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <p>A battery that’s all in, all day.</p>
  </div>
  <div class="tile tile-2-cols-1-rows">
    <p>Film like a Pro.</p>
  </div>
  <div class="tile tile-1-cols-2-rows">
    <p>Shaky shots, stable video</p>
  </div>
  <div class="tile tile-2-cols-2-rows">
    <h2>Always-On display</h2>
  </div>
  <div class="tile tile-2-cols-2-rows">
    <h2>Tougher than any smartphone glass</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>Water resistance</h2>
  </div>
  <div class="tile tile-1-cols-2-rows">
    <h2>Emergency SOS via satellite</h2>
  </div>
  <div class="tile tile-2-cols-1-rows">
    <p>A camera in a class by itselfie.</p>
  </div>
</div>

Meet Dynamic Island

48MP Main camera

The mastermind behind it all

A battery that’s all in, all day.

Film like a Pro.

Shaky shots, stable video

Always‑On display

Tougher than any smartphone glass

Water resistance

Emergency SOS via satellite

A camera in a class by itselfie.

Если в качестве значений grid‑column или grid‑row задать auto, браузер сам решит, что делать с элементом и его позицией: элементы разместятся в том же порядке, что и в коде, занимая по одной ячейке. Но если использовать auto / span N, то элемент займёт N колонок или строк, начиная с текущего места. Так можно получить «плиточную вёрстку», в которой порядок и размеры элементов определяются их разметкой. Например, как на промостраницах Эпла.

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

.grid {
  display: grid; /* Включаем раскладку гридами  */
  grid-template-columns: 1.85fr 1fr 1.85fr; /* Задаём резиновые направляющие для колонок: первая и третья в 1,85 раза больше центральной */
  grid-auto-rows: 320px; /* Задаём автоматические направляющие для строк: каждые 320 пикселей */
  gap: 20px; /* Задаём межстрочник и межколонник в 20 пк */
  background: #161617;
}

.tile {
  padding: 15px;
  border-radius: 15px;
  background: #000;
  color: #ffb6ff;
}

/* «Плитка» на одну ячейку */
.tile-1-cols-1-rows {
  grid-column: auto / span 1;
  grid-row: auto / span 1;
}

/* Плитка на одну колонку и две строки */
.tile-1-cols-2-rows {
  grid-column: auto / span 1;
  grid-row: auto / span 2;
}

/* Плитка на две колонки и одну строку */
.tile-2-cols-1-rows {
  grid-column: auto / span 2;
  grid-row: auto / span 1;
}

/* Плитка на 2 колонки и 2 строки */
.tile-2-cols-2-rows {
  grid-column: auto / span 2;
  grid-row: auto / span 2;
}
<div class="grid">
  <div class="tile tile-2-cols-2-rows">
    <h2>Meet Dynamic Island</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>48MP Main camera</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>The mastermind behind it all</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <p>A battery that’s all in, all day.</p>
  </div>
  <div class="tile tile-2-cols-1-rows">
    <p>Film like a Pro.</p>
  </div>
  <div class="tile tile-1-cols-2-rows">
    <p>Shaky shots, stable video</p>
  </div>
  <div class="tile tile-2-cols-2-rows">
    <h2>Always-On display</h2>
  </div>
  <div class="tile tile-2-cols-2-rows">
    <h2>Tougher than any smartphone glass</h2>
  </div>
  <div class="tile tile-1-cols-1-rows">
    <h2>Water resistance</h2>
  </div>
  <div class="tile tile-1-cols-2-rows">
    <h2>Emergency SOS via satellite</h2>
  </div>
  <div class="tile tile-2-cols-1-rows">
    <p>A camera in a class by itselfie.</p>
  </div>
</div>
Скрыто 8 разворотов
Скрыто 8 раз­во­ро­тов

Текст внутри эле­мен­тов сам адап­ти­ру­ется под их ширину.

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

Для тек­сто­вых эле­мен­тов полезно огра­ни­чи­вать ширину через min-width и max-width, чтобы ширина тек­ста оста­ва­лась ком­форт­ной для чтения.

Рабо­таем с
1997 года.
Экс­перты на 
рынке авто­услуг.
Зво­ните: 8 800 301‑
64‑40

Рабо­таем
с 1997 года.
Экс­перты на рынке
авто­услуг.
Зво­ните:
8 800 301‑64‑40

Работаем с
1997 года.
Эксперты на 
рынке автоуслуг.
Звоните: 8 800 301‑
64‑40

Работаем
с 1997 года.
Эксперты на рынке
автоуслуг.
Звоните:
8 800 301‑64‑40

Текст внутри элементов сам адаптируется под их ширину.

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

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

Скрыто: страницы, спецэффекты
Скрыто: стра­ницы, спе­ц­эф­фекты
Скрыто: контроль качества, тестирование вёрстки
Скрыто: кон­троль каче­ства, тести­ро­ва­ние вёрстки
Скрыто: хостинг и домен, шаринг в соцсети, аналитика и статистика посещений
Скрыто: хостинг и домен, шаринг в соц­сети, ана­ли­тика и ста­ти­стика посе­ще­ний
Скрыто: работа с верстальщиком
Скрыто: работа с вер­сталь­щи­ком