css
Основы

Наследование, каскадирование

CSS
Основы

Обновлено

14.09.2023

Просмотров

68

Время прочтения

20 мин.

Сложность

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

Наследованием называется перенос действия стилевых свойств родительских элементов на их потомков. Самый простой пример — это <p> и лежащий внутри него <span>. Span перенимает все наследуемые свойства своего родителя, собственно этим он и хорош, что он ведёт себя точно так же, как и весь остальной текст, но при этом поддаётся и индивидуальному форматированию при помощи классов.

На примере ниже мы реализовали описанную ситуацию. Можно заметить, что, хотя для <span> и не описаны свойства color и font-weight, они наследуются от <p> и применяются к нему:

                
<style> p{ color: green; font-weight: 600; } span{ text-decoration: underline; text-decoration-color: red; } </style> <p>Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Скатился маленькая <span>ведущими</span> снова текста до вдали заголовок. На берегу снова жизни великий даже предупредила, необходимыми?</p>

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

Не все css-свойства наследуются. Это уже зависит от спецификации CSS, и правильнее всего было бы, если нужно узнать, наследуется свойство, или нет, — посмотреть спецификацию. Также довольно много информации о наследовании свойств содержится в различных справочниках, о некоторых мы уже говорили в этом учебнике. К счастью, знать наизусть эту информацию совершенно необязательно. Достаточно будет запомнить, что практически все свойства, связанные со шрифтом и текстовым форматированием, наследуются. Во всех остальных случаях, если вы написали стилевое правило и внутри одного тега изменились также другие теги, то проверьте в панели разработчика их стили и блок «Inherited from», как на скриншоте. Вероятно, свойство унаследовалось.

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

                
<style> p{ color: green; font-weight: 600; } p{ color: blue; font-weight: 400; } p{ color: purple; } </style> <p>Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Скатился маленькая снова текста до вдали заголовок. На берегу снова жизни великий даже предупредила, необходимыми?</p>

Как видите, свойства «перекрывают» друг друга, если повторяются ниже. Это показывает и панель разработчика, зачёркивая переписанные свойства. Это и есть принцип каскадности стилей, он довольно простой, но невероятно важный, на нём строится вся логика работы CSS. Если мы сейчас уберём этот принцип из CSS, весь Веб тут же развалится.

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

В таком случае стили применяются сверху вниз, по мере загрузки файлов: сначала применится первый файл, затем второй и потом уже третий. Если в них будут селекторы, обращающиеся к одним и тем же элементам, то они и перезапишут повторяющиеся свойства. Этот принцип каскадности как раз и позволяет нам в своей работе перезаписывать стили браузера (reset.css), затем применять стили какого-нибудь фреймворка (bootstrap.css), затем применять собственные стили (style.css), получая необходимый результат.

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

                
<style> .theme-text{ color: blue; font-weight: 400; } p{ color: red; font-weight: 700; } </style> <p class="theme-text">Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Скатился маленькая снова текста до вдали заголовок. На берегу снова жизни великий даже предупредила, необходимыми?</p>

Как видите, стили находятся ниже, на 16-й строке, однако они определены при помощи селектора тега, а он имеет меньший вес, чем селектор класса. Поэтому стили с 12-й строки в браузере отображаются выше, и именно они применяются к элементу.

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

Селектор тега имеет минимальный вес 1, селектор класса 10, селектор идентификатора 100, директива !important (о ней позже) — 1000. Чем больше вы описываете вложенных, соседних, дочерних селекторов, чем больше указываете тегов и классов, тем выше специфичность селектора.

                
<style> div.container p.theme-text{ color: red; } .container p.theme-text{ color: blue; } </style> <div class="container"> <p class="theme-text">Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Скатился маленькая снова текста до вдали заголовок. На берегу снова жизни великий даже предупредила, необходимыми?</p> </div>

Хотя селекторы в примере практически одинаковы, всё же у первого дополнительно указан div в начале, что и придаёт ему +1 к весу, а потому он перевешивает нижестоящий селектор. Итоговый цвет текста в абзаце, как видите, красный. Принцип каскадности в CSS уступает весу селекторов.

В CSS есть некая директива !important, придающая сверхвес выбранному свойству\значению. Если мы хотим переписать какое-нибудь свойство, имеющее бОльшую специфичность и находящееся в самом верху иерархии css-файлов, то мы можем воспользоваться ей.

                
<style> div.container p.theme-text{ color: red; } .container p.theme-text{ color: blue; } p{ color: purple!important; } </style> <div class="container"> <p class="theme-text">Далеко-далеко за словесными горами в стране гласных и согласных живут рыбные тексты. Скатился маленькая снова текста до вдали заголовок. На берегу снова жизни великий даже предупредила, необходимыми?</p> </div>

Несмотря на то, что селектор у нас обладает наименьшим весом, применилось именно его правило, поскольку оно обозначено директивой !important. Эта директива, как уже говорилось, обладает весом 1000 и этого всегда достаточно, чтобы перевесить любое количество классов. Эту директиву можно перевесить лишь ею самой, указав её для другого селектора.

Использование в современных проектах директивы !important считается дурным тоном и осуждается большинством разработчиков. Также повторимся, что необходимость «перетягивания» веса селекторов добавлением в CSS код классов и вложенности является лишь следствием неправильного подхода в разработке. При соблюдении правил методологий классы различных элементов у нас не будут повторяться вообще, так что проблема случайной «перезаписи» свойств не может возникнуть.

Необходимо очков: