Наследование - это когда дочерний элемент автоматически получает значение некоторых свойств от родителя, если для него самого ничего не задано отдельно. Но наследуются далеко не все свойства: одни передаются сами собой, другие - никогда, и для них всегда используется собственное базовое значение.
В этом уроке
Попробуй прямо в этом окне: текст абзаца внутри div становится синим - цвет унаследовался от родителя. А вот рамка вокруг абзаца не появляется, хотя у самого div она есть, - border не наследуется, и у абзаца по умолчанию своя, пустая рамка.
Что наследуется само собой
Автоматически наследуются в основном свойства, связанные с текстом: цвет, шрифт, межстрочный интервал, выравнивание. Логика простая - если весь блок текста должен выглядеть одинаково, не нужно повторять одни и те же свойства на каждом вложенном теге.
color, font-family, font-size, font-weight, line-height, text-align - все они передаются от родителя к потомку без дополнительных усилий.
article { color: tomato; } strong { color: black; }, ожидая, что strong внутри article всё равно останется чёрным, потому что "так задано отдельно" - это сработает верно только потому, что для strong явно указано собственное правило; без него strong унаследовал бы оранжевый цвет от article.
Что не наследуется - и почему
Свойства блочной модели - границы, отступы, фон, ширина, высота - не наследуются никогда. Если бы они наследовались, у каждого вложенного элемента накапливались бы отступы и рамки родителей, и вёрстку было бы невозможно предсказать.
.card { border: 3px solid tomato; padding: 20px; } - эти свойства остаются только у самого .card, у вложенных тегов своя, пустая рамка и нулевой отступ, пока не задать иначе.
.card p { }, ожидая, что абзац внутри .card получит ту же рамку и отступ, что и сам .card, - border и padding не наследуются, для абзаца их нужно задавать отдельным правилом.
Ключевые слова inherit, initial, unset
Если наследование всё-таки нужно там, где его нет по умолчанию, можно явно написать значение inherit - тогда свойство принудительно возьмётся у родителя, даже border или background. initial, наоборот, сбрасывает свойство на "заводское" значение из спецификации CSS, игнорируя и родителя, и остальной каскад. unset ведёт себя по ситуации: для обычно наследуемых свойств работает как inherit, для остальных - как initial.
.card p { border: inherit; } - принудительно забирает рамку родителя, хотя border по умолчанию не наследуется.
color: initial;, ожидая получить цвет родителя, - initial даёт не родительский, а "заводской" цвет браузера (обычно чёрный), полностью игнорируя, что было унаследовано.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Ждать, что рамка, фон или отступы родителя перейдут потомку | border, background, padding, margin, width, height не наследуются - у потомка всегда собственное базовое значение, пока не задано иначе | Задавать такие свойства явно для каждого элемента, которому они нужны |
| Путать наследование и каскад | Наследование - это передача значения от родителя к потомку. Каскад - это про то, какое из конкурирующих правил победит у ОДНОГО и того же элемента. Это два разных механизма | Разделять: "откуда взялось значение" (наследование) и "какое правило победило" (каскад) |
| Не знать про inherit для принудительной передачи | Даже свойство, которое по умолчанию не наследуется (например border), можно заставить взять значение у родителя через border: inherit | Использовать inherit, если нужно явно повторить значение родителя у конкретного свойства |
| Путать initial и unset | initial всегда даёт "заводское" значение по спецификации, игнорируя родителя. unset умнее: для наследуемых свойств ведёт себя как inherit, для остальных - как initial | Использовать unset, если нужно "просто сбросить как будто ничего не задавали", а initial - если нужен именно спецификационный дефолт |
Шпаргалка
| Что | Наследуется? |
|---|---|
| color, font-family, font-size, line-height, text-align | Да, автоматически |
| border, margin, padding, background, width, height | Нет, никогда по умолчанию |
| inherit | Принудительно взять значение у родителя, даже для ненаследуемого свойства |
| initial | Сбросить на "заводское" значение из спецификации CSS |
| unset | inherit для наследуемых свойств, initial для остальных |
Коротко: отвечаем на вопросы
Почему border не наследуется, хотя color наследуется без проблем?
Это осознанное решение спецификации CSS: наследуются в основном текстовые свойства, а свойства блочной модели вроде border, margin и padding - никогда, чтобы у вложенных элементов не накапливались рамки и отступы родителей бесконтрольно.
Что такое currentColor и как это связано с наследованием?
currentColor - специальное значение, которое подставляет туда, где оно указано, текущий цвет текста этого же элемента (то есть значение свойства color). Это не наследование в чистом виде, но похожий по духу приём: например border-color: currentColor заставляет рамку автоматически совпадать по цвету с текстом, не дублируя цвет вручную.