13. Каскад и наследование

Прокрутить вниз

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

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

Бесплатные курсы web разработки. Конфликтующие правила

CSS (Cascading Style Sheets) переводиться Каскадные Таблицы Стилей. Важно обратить внимание на слово «каскадные», оно важное для понимания CSS, ведь то, как ведёт себя каскад — ключевой момент в понимании CSS.

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

Концепция наследования заключается в том, что некоторые свойства CSS наследуют по умолчанию значения установленные для родительского элемента текущего элемента, а некоторые не наследуют. Это также может стать причиной поведения, которое вы, возможно, не ожидаете. Читайте остальные уроки по HTML/CSS — бесплатные курсы web разработки.

Каскад

Каскад таблицы стилей, если говорить упрощённо, означает, что порядок следования правил в CSS имеет значение. Когда применимы два правила, имеющие одинаковую специфичность, используется то, которое идёт в CSS последним.

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

Специфичность: бесплатные курсы web разработки

Специфичность определяет, как браузер решает, какое именно правило применяется в случае, когда несколько правил имеют разные селекторы, но, тем не менее, могут быть применены к одному и тому же элементу. Различные типы селекторов селекторы элементов h1{…}, селекторы классов, селекторы идентификаторов и т.д ) имеют разной степени влияние на элементы страницы. Чем более общее влияние оказывает селектор на элементы страницы тем меньше его специфичность, конкретность. По существу, это мера того, насколько специфическим будет отбор по селектору:

  • Селектор элементов например h1 ) менее специфичен — он выберет все элементы этого типа на странице — поэтому получит меньше баллов.
  • Селектор класса более специфичен — он выберет только те элементы на странице, которые имеют конкретное значение атрибута class — поэтому получит больше баллов, селектор класса применится после селектора элемента и поэтому перекроет его стили.

Например. Как указано ниже, у нас опять есть два правила, которые могут применяться к h1. h1 в результате будет окрашен красным цветом — селектор класса даёт своему правилу более высокую специфичность, поэтому он будет применён, несмотря на то, что правило для селектора элемента расположено ниже в таблице стилей.

Далее мы объясним, как сделать оценку специфичности, и другие моменты.

Наследование

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

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

бесплатные курсы web разработки

Некоторые свойства не наследуются — например, если вы установили для элемента width равным 50%, все его дочерние элементы не получат ширину в 50% от ширины своего родительского элемента. Если бы это было так, CSS было бы чрезвычайно трудно использовать!

Обратите внимание: На страницах справочника CSS-свойств вы можете найти окно технической информации, обычно в конце раздела спецификации, в котором перечислены некоторые технические данные об этом свойстве, в том числе наследуется оно или нет.

Понимание наследования

Итак, наследование. В примере ниже мы имеем  с двумя уровнями неупорядоченных списков, вложенных в него. Мы установили для внешнего  стиль границы, внутренние отступы и цвет шрифта.

Цвет шрифта применён к прямому потомку, но также и к непрямому потомку — к прямому потомку  и к элементам внутри первого вложенного списка. Далее мы добавили класс special ко второму вложенному списку и применили к нему другой цвет шрифта. Теперь это свойство наследуется всеми его потомками.

.main {
color: rebeccapurple;
border: 2px solid #ccc;
padding: 1em;
}

.special {
color: black;
font-weight: bold;
}
<ul class=»main»>
<li>Item One</li>
<li>Item Two
<ul>
<li>2.1</li>
<li>2.2</li>
</ul>
</li>
<li>Item Three
<ul class=»special»>
<li>3.1
<ul>
<li>3.1.1</li>
<li>3.1.2</li>
</ul>
</li>
<li>3.2</li>
</ul>
</li>
</ul>

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

Какие свойства наследуются по умолчанию, а какие нет, чаще всего определяется здравым смыслом.

Контроль наследования

CSS предоставляет четыре специальных универсальных значения свойства для контроля наследования. Каждое свойство CSS принимает эти значения.

inherit

Устанавливает значение свойства, применённого к элементу, таким же, как у его родительского элемента. Фактически, это «включает наследование».

initial

Устанавливает значение свойства, применённого к выбранному элементу, равным initial value этого свойства (в соответствии с настройками браузера по умолчанию. Если в таблице стилей браузера отсутствует значение этого свойства, оно наследуется естественным образом.)

unset (en-US)

Возвращает свойству его естественное значение, что означает, что если свойство наследуется естественным образом, оно действует как inherit, иначе оно действует как initial.

Обратите внимание: Существует также более новое значение revert, которое имеет ограниченную поддержку браузерами.

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

Например:

  1. Второй элемент списка имеет класс my-class-1. Поэтому, цвет для следующего вложенного элемента a устанавливается по наследству. Как изменится цвет, если это правило будет удалено?
  2. Понятно ли, почему третий и четвёртый элементы a имеют именно такой цвет? Если нет, перечитайте описание значений, представленное выше.
  3. Какая из ссылок изменит цвет, если вы зададите новый цвет для элемента  — например: a color: red; }?

Возврат всех исходных значений свойств

Стенографическое свойство CSS all можно использовать для того, чтобы присвоить одно из значений наследования к (почти) всем свойствам одновременно. Это одно из четырёх значений (inherit, initial, unset, или revert). Это удобный способ для отмены изменений, внесённых в стили, для того, чтобы вы могли вернуться к стартовой точке перед внесением новых изменений.

В примере ниже имеются два блока . Первый имеет стиль, который применён к самому элементу blockquote, второй имеет класс fix-this, который устанавливает значение all в unset.

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

Понимание каскада

Теперь мы понимаем, почему параграф, следующий по глубине в структуре HTML документа, имеет тот же цвет, что CSS применяет к body, а вводные уроки дали понимание того, как изменить применение CSS к чему-либо в любой точке документа — или назначить CSS элементу, или создать класс. Теперь рассмотрим подробнее то, как каскад определяет выбор CSS-правил, применяемых в случае влияния на стиль элемента нескольких объектов.

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

  • Порядок следования
  • Специфичность
  • Важность

Мы внимательно изучим их, чтобы увидеть, как именно браузеры определяют, какой CSS следует применить.

Порядок следования

Мы уже видели, какое значение для каскада имеет порядок следования. Если у вас несколько правил, которые имеют одинаковую важность, то побеждает правило, которое идёт последним в CSS. Другими словами, правила, более близкие к самому элементу, переписывают более ранние, пока последнее не победит, оно и стилизует элемент.

Специфичность

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

Ранее в этой статье мы описали, что селектор класса имеет больший вес, чем селектор элемента. Поэтому свойства, определённые в классе, будут переопределять свойства, применённые непосредственно к элементу.

На этом моменте следует учесть, что, хотя мы думаем о селекторах и правилах, применяемых к объекту, который они выбирают, переписывается не всё правило, а только свойства, которые являются одинаковыми.

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

Вычисление специфичности

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

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

  1. Тысячи: поставьте единицу в эту колонку, если объявление стиля находится внутри атрибута style (встроенные стили). Такие объявления не имеют селекторов, поэтому их специфичность всегда просто 1000.
  2. Сотни: поставьте единицу в эту колонку за каждый селектор ID, содержащийся в общем селекторе.
  3. Десятки: поставьте единицу в эту колонку за каждый селектор класса, селектор атрибута или псевдокласс, содержащийся в общем селекторе.
  4. Единицы: поставьте общее число единиц в эту колонку за каждый селектор элемента или псевдоэлемент, содержащийся в общем селекторе.

 Важно: Универсальный селектор (*), комбинаторы (+, >,  ~, ») и псевдокласс отрицания (:not) не влияют на специфичность.

Бесплатные курсы web разработки: таблица специфичности селекторов

Следующая таблица показывает несколько несвязанных примеров, которые помогут вам разобраться. Посмотрите их все и убедитесь, что вы понимаете, почему они обладают той специфичностью, которую мы им дали. Мы ещё не рассмотрели селекторы детально, но вы можете найти подробную информацию о каждом селекторе в справочнике селекторов MDN.

бесплатные курсы web разработки

Прежде чем мы продолжим, давайте посмотрим на пример в действии.

бесплатные курсы web разработки

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

  • Первые два правила конкурируют за стилизацию цвета фона ссылки — второе выигрывает и делает фоновый цвет синим, потому что у него есть дополнительный селектор ID в цепочке: его специфичность 201 против 101.
  • Третье и четвёртое правило конкурируют за стилизацию цвета текста ссылки — второе выигрывает и делает текст белым, потому что, хотя у него на один селектор элемента меньше, отсутствующий селектор заменяется на селектор класса, который оценивается в десять вместо единицы. Таким образом, приоритетная специфичность составляет 113 против 104.
  • Правила 5–7 соревнуются за определение стиля границы ссылки при наведении курсора. Шестой селектор со специфичностью 23 явно проигрывает пятому со специфичностью 24 — у него в цепочке на один селектор элемента меньше. Седьмой селектор, однако, превосходит как пятый, так и шестой — он имеет то же количество подселекторов в цепочке, что и пятый, но один элемент заменён селектором класса. Таким образом, приоритетная специфичность 33 против 23 и 24.

Примечание: Это был условный пример для более простого усвоения. В действительности каждый тип селектора имеет собственный уровень специфичности, который не может быть замещён селекторами с более низким уровнем специфичности. Например, миллион соединённых селекторов класса не способны переписать правила одного селектора id. Бесплатные курсы web разработки — сделай первый шаг в успешное будущее уже сегодня!

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

!important

Существует специальный элемент CSS, который вы можете использовать для отмены всех вышеперечисленных вычислений, однако вы должны быть очень осторожны с его использованием — !important. Он используется, чтобы сделать конкретное свойство и значение самыми специфичными, таким образом переопределяя нормальные правила каскада.

Взгляните на этот пример, где у нас есть два абзаца, один из которых имеет ID.

бесплатные курсы web разработки

Давайте пройдёмся по этому примеру

Чтобы увидеть, что происходит — попробуйте удалить некоторые свойства, чтобы увидеть, что получится, если вам трудно понять:

  1. Вы увидите, что применены значения color (en-US) и padding третьего правила, но background-color — нет. Почему? Действительно, все три безусловно должны применяться, потому что правила, более поздние в порядке следования, обычно переопределяют более ранние правила.
  2. Однако вышеприведённые правила выигрывают, потому что селекторы классов имеют более высокую специфичность, чем селекторы элементов.
  3. Оба элемента имеют class с названием better, но у второго также есть id с названием winning. Поскольку ID имеют ещё более высокую специфичность, чем классы (у вас может быть только один элемент с каждым уникальным ID на странице, но много элементов с одним и тем же классом — селекторы ID очень специфичны, на что они и нацелены), красный цвет фона и однопиксельная чёрная граница должны быть применены ко 2-му элементу, причём первый элемент получает серый фоновый цвет и отсутствие границы, как определено классом.
  4. 2-й элемент получил красный цвет фона и отсутствие границы. Почему? Из-за объявления !important во втором правиле — размещение которого после border: none означает, что это объявление перевесит значение границы в предыдущем правиле, даже если ID имеет более высокую специфичность.

Учтите: Единственный способ переопределить объявление !important –  это включить другое объявление !important в правило с такой же специфичностью позже или в правило с более высокой специфичностью. Бесплатные курсы web разработки серия статей о основах языковой разметки HTML и стилизации CSS.

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

Одна из ситуаций, в которой вам, возможно, придётся это использовать, — это когда вы работаете с CMS, где вы не можете редактировать модули CSS ядра, и вы действительно хотите переопределить стиль, который нельзя переопределить другим способом. Но, вообще говоря, не стоит использовать этот элемент, если можно этого избежать.

Влияние расположения CSS

Конечно, следует отметить, что важность объявления CSS зависит от того, в какой таблице стилей оно указано — у пользователя есть возможность установить индивидуальные таблицы стилей для переопределения стилей разработчика, например, пользователь может иметь проблемы со зрением и захочет установить размер шрифта на всех посещаемых им веб-страницах в два раза больше нормального размера, чтобы облегчить чтение.

Подведение итогов

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

  1. Объявления в таблицах стилей клиентского приложения (например, стили браузера по умолчанию, используемые, когда не заданы другие стили).
  2. Обычные объявления в пользовательских таблицах стилей (индивидуальные стили устанавливаются пользователем).
  3. Обычные объявления в авторских таблицах стилей (это стили, установленные нами, веб-разработчиками).
  4. Важные объявления в авторских таблицах стилей.
  5. Важные объявления в пользовательских таблицах стилей.

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

Эта статья вмещает в себе много информации, поэтому следует не спеша во всем разобраться. Бесплатные курсы web разработки это возможность освоить базовые знания по программированию. А проверить усвоили ли вы эту тему вы можете пройдя тест. Желаем удачи!