HTML и CSS

HTML – язык для браузера, который говорит что и как отображать.

Сразу перейдем к примерам. Создадим файл page.html со следующим содержимым:

<h1>Текст заголовка</h1>
<p>Это параграф текста</p>

<article>
  <p>Первый параграф статьи</p>
  <p>Второй параграф статьи</p>
</article>

Если открыть файл в браузере то увидем примерно следующее:

Все что было внутри угловых скобок < и > оказалось скрыто. То были теги <h1> для заголовка, <p> для параграфа текста и <article> для статьи. Они сообщили браузеру на какие блоки разбит текст и тот построил иерархическую струтуру данных - Document Object Model, сокращенно, DOM - которая затем используется для отрисовки страницы и для доступа к содержимому документа из JavaScript. Схематично, DOM для нашего примера выглядит так:

Все что оказалось внутри тега <article> .... </article>, а это два параграфа с текстом <p>...</p>, стало дочерними элементами тега article.

Браузер отрисовывает страницу руководствуясь содержимым DOM. Схематично, выглядит это так:

Браузер берет первый элемент DOM дерева — тег h1 —, определяет положение этого блока на странице и размещает внутри него строку "Текст заголовка". Затем он берет следующий элемент — тег <p> и повторяет свои действия. Очередь доходит до тега article, и с ним все несколько сложнее из-за наличия дочерних элементов. Определив горизонтальную границу блока article браузер переходит к отрисовке дочерних элементов — двух тегов p - сверху вниз, попутно вычисляя высоту блока article.

Хорошую статью с примерами и иллюстрациями DOM можно найти на Хабрахабре.

Атрибуты тегов

У каждого тега есть набор атрибутов влияющих на его поведение. Их можно сразу указать в HTML разметке страницы, либо позднее назначить с помощью JavaScript кода. Например, у ссылок есть атрибут href, он содержит URL адрес этой ссылки:

<a href="https://devman.org/challenges/">Задачи</a>

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

<tag attr1name="attr1value" attr2name="attr2value" ...>

Кроме специфических атрибутов, как-то href для ссылки или value для поля ввода, есть набор универсальных атрибутов. Их можно использовать для любого тега.

style настраивает оформление тега: отступы, цвет, размер шрифта и прочее.

id назначает тегу уникальный идентификатор. Например:

<article id="chapter1">
...
</article>

Указанный id не может повторно использоваться в документе, первая глава "chapter1" может быть только одна. Атрибут id удобен для быстрой навигации по DOM дереву из JavaScript кода, см document.getElementById. Также полезен в качестве якоря на страницах.

class назначает тегу набор неуникальных идентификаторов. Используется для привязки стилей в CSS, удобен для навигации по DOM дереву в JavaScript коде. Например, вот так может выглядеть большая синяя кнопка на странице:

<button class="btn btn-lg btn-primary btn-disabled">Сохранить</button>

data-* присваивает тегу данные в формате JSON для последующей работы с ними из JavaScript кода. Подробно описано на сайте Mozilla Developer Network, MDN - здесь.

Шаблон HTML документа

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

<!DOCTYPE html>
<html>
  <!-- тег самого верхнего уровня, включается в себя весь HTML документ -->
  <head>
    <!-- теги ниже не отображаются, но содержат много важных настроек и мета-информации -->
    <meta charset="utf-8"><!-- кодировка нижеследующей разметки -->
    <title>Название страницы, отображается на вкладке браузера и в закладках</title>
  </head>`
  <body>
    <!--Основное содержимое страницы-->
    <p>здесь живут все видимые теги</p>
  </body>
</html>

Подробно структура документа разобрана на Структура HTML документа.

Стили

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

Рассмотрим пример. Для каждого тега на странице укажем border. На вкладке «Result» виджета JSFiddle виден результат отрисовки.

Другой пример. Выделим цитату на фоне остального текста.

Стили позволяют сильно изменить внешний вид тегов. Также можно изменить алгоритм их отрисовки. Размещение блоков на странице сверху вниз в том порядке, в каком теги встречаются в HTML разметке называется Normal layout flow. С помощью свойств position, float и display можно переключить движок браузера в другой режим. Для примера разместим блоки справа налево.

Набор правил по которым браузер вычисляет размер блоков/тегов с учетом padding, margin, border и прочих свойств называется CSS Box Model. С ним полезно ознакомиться.

Писать стили для HTML разметки не всегда просто. Если задача не имеет очевидного решения, начать поиски стоит со Stack Overflow. На этом сайте собрано большое количество рецептов по верстке.

Самый полезный инструмент в арсенале верстальщика - это Chrome DevTools. Он позволяет найти тег на странице, проверить его стили и дописать новые, узнать размер блока, отредактировать его содержимое и все это в интерактивном режиме. Знакомство стоит начать с inspecting the DOM and styles.

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

CSS

Cascading Style Sheets, они же каскадные таблицы стилей, позволяют привязывать стили к целым группам тегов. Например, можно разом изменить цвет всех ссылок на черный, использовать bold шрифт. Как это сделать:

<style>
  a {
    color: black;
    font-weight: bold;
  }
</style>

<a href="https://stackoverflow.com/">Stack Overflow</a>
....
<a href="#top">Вернуться назад</a>

CSS правила помещаются внутрь тега <style>, стили указываются внутри фигурных скобок, символ ; служит разделителем. Подробное синтаксис описан здесь.

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

<style>
  .btn {
    padding: 6px 12px;
    font-size: 14px;
  }
  .btn-blue {
    background-color: blue;
  }
</style>

<button class="btn btn-blue">Синяя кнопка</a>
....
<button class="btn">Серая кнопка</a>
<button>Стандартная кнопка</a>

Как видно из примера выше тег "Синяя кнопка" получил стили сразу двух селекторов .btn и .btn-blue. Классы и CSS правила можно смешивать в рамках одного тега, последовательность применения правил и приоритет описаны на странице Cascade and inheritance. Правила эти довольно запутанные, упрощенно их можно сформулировать так:

  • Стили описанные в атрибуте style считаются самыми приоритетными. Их уже не переопределить.
  • Чем специфичней селектор - чем больше в нем указано сведений о теге -, тем он приоритетнее.
  • В селекторе класс ценится выше названия тега. Селектор .btn специфичнее чем button.
  • Из двух одинаковых или одинаково специфичных селекторов побеждает тот который находится ниже в HTML документе.
  • Самый низкий приоритет у стандартных стилей браузера.

Примеры селекторов с пояснениями есть в том же туториале MDN:

Сайты, как правило, состоят из большого количества страниц. Чтобы не дублировать содержимое тега <style> стили выносят в отдельный файл и затем подключают его внутри <head> документа:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="/style.css">
  </head>
  <body>
    ...
  </body>
</html>

Браузер самостоятельно подгрузит файл style.css с сервера.

Во внешние CSS файлы стараются вынести весь код пригодный для повторного использования. В теге <style> оставляют только стили специфичные для данной страницы.

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

  • Сайт сначала верстают под экран смартфона, а уже затем адаптируют под большие экраны: растягивают элементы, добавляют отступы по краям страницы, размещают баннеры. Этот подход получил название «Mobile First».
  • В спецификации CSS3 появились media-queries. Часть правил активируется только при заданной ширине экрана браузера.

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

<style>
.article p {
  font-size: 12px;
}

@media (min-width: 1200px) {
  .article p {
    font-size: 14px;
  }
}
@media (max-width: 768px) {
  .article p {
    font-size: 10px;
  }
}
</style>

Для ознакомления полезно посмотреть больше примеров с media queries.

Еще одна древняя проблема это анимация HTML разметки: чтобы сообщения появлялись красиво и плавно, чтобы навигационное меню выезжало слева. Раньше все это делалось средствами JS, что приводило к низкой производительности. Браузеру сложно перерисовывать страницу десять раз в секунду. И вот, появилась CSS анимация. Она оптимизирована по производительности, почти не требует JS, работает "из коробки". Примеры можно посмотреть там же, на сайте MDN.

Со временем Веб становится все красочнее. Возможности браузеров и компьютеров растут, дизайнеры спешат привнести что-то новое, свежее. Теперь даже одностраничный лендинг требует многих тысяч строк кода CSS. Энтузиастов готовых писать такое раз за разом с нуля становится все меньше. Чтобы сократить объем работы придумали фреймворки. Это библиотеки с большим количеством стилизованных и хорошо подогнанных друг к другу элементов. Один из самых популярных — это Bootstrap. От фреймворка разработчик получает мощные механизмы адаптивной верстки, богатый набор стандартных элементов, инструменты для создания своих тем. Когда на одной чаше весов 10К строк глючного CSS, а на другой Bootstrap + 400 тривиальных строк кода, многие выбирают второй вариант.

Валидация верстки и CSS

Одна из частых проблем на сайтах — это сломанная верстка. Где-то забыли закрыть тег, где-то опечатались в названии стиля. Не всегда ошибки бросаются глаза, порой заметны они становятся только в других браузерах. Например, разрабатываешь под Chrome, а в Firefox все ломается, потому что движок webkit менее чувствителен к ошибкам верстальщика.

Для решения этой проблемы создали автоматические валидаторы верстки. Один из самых популярных это W3C HTML Validator. Все что нужно — это указать URL страницы сайта либо загрузить файл с HTML разметкой.

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

Форматирование кода HTML и CSS

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

Соблюдай отступы в HTML и CSS

Вот так плохо:

<section class="slide"
  id="9">
    <div>
    <h2>KPI бывают разными</h2>
        <div>Зависит от задач бизнеса</div>
      <ul>
    <li class="next">Воронка продаж и конверсия</li>
  <li class="next">
    Посещаемость сайта</li>
    <li class="next">Источники переходов на сайт</li>
    ...

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

  <section class="slide" id="9">
    <div>
      <h2>KPI бывают разными</h2>
      <div>Зависит от задач бизнеса</div>
      <ul>
        <li class="next">Воронка продаж и конверсия</li>
        <li class="next">Посещаемость сайта</li>
        <li class="next">Источники переходов на сайт</li>
        ...

В качестве размера отступа в HTML, CSS и JS принято использовать 2 пробела, против 4х в Python.

CSS тоже должен быть пригоден для быстрой навигации по нему. Вот так плохо:

.selector, .selector-secondary, .selector[type=text]{padding:50px; margin:0px 0px 15px; background-color: #f5f5f5; font-size: 10px;}
.btn{padding: 5px;}

Так лучше:

/* по одному селектору на строку */
.selector,
.selector-secondary,
.selector[type=text] {
  /* по одному правилу на строку */
  padding:50px;
  margin:0px 0px 15px;
  background-color: #f5f5f5;
  font-size: 10px;
}
.btn {
  padding: 5px;
}

В разметке HTML и CSS также не стоит использовать табуляцию. Она по-разному отображается в текстовых редакторах и на GitHub. Лучше обозначать отступ двумя пробелами.

Правила оформления кода на проекте могут отличаться от рекомендованных, по историческим причинам. Важно придерживаться стиля принятого в команде. Для этого используют EditorConfig. Установи расширение для своей IDE/текстового редактора, оно автоматически подхватит настройки из файла .editorconfig в репозитории проекта. Для нового проекта можно воспользоваться настройками рекомендованными Devman.

Более полное руководство есть на сайте Академии HTML.

Что дальше

HTML надо знать, даже если вы занимаетесь только серверным программированием. Постоянно надо что-то оживить, доделать в шаблоне или распарсить.

Тегов существует огромное количество, и еще больше разных стилей к ним. Все их знать не обязательно. Часто встречаются 30-40 тегов, и они покрывают 99% потребностей.

Вот полезные ресурсы: