Глава 2.3. Значения свойств, каскадность и наследование

2.3.1. Вычисление значений свойств

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

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

  1. Если каскад возвращает значение, то используется оно.
  2. В противном случае, если свойство является наследуемым, то используется соответствующее значение отцовского элемента
  3. В противном случае, используется начальное значение свойства (оно указано ниже в определении каждого из свойств).

Специфицированные значения могут быть как абсолютными (например, red или 2mm), так и относительными (например, auto или 2em или 10%). Для абсолютных значений вычисленное значение совпадает со специфицированным. С другой стороны, относительные значения должны быть преобразованы к абсолютным. Так, процентные величины преобразуются в числа путем умножения на соответствующее значение; размеры, заданные в em, ex или px, умножаются на размер шрифта или пикселя; значение auto заменяется на величину, вычисляемую по формуле, указанной в определении соответствующего свойства и т. п.

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

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

Некоторые свойства наследуются детьми элемента в дереве документа. В определении каждого свойства указывается, является оно наследуемым или нет. Пусть, например, элемент H1 содержит элемент EM:

<H1>Этот заголовок <EM>очень важен</EM>!</H1>

Если элементу EM не присвоен цвет, то он унаследует цвет своего отца, т. е. элемента H1.

По этой причине для задания стиля отображения элементов "по умолчанию", достаточно задать стиль элемента HTML или BODY. Все остальные элементы являются потомками этих элементов, поэтому они будут наследовать их свойства. При этом важно помнить, что значения, заданные в виде процентных величин, не наследуются!

Многие свойства имеют в качестве возможного значения значение inherit. Оно означает, что в качестве значения свойства должно использоваться вычисленное значение данного свойства отцовского элемента.

2.3.3. Директива @import

Директива @import позволяет нам включать в свою таблицу стилей другие таблицы стилей. Она должна содержать URI импортируемой таблицы стилей; следующие две директивы эквивалентны и демонстрируют синтаксис данной директивы:

@import "mystyle.css";
@import url(mystyle.css);

Директива @import может содержать список названий устройств отображения, к которым должна применяться данная таблица стилей, разделенных запятыми, например:

@import url("fineprint.css") print;
@import url("bluish.css") projection, tv;

Если списка названий устройств нет, то предполагается, что он равен all, т. е. импортируемая таблица стилей применима ко всем устройствам.

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

Поддержка: Internet Explorer Поддерживаются только устройства all, screen и print (5.0+)
           Netscape Navigator Не поддерживается

2.3.4. Каскадность

2.3.4.1. Порядок каскадов

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

  • Автор задает таблицу стилей для своего документа, как было описано выше.
  • Пользователь также может задать свою таблицу стилей для конкретного документа.
  • Обозреватель должен применить к документу свою таблицу стилей по умолчанию прежде, чем применять к нему все остальные таблицы стилей.

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

По умолчанию, вес правил таблицы автора больше, чем вес правил таблицы пользователя (за исключением правил с атрибутом !important, для которых это соотношение является обратным). Вес правил таблиц автора и пользователя больше, чем вес правил таблицы обозревателя. Общий порядок определения правила и свойства, которые будут применены к элементу, таков:

  1. Выбираются все декларации, которые соответствуют данному устройству отображения; из них выбираются все правила, чьи селекторы соответствуют данному элементу.
  2. Декларации сортируются по весу их источника происхождения, как описано выше.
  3. Производится вторичная сортировка по специфичности селектора: более специфичные селекторы сильнее, чем более общие.
  4. И, наконец, последняя сортировка: если два правила имеют одинаковый вес и специфичность, то применяется последнее из них. При этом правила импортированных таблиц располагаются до всех правил импортирующей таблицы.

2.3.4.2. Атрибут !important

Для того, чтобы правила пользовательской таблицы стилей могли перекрывать авторскую, CSS содержит атрибут !important. Правило пользовательской таблицы стилей, имеющее такой атрибут, имеет больший вес, чем соответствующее правило авторской таблицы стилей. Рассмотрим следующий пример:

/* Из таблицы стилей пользователя */
P { text-indent: 1em !important }
P { font-style: italic !important }
P { font-size: 18pt }

/* Из таблицы стилей автора */
P { text-indent: 1.5em !important }
P { font: 12pt sans-serif !important }
P { font-size: 24pt }

Здесь первое правило таблицы стилей пользователя содержит атрибут !important, поэтому оно весомей, чем первое правило таблицы стилей автора. Второе правило пользователя также более весомо, по той же самой причине. Однако, третье правило пользователя менее весомо, чем второе правило автора. Точно также, третье правило автора менее весомо, чем его второе правило.

Поддержка: Internet Explorer Соответствует стандарту (4.0+)
           Netscape Navigator Не поддерживается

2.3.4.3. Специфичность селектора

Специфичность селектора вычисляется следующим образом:

  1. подсчитать количество атрибутов id в селекторе;
  2. подсчитать количество атрибутов class в селекторе;
  3. подсчитать количество имен элементов в селекторе (все псевдоэлементы игнорируются).

Теперь запишем эти три числа подряд, чтобы получить число из трех цифр (нам, возможно, придется привести числа a, b и c к системе счисления с большим основанием, чтобы каждое из них выражалось одной цифрой). Результатом и будет специфичность селектора (чем она выше, тем селектор специфичней). Приведем список примеров селекторов, отсортированных по их специфичности:

#id1         {…} /* a=1 b=0 c=0 --> спефифичность = 100 */
UL UL LI.red {…} /* a=0 b=1 c=3 --> спефифичность = 013 */
LI.red       {…} /* a=0 b=1 c=1 --> спефифичность = 011 */
LI           {…} /* a=0 b=0 c=1 --> спефифичность = 001 */

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