Во всех браузерах элементу body через таблицу стилей по умолчанию добавляется внешний отступ 8px. Но почему именно 8px? Разбираемся вместе с автором книги Jump Start Sass: Get Up to Speed With Sass in a Weekend к старту курса по Fullstack-разработке на Python.


Исходные значения против браузерных значений по умолчанию

У каждого свойства в CSS есть исходное значение, одинаковое для всех элементов во всём вебе. Для display — это inline, а для каждого свойства margin — 0.

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

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

/* you can't get any more 'reset' than this */
* { all: initial !important; }

Потому и нужны стили браузера: от одного элемента к другому у них разные значения по умолчанию. Есть блочные элементы display: block (элементы группировки контента, абзацы, списки, заголовки и т. д.), в них используются отступы — для лучшего удобства восприятия.

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

Стандартизация значений браузера по умолчанию

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

  • Сбросами удаляют значения по умолчанию, чтобы «сделать холст чище».

  • С помощью нормализаторов значения по умолчанию в браузерах становятся более согласованными.

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

Не уверена, есть ли где-то более новая версия (не нашла её).

Таблица стилей CSS 2.2 по умолчанию
html, address,
blockquote,
body, dd, div,
dl, dt, fieldset, form,
frame, frameset,
h1, h2, h3, h4,
h5, h6, noframes,
ol, p, ul, center,
dir, hr, menu, pre   { display: block; unicode-bidi: embed }
li              { display: list-item }
head            { display: none }
table           { display: table }
tr              { display: table-row }
thead           { display: table-header-group }
tbody           { display: table-row-group }
tfoot           { display: table-footer-group }
col             { display: table-column }
colgroup        { display: table-column-group }
td, th          { display: table-cell }
caption         { display: table-caption }
th              { font-weight: bolder; text-align: center }
caption         { text-align: center }
body            { margin: 8px }
h1              { font-size: 2em; margin: .67em 0 }
h2              { font-size: 1.5em; margin: .75em 0 }
h3              { font-size: 1.17em; margin: .83em 0 }
h4, p,
blockquote, ul,
fieldset, form,
ol, dl, dir,
menu            { margin: 1.12em 0 }
h5              { font-size: .83em; margin: 1.5em 0 }
h6              { font-size: .75em; margin: 1.67em 0 }
h1, h2, h3, h4,
h5, h6, b,
strong          { font-weight: bolder }
blockquote      { margin-left: 40px; margin-right: 40px }
i, cite, em,
var, address    { font-style: italic }
pre, tt, code,
kbd, samp       { font-family: monospace }
pre             { white-space: pre }
button, textarea,
input, select   { display: inline-block }
big             { font-size: 1.17em }
small, sub, sup { font-size: .83em }
sub             { vertical-align: sub }
sup             { vertical-align: super }
table           { border-spacing: 2px; }
thead, tbody,
tfoot           { vertical-align: middle }
td, th, tr      { vertical-align: inherit }
s, strike, del  { text-decoration: line-through }
hr              { border: 1px inset }
ol, ul, dir,
menu, dd        { margin-left: 40px }
ol              { list-style-type: decimal }
ol ul, ul ol,
ul ul, ol ol    { margin-top: 0; margin-bottom: 0 }
u, ins          { text-decoration: underline }
br:before       { content: "\A"; white-space: pre-line }
center          { text-align: center }
:link, :visited { text-decoration: underline }
:focus          { outline: thin dotted invert }

/* Begin bidirectionality settings (do not change) */
BDO[DIR="ltr"]  { direction: ltr; unicode-bidi: bidi-override }
BDO[DIR="rtl"]  { direction: rtl; unicode-bidi: bidi-override }

*[DIR="ltr"]    { direction: ltr; unicode-bidi: embed }
*[DIR="rtl"]    { direction: rtl; unicode-bidi: embed }

@media print {
  h1            { page-break-before: always }
  h1, h2, h3,
  h4, h5, h6    { page-break-after: avoid }
  ul, ol, dl    { page-break-before: avoid }
}

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

body { margin: 8px; }

Понятно, что по краям документа нужен интервал по умолчанию, но почему 8px? Откуда он взялся?

Ничто и никогда не исчезает бесследно

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

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

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

В сегодняшних браузерах многие стили по умолчанию — это те же значения по умолчанию, что были во время появления HTML-элемента.

Спецификация: чистота против реальности

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

Стандарт не имеет смысла, если он не описывает реальность.

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

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

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

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

Внешний отступ во всех элементах body

В прошлом месяце я решила проследить истоки этого стиля:

body { margin: 8px; }

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

Но откуда он взялся изначально? Я задала вопрос в Твиттере, и в итоге отследить стиль в целом удалось.

Шаг первый. Спецификация

Алан Стернс — один из нынешних руководителей рабочей группы CSS — указал мне на первую спецификацию с отступом 8px в таблице стилей по умолчанию:

«Сама спецификация появилась в 2003 году. В версии предыдущего года был внутренний отступ 8px».

«Ой, ошибся на год. Внутренний отступ был в 2003 году. В 2004-м изменён на внешний».

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

Шаг 2. Первые браузеры

Есть ссылки, по которым я иногда перехожу, когда хочу почитать об истории CSS. Мои любимые — это документы-источники:

Кроме того, есть отличные статьи о появлении CSS:

  • Краткая история CSS до 2016 года от соавтора оригинальной спецификации CSS Берта Боса.

  • Оглядываясь на историю CSS Джея Хоффмана о хитростях CSS.

  • Языки, которые чуть не стали CSS Зака Блума.

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

«Кстати, IE3 был первым коммерческим браузером с CSS. Это 1996 год. Затем в Netscape 4 добавили поддержку. Но раньше этих двух CSS тестировался на Argo и Arena… Как давно это было???»

Шаг третий. Архивы www-talk и www-style

Конечно, большинство этих исторических предложений по стилю изначально написаны как электронные письма списка рассылки www-talk@w3.org или позже на специально отведённый для них список рассылки www-style@w3.org. Оба списка хорошо архивированы, по ним возможен поиск. Это одно из преимуществ среды, созданной кучкой гиков, помешанных на информатике.

Порывшись в архивах, я наткнулась на письмо Тодда Фарнера за март 1998 года:

«В моей последней редакции «Базовой таблицы стилей» задан внешний отступ 0, а внутренний — 8 пикселей. Ранее внешний был 8 пикселей, внутренний — 0, а позиция фонового изображения — -8px».

Это ветка почтовой переписки, посвящённой правильной обработке фоновых изображений. Не совсем по теме, но есть внешние/внутренние отступы 8px элемента body.

Шаг четвёртый. The wayback machine

Ссылка на редакцию выше не сработала, поэтому я рванула на The WayBack Machine. Нет ли там архивной копии? Есть, и не одна!

Сначала я попала в базовую таблицу стилей от 22 февраля 1999 года, которая последний раз менялась 7 ноября 1998 года. Затем перешла к самому первому архиву страницы — базовой таблице стилей от 30 января 1998 года. Последнее изменение было 04.07.2022 в 16:39:51 по Гринвичу: в тот самый момент я загрузила страницу. Что? Просматривая исходный код, я обнаружила следующее:

<p>
  This is a work in progress, last modified
  <script>document.write(document.lastModified);</script>
  <noscript>quite recently</noscript> GMT...
</p>

Значит, document.lastModified обновляется в The WayBack Machine при каждой загрузке страницы?

Базовая таблица стилей

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

«В базовой таблице стилей описывается «согласованный по умолчанию» рендеринг всех элементов HTML 4.0 в браузерах-потомках Mosaic (Netscape Navigator и Microsoft Internet Explorer). И … фиксируется статус-кво, чтобы идти дальше».

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

«Якобы нейтральная в браузере Mosaic таблица стилей по умолчанию — это простая адаптация нормативного стиля для (печатных) научных работ в Европе (cf. Wanning, Frank; Internationaler Typographie und wissenschaftliche Textverarbeitung; Haag + Herchen, 1996).

Вполне допустимо с учётом того, что Интернет появился в ЦЕРН. Но в свете гораздо большего распространения Интернета в коммерции, развлечениях, журналистике и гуманитарных науках, а также глубоко укоренившегося доминирования на рынке браузеров на основе Mosaic справедливо утверждать, что «правильный» HTML заражён ненадлежащим стилем, как раком или вирусом.

В результате распространения вируса таблицы стилей по умолчанию (браузера Mosaic) из научного сообщества ЦЕРН в Интернете появились поколения инструментов-мутантов и авторов, которые неправильно используют разметку исключительно для вызова определённых эффектов этой таблицы. Примеры сигнатур — использование <p> для создания вертикальных пробелов и табличных структур для нетабулярной информации.

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

Чтобы обратить вспять эту эпидемию, необходимо сначала изолировать вирус и подвергнуть его гены точным и всесторонним манипуляциям. Базовая таблица стилей — это модель CSS1 вируса таблицы стилей по умолчанию (браузера Mosaic) и первый шаг к разработке «стилевых антител», то есть полноценных альтернативных таблиц стилей для HTML».

Вот и всё. Эта таблица стилей нужна для захвата того, что уже происходило до существования CSS в браузерах на основе Mosaic, и воссоздания этих стилей в CSS. Интервал 8px в элементе body появился раньше CSS! Похоже, истоки стиля напрямую восходят к внутренним правилам Mosaic (ещё до появления CSS), поэтому остаётся один вопрос: представить его как внутренний или внешний отступ.

Базовая таблица стилей Тодда Фарнера (черновой вариант)
A, ABBR, ACRONYM, ADDRESS, BDO, BLOCKQUOTE, BODY, BUTTON, CITE, CODE, DD, DEL,
DFN, DIV, DL, DT, EM, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HTML, IFRAME, IMG, INS,
KBD, LABEL, LI, OBJECT, OL, P, Q, SAMP, SPAN, STRONG, SUB, SUP, UL, VAR,
APPLET, B, BIG, CENTER, DIR, FONT, HR, I, MENU, PRE, S, SMALL, STRIKE, TT, U {
  background: transparent;
  width: auto;
  height: auto;
  text-decoration: none;
  margin: 0;
  padding: 0;
  border: 0;
  float: none;
  clear: none;
  vertical-align: baseline;
  list-style-image: none;
  list-style-type: disc;
  list-style-position: outside;
  }

ADDRESS, BLOCKQUOTE, BODY, DD, DIV, DL, DT, FIELDSET, FORM, H1, H2, H3, H4, H5,
H6, OL, P, UL, CENTER, DIR, HR, MENU, PRE {
  display: block;
  }

A, ABBR, ACRONYM, APPLET, BDO, BUTTON, CITE, CODE, DEL, DFN, EM, IFRAME, IMG,
INS, KBD, LABEL, OBJECT, Q,
SAMP, SPAN, STRONG, SUB, SUP, VAR, B, BIG, FONT, I, S, SMALL, STRIKE, TT, U {
  display: inline;
  }

LI {
  display: list-item;
  }

/* Begin tree of inherited properties and cascades. */

/* Describes the default type, color, and link decoration specs of
Mosaic-derivative browsers to the extent and degree of granularity that users
may typically override. Uncomment for "factory settings." */

HTML {
  font-family: "Times New Roman", Times;
  font-size: medium;
  color: black;
  background-color: #BFBFBF;
  }

PRE, TT, CODE, KBD, SAMP {
  font-family: "Courier New", Courier;
  }

A:link, A:visited, A:active {
  text-decoration: underline;
  }

A:link {
  color: #0000FF;
  }

A:visited {
  color: #7F007F;
  }

A:active {
  color: #0000FF;
  }

end pre-CSS user settings */

HTML {
  line-height: 1.12;
  word-spacing: normal;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  text-indent: 0;
  white-space: normal;
  }

BODY {
  padding: 8px;
  }

H1 {
  font-size: xx-large;
  margin: .67em 0;
  }

H2 {
  font-size: x-large;
  margin: .75em 0;
  }

H3 {
  font-size: large;
  margin: .83em 0;
  }

H4, P, BLOCKQUOTE, FIELDSET, FORM, UL, OL, DL, DIR, MENU {
  margin: 1.12em 0;
  }

H5 {
  font-size: small;
  margin: 1.5em 0;
  }

H6 {
  font-size: x-small;
  margin: 1.67em 0;
  }

H1, H2, H3, H4, H5, H6, B, STRONG {
  font-weight: bolder;
  }

BLOCKQUOTE {
  margin-left: 40px;
  margin-right: 40px;
  }

I, CITE, EM, VAR, ADDRESS {
  font-style: italic;
  }

PRE, TT, CODE, KBD, SAMP {
  font-family: monospace;
  }

PRE {
  white-space: pre;
  }

BIG {
  font-size: larger;
  }

SMALL, SUB, SUP {
  font-size: smaller;
  }

SUB {
  vertical-align: sub;
  }

SUP {
  vertical-align: super;
  }

S, STRIKE, DEL {
  text-decoration: line-through;
  }

HR {
  border: 1px inset; /* questionable */
  }

OL, UL, DIR, MENU, DD {
  padding-left: 40px;
  }

OL LI {
  list-style-type: decimal;
  }

UL LI {
  list-style-type: disc;
  }

UL UL, UL OL, UL MENU, UL DIR, MENU UL, MENU OL, MENU MENU, MENU DIR, DIR UL,
DIR OL, DIR MENU, DIR DIR, OL UL, OL OL, OL MENU, OL DIR {
  margin-top: 0;
  margin-bottom: 0;
  }

OL UL, UL UL, MENU UL, DIR UL, OL MENU, UL MENU, MENU MENU, DIR MENU, OL DIR, UL
DIR, MENU DIR, DIR DIR  {
   list-style-type: circle;
  }

OL OL UL, OL UL UL, OL MENU UL, OL DIR UL, OL OL MENU, OL UL MENU, OL MENU MENU,
OL DIR MENU, OL OL DIR, OL UL DIR, OL MENU DIR, OL DIR DIR, UL OL UL, UL UL UL,
UL MENU UL, UL DIR UL, UL OL MENU, UL UL MENU, UL MENU MENU, UL DIR MENU, UL OL
DIR, UL UL DIR, UL MENU DIR, UL DIR DIR, MENU OL UL, MENU UL UL, MENU MENU UL,
MENU DIR UL, MENU OL MENU, MENU UL MENU, MENU MENU MENU, MENU DIR MENU, MENU OL
DIR, MENU UL DIR, MENU MENU DIR, MENU DIR DIR, DIR OL UL, DIR UL UL, DIR MENU
UL, DIR DIR UL, DIR OL MENU, DIR UL MENU, DIR MENU MENU, DIR DIR MENU, DIR OL
DIR, DIR UL DIR, DIR MENU DIR, DIR DIR DIR  {
  list-style-type: square;
  }

U, INS {
  text-decoration: underline;
  }

CENTER {
  text-align: center;
  }

CAPTION, COL, COLGROUP, LEGEND, TABLE, TBODY, TD, TFOOT, TH, THEAD, TR {
  background: transparent;
  text-decoration: none;
  margin: 1px;
  padding: 1px;
  border: none;
  float: none;
  clear: none;
  }

TABLE, TBODY, TFOOT, THEAD, TR {
  display: block;
  background-position: top left;
  width: auto;
  height: auto;
  }

CAPTION, LEGEND, TD, TH {
  display: inline;
  vertical-align: baseline;
  font-size: 1em;
  line-height: 1.33em;
  color: black;
  word-spacing: normal;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
  text-indent: 0;
  white-space: normal;
  }

TH {
  font-weight: bolder;
  text-align: center;
  }

CAPTION {
  text-align: center;
  }

/* not part of the legacy browser default sheet, but an obvious enhancement */

OL OL LI {
  list-style-type: lower-alpha;
  }

OL OL OL LI {
  list-style-type: lower-roman
  }

Средство от вируса таблицы стилей по умолчанию (браузера Mosaic)?

План сработал не совсем так, как представлял Тодд Фарнер. Эта базовая таблица стилей продолжает существовать, при этом ряд стилей на основе Mosaic остаётся нетронутым. Для HTML нет полноценных альтернативных таблиц стилей — по крайней мере у w3c или поставщиков браузеров. И те, и другие слишком увлечены обратной совместимостью, чтобы вносить какие-либо радикальные изменения в стили веба по умолчанию.

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

Именно это привело Джен Симмонс к созданию CSS Remedy. Я одна из основных участников, хотя в последнее время в проекте было немного работы. Цель — переосмыслить для современного Интернета таблицу стилей по умолчанию. Что было бы придумано сейчас, если бы нас не сдерживало то, что сделано в Mosaic почти 30 лет назад? Впереди ещё много дискуссий, но в строке 47 основной таблицы стилей CSS Remedy бесспорно одно:

body { margin: 0; }

В CSS Remedy в целом нет стремления сделать всё красиво — просто попробовать прийти к лучшему значению по умолчанию. Ещё есть проекты с менее гибким подходом для полностью разработанных стилей базовых элементов HTML.

В прошлом месяце Робин Рендл поделился мыслями о The Smallest CSS, отвечающим на вопрос о том, какой наименьший CSS можно написать, чтобы HTML выглядел сколько-нибудь прилично. Это отличное исследование, которое вместилось в ~15 строках CSS.

А ещё мне нравятся бесклассовые фреймворки, полностью основанные на написании семантического html и без специальных селекторов. Взгляните и на эти бесклассовые CSS-библиотеки.

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

Выбрать другую востребованную профессию.

Комментарии (3)


  1. mobi
    13.07.2022 19:09
    +6

    Половина высоты кегля (по умолчанию 16px) — это как раз оптимальный отступ между границей экрана и первым символом строки. И в большинстве шрифтов пробел имеет как раз такую ширину.


    1. nin-jin
      14.07.2022 09:17
      +1

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


  1. funca
    13.07.2022 22:51

    Сейчас у браузеров есть ещё одна подобная фича - Simplified View (aka Reading Mode). При отображении тоже используются некие дефолтные стили, где все ещё более нестандартно.