Опубликован: 28.11.2008 | Уровень: для всех | Доступ: платный
Лекция 28:

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

< Лекция 27 || Лекция 28: 12 || Лекция 29 >

Каскадирование

CSS означает Каскадные таблицы стилей (Cascading Style Sheets), поэтому нет ничего удивительного, что каскадирование является важной концепцией. Это механизм, который управляет конечным результатом, когда несколько конфликтующих объявлений CSS применяются к одному элементу. Имеется три основные концепции, которые управляют порядком, в котором применяются объявления CSS:

  1. Важность
  2. Специфичность
  3. Порядок исходного кода

Мы рассмотрим эти концепции далее по очереди.

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

Важность

Важность объявления CSS зависит от того, где оно определено. Конфликтующие объявления будут применяться в следующем порядке, более поздние будут переопределять предыдущие:

  1. Таблицы стилей агента пользователя
  2. Обычные объявления в таблицах стиля пользователя
  3. Обычные объявления в таблицах стиля автора
  4. Важные объявления в таблицах стиля автора
  5. Важные объявления в таблицах стиля пользователя

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

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

Браузер Opera позволяет определять таблицы стилей пользователя, переходя в меню Tools (или меню Opera на компьютере Mac) > Preferences … > вкладка Advanced > Content, щелкая на кнопке Style Options …, и затем указывая на свою таблицу стилей в текстовом поле My style sheet на вкладке Display этого диалогового бокса. Можно также определить на вкладке Presentation, хотите ли вы, чтобы таблица стилей пользователя переопределяла таблицу стилей автора (Web-дизайнера), и даже добавить кнопку в интерфейс пользователя, которая позволяет переключаться между таблицами стилей пользователя и автора. Для этого выйдите полностью из меню Preferences …, затем сделайте щелчок правой кнопкой мыши или при нажатой клавише Ctrl где-нибудь в интерфейсе браузера Opera, выберите Customize … > вкладка Buttons > представление Browser, и перетащите кнопку Author Mode куда-нибудь на одну из своих панелей инструментов.

Таблица стилей автора является тем, что мы обычно называем "таблица стилей". Это таблица стилей, которую автор документа (или, более вероятно, дизайнер сайта) написал и присоединил (или включил).

Обычные объявления являются именно этим: обычными объявлениями. Противоположными являются важные объявления, которые являются объявлениями, за которыми следует директива !important.

Как можно видеть, важные объявления в таблице стилей пользователя будут перекрывать все остальное, что вполне логично. Этот пользователь с дислексией может, например, захотеть, чтобы весь текст выводился шрифтом Comic Sans MS, если он считает, что этот шрифт легче всего читать. Он мог бы тогда создать таблицу стилей пользователя, содержащую следующее правило:

* {
  font-family: "Comic Sans MS" !important;
}

В этом случае не имеет значения, что определил дизайнер, и не имеет значение, какое семейство шрифтов задано по умолчанию в браузере, все будет выводиться шрифтом Comic Sans MS.

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

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

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

Специфичность является некоторой характеристикой, которую каждый автор CSS должен понимать и думать о ней. Можно представлять ее как меру того, насколько конкретным является селектор некоторого правила. Селектор с низкой специфичностью может соответствовать многим элементам (такой как *, который соответствует каждому элементу в документе), в то время как селектор с высокой специфичностью может соответствовать только одному элементу на страницу (такой как #nav, который соответствует только элементу с id совпадающим с nav ).

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

Специфичность имеет четыре компонента, давайте назовем их a, b, c и d. Компонент "a" является наиболее разграничивающим, "d" — наименее.

Компонент "a" очень простой: это 1 для объявления атрибута style, иначе это 0.

Компонент "b" является числом селекторов id в селекторе (тех, которые начинаются с #).

Компонент "c" является числом селекторов атрибутов, включая селекторы классов - и псевдо-классов.

Компонент "d" является числом типов элементов и псевдо-элементов в селекторе.

После небольшого подсчета можно получить строку из этих четырех компонентов, определяющую специфичность для любого правила. Объявления CSS в атрибуте style не имеют селектора, поэтому их специфичность всегда будет 1,0,0,0.

Давайте рассмотрим несколько примеров - после этого должно быть вполне понятно, как это работает.

Селектор a b c d Специфичность
h1 0 0 0 1 0,0,0,1
.foo 0 0 1 0 0,0,1,0
#bar 0 1 0 0 0,1,0,0
html>head+body ul#nav *.home a:link 0 1 2 5 0,1,2,5

Рассмотрим подробнее последний пример. Мы имеем a=0, так как это селектор, а не объявление в атрибуте style. Имеется один селектор ID ( #nav ), поэтому b=1. Имеется один селектор атрибута ( .home ) и один псевдо-класс ( :link ), поэтому c=2. Имеется пять типов элементов ( html, head, body, ul и a ), поэтому d=5. Окончательная специфичность будет иметь вид 0,1,2,5.

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

Стоит также отметить, что имеется значительная разница в специфичности между селектором id и селектором атрибута, который ссылается на атрибут id. Хотя они соответствуют одному элементу, они имеют очень разную специфичность. Специфичность #nav будет 0,1,0,0, в то время как специфичность [id="nav"] будет только 0,0,1,0.

Давайте посмотрим, как это работает на практике.

  1. Начнем с добавления еще одного параграфа в документ HTML.
    <body>
      <h1>Heading</h1>
      <p>A paragraph of text.</p>
      <p>A second paragraph of text.</p>
    </body>
  2. Добавим правило в таблицу стилей, чтобы изменить цвет текста в параграфах:
    p {
      color: cyan;
    }
  3. Сохраните оба файла и перезагрузите документ в браузере, теперь должно быть два параграфа с голубым (cyan) цветом текста.
  4. Зададим id для первого параграфа, поэтому можно будет легко указать на него с помощью селектора CSS.
    <body>
      <h1>Heading</h1>
      <p id="special">A paragraph of text.</p>
      <p>A second paragraph of text.</p>
    </body>
  5. Добавим в таблицу стилей правило для специального параграфа:
    #special {
      background-color: red;
      color: yellow;
    }
  6. Сохраните оба файла и перезагрузите документ в браузере, чтобы увидеть теперь разноцветный результат.

Давайте посмотрим на объявления, которые применяются к двум этим параграфам.

Первое добавленное правило задает color:cyan для всех параграфов. Второе правило задает красный цвет фона и задает color:yellow для одного элемента, который имеет специальный id.

Красный фон не является проблемой, так как он определен только для #special. Оба правила содержат объявление свойства color, что означает, что имеется конфликт. Оба правила имеют одинаковую важность — они являются обычными объявлениями в таблице стилей автора — поэтому нужно проверить специфичность двух селекторов.

Селектором первого правила является p, который имеет специфичность 0,0,0,1 согласно приведенным выше правилам, так как он содержит один тип элемента. Селектором второго правила является #special, который имеет специфичность 0,1,0,0, так как состоит из селектора id. 0,1,0,0 является значительно более специфичным, чем 0,0,0,1, поэтому объявление color:yellow выигрывает, и вы получите желтый текст на красном фоне.

Порядок исходного кода

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

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

  1. Добавим новое правило в таблицу стилей в самом конце файла следующим образом:
    p {
      background-color: yellow;
      color: black;
    }
  2. Сохраните и перезагрузите Web-страницу. Мы имеем теперь два правила, которые соответствуют всем параграфам. Они имеют одинаковую важность и одинаковую специфичность (так как селектор один и тот же), поэтому окончательным механизмом для различения будет порядок исходного кода.

Последнее правило определяет color:black и оно будет переопределять color:cyan из предыдущего правила.

Обратите внимание, что первый параграф вообще не затрагивается этим новым правилом. Хотя новое правило появляется последним, его селектор имеет меньшую специфичность, чем у #special. Это четко показывает, что специфичность имеет более высокий приоритет, чем порядок исходного кода.

Заключение

Наследование и каскадирование являются фундаментальными концепциями, которые должен понимать каждый Web-дизайнер.

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

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

Контрольные вопросы

  • Наследуется ли свойство width? Подумайте сначала об этом - будет ли это иметь смысл? - затем посмотрите правильный ответ в спецификации CSS (http://www.w3.org/TR/CSS21/).
  • Если добавить !important в объявление color:black в последнем правиле в нашем примере таблицы стилей, будет ли это как-то влиять на цвет текста в первом, "специальном" параграфе?
  • Какой селектор более специфический, " #special " или " html>head+body>h1+p "?
  • Как должна выглядеть таблица стилей пользователя, чтобы наш тестовый документ выводился черным шрифтом Comic Sans MS на белом фоне, независимо от таблицы стилей автора?

Об авторе

Томми Олссон является прагматичным пропагандистом стандартов Web и доступности, который живет в малонаселенной области центральной Швеции. Он написал свой первый документ HTML в 1993 г. и является в настоящее время техническим Web-мастером для правительственного агентства Швеции.

Он написал пока одну книгу - Полный справочник по CSS (совместно с Полем О'Брайеном) - и поддерживает крайне нерегулярно блог с названием Кукушка-аутист (http://www.autisticcuckoo.net/).

Материалы этого курса имеют лицензию Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.
< Лекция 27 || Лекция 28: 12 || Лекция 29 >
Марина Походаева
Марина Походаева

Помогите мне. Я ничего не понимаю в курсе ((((((   (от слова "совсем") и мне от этого очень грустно. Есть ли какие-нибудь курсы для "чайников", самые простые в объяснении. ПАМАГИТЕ!!!

Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Данила Некрасов
Данила Некрасов
Россия, Пермь, ПНИПУ
Сергей Федоров
Сергей Федоров
Россия