Привет Хабр! Представляю вам перевод статьи BODY MARGIN 8PX The origin story for a style no one wants. Данная статья мне показалась интересной и я надеюсь что я более менее нормально смогу передать вам ее содержание. Так же если вдруг вам интересно то я веду канал по фронту в котором стараюсь публиковать интересные материалы. В общем поехали.
Все браузеры элементу body добавляют внешний отступ со значением 8px (margin 8px). Это часть таблицы стилей по умолчанию, рекомендованных w3c. Но почему именно 8px? Откуда такая тенденция?
Дефолтные значения vs параметры браузера по умолчанию
Каждое свойство в CSS имеет дефолтное значение, и оно одинаково для всех элементов веба. Например, дефолтное значение display — inline, а margin — 0.
Дефолтные значения используют тогда, когда другие не указаны или не унаследованы откуда-то еще. Можно также вернуть стили прямо к их начальному значению, используя ключевое слово initial.
Но когда все свойства одинаковы, то ссылка, абзац, заголовок или список визуально не отличаются, и это плохо. Убедимся в этом на примере Ultimate CSS Reset:
/* you can't get any more 'reset' than this /
{ all: initial !important; }
Вот для чего нам нужны стили браузера — от элемента к элементу у них разные значения по умолчанию. Некоторые относятся к display, как блоковый элемент. Внутри него div’ы, параграфы, списки, заголовки, и т.д., и им нужны отступы для лучшего восприятия контента.
Мы можем откатить любое свойство к стилю браузера по умолчанию, используя ключевое слово revert. Технически это удаляет любые авторские или пользовательские стили.
Стандартизация настроек браузера
Стили браузера — неотъемлемая часть интерфейса, но мы обращаем на них внимание только тогда, когда они кажутся нам неправильными или неожиданными. Тогда мы воспринимаем их как проблему, которую нужно решить с помощью ресета или нормализации.
Reset удаляет значения по умолчанию для эффекта «чистого холста».
Normalize делает дефолтные значения одинаковыми в разных браузерах.
Рабочая группа 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 }
}
Некоторые из стилей кажутся очевидными: элементы block должны отображаться блоком, элементы table — таблицами, а list — списками. Для заголовков предусмотрен более крупный и жирный шрифт. В то же время, другие стили по умолчанию кажутся довольно произвольными.
Пролистнем блок с кодом на ⅓ вниз и увидим вот это:
body { margin: 8px; }
Логично, что по умолчанию по краям документа должен быть отступ, но почему именно 8px?
Ничто не исчезает бесследно
Таблица стилей по умолчанию нужна для совместимости между браузерами, так как весь веб создан по принципу прямой и обратной совместимости. Веб не статичен — разработчики регулярно добавляют новые функции и фишки, и эти фичи не должны ломать существующие сайты.
Но в редких случаях что-нибудь да ломается, и мы делаем все, чтобы избежать таких ситуаций. А еще часто браузеры перестают использовать фичи (как это было со старым элементом marquee), продолжая при этом ее поддерживать.
Стили по умолчанию в браузерах действуют по той же схеме. Они существовали с тех пор появился CSS. Хотя браузеры время от времени добавляют новые стили по умолчанию, старые удаляют крайне редко — велик риск нарушить работу сайтов, в которых они уже используются.
Многие из сегодняшних стилей по умолчанию, которые есть в браузерах, это те же, что существовали при первом появлении HTML-элемента.
Чистота против реальности спецификации
Для разработки стандартов, даже ненормативных (необязательных к соблюдению), есть одно правило. Оно применимо и к таблице стилей по умолчанию. Стандарт не имеет смысла, если он не описывает реальность.
Чтобы быть успешным, стандарт должен быть предписывающим, то есть указывающим браузерам, что внедрять. А еще он должен быть описательным в ретроспективе — описывать то, что браузеры уже внедрили. Бесполезно иметь совершенную в теории спецификацию, если она не точно описывает реальный веб.
Новые стандарты пишутся для того, чтобы указать, как должна реализовываться и работать новая фича. Однако это только первый шаг сложного процесса. Действующие стандарты регулярно пересматриваются, чтобы понять, как функции на самом деле работают после внедрения. Опять же, мы отдаем предпочтение совместимости между браузерами, а не теоретической чистоте самих стандартов.
Внешний отступ во всех элементах body
В прошлом месяце я решила выяснить происхождение этого стиля:
body { margin: 8px }
Я знала, что он — часть таблицы стилей, и предполагала, что он унаследован от старых версий браузеров. Затем его стандартизировали ради согласованности между вебом и браузерами.
Но откуда он взялся изначально? Я решила обратиться к Твиттеру, и в итоге мы отследили его путь.
Шаг 1: Спецификация
Алан Стернс (один из нынешних председателей CSSWG) указал мне на первую спецификацию с margin 8px в таблице стилей по умолчанию:
В 2003-ем был padding. С 2004 поменялся на margin
Замена с padding на margin интересна. Но я полагаю, что эти таблицы стилей, описывали какую-то предшествующую реальность браузера — не создавали же этот стиль с нуля?
Шаг 2: Оригинальные браузеры
Есть несколько ссылок, которые я поглядываю от случая к случаю, когда мне хочется почитать об истории CSS. Больше всего мне нравятся эти документы-источники:
Cascading HTML style sheets – a proposal от Håkon Lie (пропозал, который стал в итоге CSS);
Но есть и другие крутые статьи с историей CSS:
A brief history of CSS until 2016 от Берта Боса (соавтор оригинальной специализации CSS);
A Look Back at the History of CSS от Джея Хоффмана на сайте SS-Tricks;
The Languages Which Almost Became CSS от Зака Блума.
Я настоятельно рекомендую прочитать их, чтобы понять принцип работы языка. В них я нашла список первых браузеров с CSS, но не узнала ничего про margin в body:
Для контекста, IE3 был первым коммерческим браузером с CSS. Это был 1996 год. Затем Netscape 4 добавил некоторую поддержку языка. До этого CSS тестировался в Argo и Arena... Как давно это было...?
Шаг 3: Архивы www-talk и www-style
Большинство этих пропозалов были изначально написаны в виде писем для рассылки www-talk@w3.org или для специального списка рассылки www-style@w3.org. Оба сайта хорошо архивированы и доступны для поиска (одно из преимуществ среды, созданной группой ботаников в области информатики).
Поиск в архивах привел меня к письму от Тодда Фарнера за март 1998 года:
В моей последней редакции «Базовой таблицы стилей» задан margin: 0px, padding: 8px. Ранее было так: margin: 8px, padding: 0px, а background-position: -8px
Тема ветки писем говорит о правильной работе с фоновыми изображениями. Не совсем по теме, но здесь говорится про наш padding/margin 8px.
Шаг 4: Wayback machine
Следующая ссылка не работает, поэтому я кинулась на сайт The WayBack Machine чтобы проверить, есть ли архивированная копия — и их оказалось несколько!
Сначала зашла на страницу The Base Stylesheet - February 22, 1999. Судя по ней, последние изменения были 7 ноября 1998. Затем перешла к самой ранней версии страницы — The Base Stylesheet - January 30, 1998.
Что, простите? Покопавшись в исходном коде, я нашла это:
<p>
This is a work in progress, last modified
<script>document.write(document.lastModified);</script>
<noscript>quite recently</noscript> GMT...
</p>
Получается, параметр .lastModified обновляется через WayBack Machine каждый раз при загрузке страницы?
Последний ответ: базовая таблица стилей
Вот то, что мы искали: оригинальная таблица стилей по умолчанию, на тот момент она все еще в разработке. Здесь есть несколько примечательных цитат:
«Базовая таблица стилей описывает “согласованный по умолчанию” рендеринг всех элементов HTML 4.0 в веб-браузерах, производных от Mosaic. Он... фиксирует статус-кво для того, чтобы выйти за его пределы.»
Netscape Navigator и Microsoft Internet Explorer — основные браузерные движки того времени, и оба они восходят к предыдущему браузеру Mosaic.
Таблица стилей по умолчанию браузера Mosaic — это простая адаптация нормативов для печатных научных трудов в Европе (см. Wanning, Frank; Internationaler Typographie und wissenschaftliche Textverarbeitung; Haag + Herchen, 1996). Звучит убедительно, учитывая, что веб зародился в лабораториях CERN. Однако есть одно но: большее распространение веб получил в коммерции, сфере развлечений, журналистике и гуманитарных науках. А ещё на тот момент на рынке доминировали браузеры на базе Mosaic — оба факта позволяют сказать, что ”правильный” HTML был заражен абсолютно неподходящим стилем, как раком или вирусом.
Mosaic Browser Default Stylesheet (MBDS) вышел из научного сообщества CERN в широкое пользование и породил в Сети несколько поколений мутировавших инструментов и авторов, неправильно применяющих разметку только чтобы вызвать определенные эффекты MBDS.
Характерный пример этого явления — использование <p> для создания вертикального пробела и табличных структур для нетабличной разметки. Надежность таких манипуляций объясняет каннибализацию HTML за пределами академических кругов и коммерческий успех архитектурно несочетаемых расширений HTML для облегчения симптомов.
Чтобы повернуть вспять эту эпидемию, необходимо сначала изолировать вирус и подвергнуть его гены точному и всестороннему лечению. Base Stylesheet — это модель CSS1 вируса MBDS и первый шаг к разработке «стилевых антител» — комплексных альтернативных таблиц стилей для HTML.
Вот и все. Эта таблица стилей призвана показать то, что уже происходило до появления CSS в браузерах на базе Mosaic, и воссоздать эти стили в CSS. Интервал в 8px в Body появился еще до появления CSS. Вероятно, этот стиль пришел из внутренних правил Mosaic, еще до изобретения CSS, так что вопрос, как его представить, — как padding или как margin, — остается открытым.
Базовая таблица стилей Тодда Фарнера (ранняя версия):
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
}
Лекарство от вируса MBDS?
План сработал не совсем так, как представлял себе Тодд Фарнер. Эта базовая таблица стилей продолжает жить, и ряд стилей, основанных на Mosaic, остался нетронутым. Альтернативных таблиц стилей для HTML не существует, по крайней мере, ни у w3c, ни у производителей браузеров. И те, и другие слишком заинтересованы в обратной совместимости, чтобы вносить какие-либо радикальные изменения в стили, которые уже используются.
Если это и произойдет, то с инициативы веб-авторов, которые могут выбрать новую таблицу стилей, не беспокоясь об обратной совместимости. В некоторой степени, reset и normalize — это попытки создать новую всеобъемлющую таблицу стилей. Однако ресеты обычно удаляют слишком много (полагаясь на авторов, которые смогут вернуть все обратно), а нормализаторы часто больше заботятся о совместимости с браузером, чем об улучшении стилей.
Именно это привело Джен Симмонс к созданию CSS Remedy. Я одна из основных участников, хотя в последнее время в проекте было немного работы. Цель — переосмыслить для современного интернета таблицу стилей по умолчанию. Что было бы придумано сейчас, если бы нас не сдерживали достижения Mosaic 30-летней давности? Впереди ещё много дискуссий, но в строке 47 основной таблицы стилей CSS Remedy бесспорно одно:
body { margin: 0; }
В CSS Remedy в целом нет стремления сделать всё красиво — лишь попробовать прийти к лучшим дефолтным значениям. Еще есть проекты с менее гибким подходом для уже разработанных стилей базовых элементов HTML.
В прошлом месяце Робин Рендл поделился мыслями о The Smallest CSS, отвечающим на вопрос о том, какой наименьший CSS можно написать, чтобы HTML выглядел более-менее прилично. Это отличное исследование, которое вместилось в ~15 строках CSS.
А ещё мне нравятся бесклассовые фреймворки, которые основаны на написании семантического html без специальных селекторов. Взгляните и на эти бесклассовые CSS-библиотеки.
Мне самой не терпится попробовать что-то подобное.