SNK Software
Web Studio Монополия Metaproducts Утилиты Игры
Монополию Web Studio Библиотека
Вебмастер Дельфи Работа на ПК Самоучитель
Для PHP Для Delphi
Веб-дизайн Программирование Компьютеры Девайсы Заметки
SNK Software Индустрия hardware Индустрия software
О студии Портфолио Сопровождение сайтов

Новые материалы

Девайсы:
Сравнительный обзор Nokia Lumia 920 и HTC 8X
Девайсы:
Обзор Nokia Lumia 820 – смартфона на WP8
Вебмастеру:
Настройка Apache, PHP и MySQL для Linux-VPS
Вебмастеру:
VPS на домашнем ПК: настройка сети в VM VirtualBox и Debian
Вебмастеру:
VPS на домашнем ПК: устанавливаем Linux Debian 6
Вебмастеру:
VPS на домашнем ПК: установка VM VirtualBox
Работа на компьютере:
Иные возможности текстового процессора Word
Работа на компьютере:
Вставка объектов
Работа на компьютере:
Таблицы в Word
Работа на компьютере:
Печать и сохранение документов
Работа на компьютере:
Сноски, колонтитулы, оглавление и указатели в Word

Селекторы CSS

В этой главе:

  1. Селекторы классов и идентификаторов
  2. Селекторы атрибутов
  3. Родственные селекторы
  4. Псевдоклассы
  5. Псевдоэлементы
  6. Наследование и каскадирование

В предыдущей главе мы в целом изучили составление правил CSS. Если бы применение таблиц стилей ограничивалось атрибутом STYLE, то этого было бы достаточно для того, чтобы начать использовать CSS. Но поскольку применение таблиц стилей гораздо более гибкое (на то они и каскадные), то для описания порядка применения правил к документу в CSS 2.1 предусмотрен мощный механизм селекторов.

Селекторы классов и идентификаторов

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

p {font-face: Arial} /* селектор элементов p */ .extra {font-weight: bold} /* селектор класса extra */ #part1 {font-size: 1pc} /* селектор идентификатора part1 */

Селекторы элементов, классов и идентификаторов можно комбинировать. Например, если мы хотим указать, что определяемое правило для класса «extra» должно распространяться только на элементы P, имеющие этот класс, следует объединить в селекторе элемент и его класс:

p.extra {font-weight: bold}

Такой шаблон совпадет только с элементами P, имеющими указанный класс, но не с другими элементами P или иными элементами с классом extra. Так, если мы применим такую таблицу к документу, приведенному в листинге 3.2, то сможем убедиться, что определенное нами правило было применено только к первому абзацу (рис. 3.1).

Листинг 3.1. Селекторы классов

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"> <html> <head> <title>Селекторы классов</title> <style type="text/css"> p.extra {font-weight: bold} </style> </head> <body> <p class="extra">Элемент P с классом extra</p> <p class="super">Элемент P с другим классом (super)</p> <p>Элемент P без определенного класса</p> <div class="extra">Другой элемент (DIV) с классом extra</div> </body> </html> Селектор класса CSS для элемента P

Рис. 3.1. Селектор класса для элемента P

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

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

p.extra#unicum {font-weight: bold}

Для того чтобы «сработало» заданное таким образом правило, придется несколько изменить документ из листинга 3.1, в частности, два первых абзаца будут такими:

<p class="extra">Элемент P с классом extra</p> <p class="extra" id="unicum">Элемент P с классом extra и идентификатором unicum</p>

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

От такого особо выборочного варианта перейдем к наиболее общему: в CSS имеется специальный обобщающий шаблон «*» (звездочка), который подразумевает любой элемент. Таким образом, следующее правило будет применяться абсолютно ко всем элементам документа:

* {background: transparent;}

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

.extra {font-weight: bold} *.extra {font-weight: bold}

Обе эти записи эквивалентны, так что ставить или нет в подобных случаях звездочку перед именем класса или идентификатором – решать вам.

Селекторы атрибутов

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

p.major {color: red} /* стандартное применение селектора класса */ p[class="major"] {color: red} /* использование селектора атрибута */

Хотя вторая запись кажется более громоздкой, и в данном случае использование такого синтаксиса – не лучшая идея, в ряде других случаев селекторы атрибута могут быть очень полезными. Так, в данном случае был использован селектор с совпадением значения (т.е. значение атрибута должно совпасть с указанным текстом), однако допустимо указывать и более общий случай – например, для всех элементов, имеющих атрибут class:

p[class] {background: red}

В этом случае для всех элементов P, имеющих атрибут CLASS, вне зависимости от того, какое именно значение имеет этот атрибут, будет установлен красный цвет фона. Собственно, вместо CLASS может быть указан любой другой атрибут, например, TITLE:

a[title] {text-decoration: none;}

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

ПРИМЕЧАНИЕ
К сожалению, вам, возможно, так и придется поступать еще некоторое время, поскольку в MSIE 6-7 селекторы атрибутов не поддерживаются, как и многие другие новые методы каскадирования, появившиеся в CSS 2. Полную поддержку селекторов CSS уровня 2 имеют лишь современные браузеры Mozilla и Opera.

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

img[title~="Москва"] {border: red}

В этом случае все картинки, имеющие в подписи слово «Москва», будут заключены в красную рамку:

<img src="mos1.jpg" title="Москва днем" /> <img src="mos2.jpg" title="Москва ночью" /> <img src="mos3.jpg" title="Универмаг Москва" />

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

div[lang|="en"] { font-style: italic;}

Такой шаблон подойдет к любому блоку с указанным языком, начинающимся на en:

<div lang="en-us">American English</div> <div lang="en-uk">British English</div> <div lang="en">English</div>

Все три блока получат курсивное начертание шрифта. Впрочем, ничего не мешает использовать такие шаблоны и для любых других случаев. Допустим, если бы мы изменили в шаблоне Москва «img[title~="Москва"]» на «img[title|="Москва"]», то он был бы применен к такой вот картинке:

<img src="mos4.jpg" title="Москва-река" />

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

*[title] {text-decoration: underline} [lang|="en"] {font-style: italic;}

Здесь в первой строке мы задали подчеркивание для всех элементов, имеющих атрибут TITLE, а во второй – наклонный шрифт для любых элементов с установленным английским языком.

Резюмируя информацию по селекторам атрибутов, остается сделать две вещи: свести правила совпадения в таблицу 3.2 и высказать сожаление, что они (увы!) не поддерживаются наиболее популярной программой просмотра.

Совпадает, когда элемент имеет указанный атрибут, а его значение состоит из разделенных черточкой слов и начинается с указанного слова

Дополнительные примеры с селекторами атрибутов можно посмотреть в файле Part_3\Selectors\selattr.html.

Родственные селекторы

Другим мощным средством выборочного назначения правил CSS является использование «родственных» селекторов. К таковым относятся селекторы потомков, селекторы дочерних элементов и смежные родственные (или «сестринские») селекторы.

Селекторы потомков были введены еще в CSS 1, и, следовательно, поддерживаются всеми CSS-совместимыми браузерами. Они используются в тех случаях, когда необходимо сопоставить селектор элементу, являющемуся потомком некоторого другого элемента в дереве документа (скажем, элементам P, вложенным в DIV). Такой селектор состоит из или более селекторов, разделенных пробелом:

div p {font-style: italic}

Эта запись определяет курсивное начертание текста во всех элементах P, вложенных в DIV. Подобно другим селекторам, потомков можно сочетать с классами и иными типами селекторов. Например, мы можем определить для элемента P класс «special», при этом все вложенные в блоки DIV элементы такого класса должны быть зелеными, а вне блоков – красными. Для этого создадим два правила: одно – для общего случая, второе – для потомка:

p.special {color: red} div p.special {color: green}

Если теперь совместить оба примера в одной таблице стилей и написать подходящий код HTML (листинг 3.2), то можно воочию увидеть применение селекторов потомков (рис. 3.2).

Листинг 3.2. Селекторы потомков

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html> <head> <title>Селекторы потомков</title> <style type="text/css"> div p {font-style: italic} p.special {color: red} div p.special {color: green} </style> </head> <body> <p>Абзац P вне блока DIV</p> <div> <p>Абзац P, вложенный в блок DIV</p> <p class="special">Абзац P класса "special", вложенный в DIV</p> </div> <p class="special">Абзац P класса "special" вне блока DIV</p> </body> </html>CSS - Селекторы потомков

Рис. 3.2. Селекторы потомков

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

ul {color: red} ul ul {color: green}

Здесь мы определили, что списки верхнего уровня будут красными, а вложенные в них – зелеными. Можно несколько видоизменить задачу, и добиться того, чтобы зеленый цвет имели лишь нумерованные списки, вложенные в обычные. Для этого достаточно в нижней строке изменить второй UL на OL:

ul ol {color: green}

Теперь все нумерованные списки, вложенные в ненумерованные будут красными. Собственно, как и все друге нумерованные списки, в том числе и вложенные в другие нумерованные, если они в качестве общего предка будут иметь UL. Например, в таком случае:

<ul> <li>Строка ненумерованного списка (красная)</li> <ol> <li>Строка нумерованного списка, вложенного в ненумерованный (зеленая) </li> <ol> <li>Строка нумерованного списка, вложенного в нумерованный (зеленая) </li> </ol> </ol> </ul>

Суть здесь в том, что использование селекторов потомков подразумевает общее наследование, т.е. неважно, какой именно элемент является непосредственным «родителем» – все вложенные в него элементы унаследуют определенный таким образом стиль. Если же требуется более строгий учет в иерархии, то следует применять дочерние селекторы, введенные в CSS уровня 2. В отличие от селекторов потомков, дочерние селекторы явно указывают на то, какой элемент должен быть предшествующим в дереве документа. Так, чтобы в рассмотренном случае с двумя вложенными нумерованными списками правило «color: green» распространялось лишь на те нумерованные списки, которые непосредственно вложены в ненумерованные, следует задать такой селектор:

ul > ol {color: green}

Здесь знак «>» как раз указывает на то, что данный селектор является дочерним. Теперь строка второго (внутреннего) нумерованного списка будет иметь тот же цвет, что и любой другой нумерованный список. Допустим, общее правило определяет красный цвет для всех списков:

ol, ul {color: red}

В таком случае для нашего примера мы получим такие цвета: самый внешний (ненумерованный) список будет красным, вложенный в него (нумерованный) список будет зеленым, и, наконец, вложенный в него второй нумерованный список будет кранным (рис. 3.3, см. так же файл child.html).

Вложенные списки и дочерние селекторы CSS

Рис. 3.3. Вложенные списки и дочерние селекторы

Кроме дочерних, можно определять и «внучатые» селекторы. Хотя в CSS 2 таковых явно не предусмотрено, делается это путем сочетания двух дочерних селекторов:

ul > * > ol {color: blue}

Такой селектор охватит все нумерованные списки, которые в качестве своего «дедушки» будут иметь ненумерованный список (если добавить такое правило в только что рассмотренный пример, то последний список будет синим).

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

div p > cite {text-decoration: blink}

Разобравшись таким образом с различными по уровню иерархии селекторами, перейдем к смежным. Они имеют синтаксис «Элемент1 + Элемент2», где «Элемент2» является областью действия селектора, а «Элемент1» указывает на то, что должно непосредственно предшествовать «Элементу2». При этом оба элемента должны иметь общего предка (листинг 3.3).

Листинг 3.3. Смежные селекторы

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html> <head> <title>Смежные селекторы</title> <style type="text/css"> h1 + h2 {margin-top: -0.5em} </style> </head> <body> <h1>Заголовок 1</h1> <h2>Заголовок 2</h2> </body> </html>

В данном случае общим предком для обоих заголовков является элемент BODY, а элемент H1 непосредственно предшествует элементу H2. В результате выполняется правило «margin-top: -0.5em», благодаря которому расстояние между заголовками получается меньшим, чем обычно (см. файл sibling.html).

Итак, мы рассмотрели все три типа родственных селекторов, предусмотренных в CSS уровня 2 – потомственные, дочерние и смежные. И хотя MSIE поддерживает только потомственные селекторы, применение двух других типов также может быть востребованным, например, для создания более изысканного оформления для CSS-2 браузеров или для преодоления разночтений в поддержке CSS разными программами просмотра. Так, между MSIE и другими браузерами часто возникают разночтения по части полей (свойства margin, padding). В таких случаях можно добиться идентичного отображения путем указания разных значений: при помощи селекторов потомков – для MSIE, и дочерних селекторов – для других браузеров.

Псевдоклассы

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

Всего в CSS 2 определено семь псевдоклассов, три из которых «досталось в наследство» от CSS 1. Прежде всего, это псевдоклассы ссылок :link и :visited, а так же динамические псевдоклассы :active, :hover и :focus. Кроме того, имеются еще псевдоклассы :first-child и :lang. В CSS 1 имелись только псевдоклассы ссылок, причем тогда их было не 2, а 3, поскольку псевдокласс :active относился к ним же. Кроме того, в MSIE имеется поддержка псевдокласса :hover, но в этой программе он тоже относится к псевдоклассам ссылок, поскольку динамические псевдоклассы, введенные в CSS 2, браузер от Microsoft все еще не поддерживает. Разница между псевдоклассами ссылок и динамическими псевдоклассами состоит в том, что если первые могут применяться только к ссылкам (элементам A), то вторые – к любым элементам. Вместе с тем, поскольку это единственное принципиальное отличие между данными группами псевдоклассов, то мы можем объединить их в общую группу и рассмотреть вместе (таблица 3.3).

Таблица 3.2. Селекторы атрибутов
Тип шаблонаОписание
[атрибут]Совпадает, когда элемент имеет указанный атрибут
[атрибут=значение]Совпадает, когда элемент имеет указанный атрибут с указанным значением
[атрибут~=слово]Совпадает, когда элемент имеет указанный атрибут, а в его значении имеется указанное слово
[атрибут|=слово]Совпадает, когда элемент имеет указанный атрибут, а его значение состоит из разделенных черточкой слов и начинается с указанного слова
Таблица 3.3. Ссылочные и динамические псевдоклассы
ПсевдоклассОписание
:linkПрименяется, если ссылка не была просмотрена пользователем
:visitedПрименяется, если ссылка уже была просмотрена пользователем
:activeПрименяется, когда элемент активизируется пользователем. Например, между моментами, когда пользователь нажимает кнопку мыши и отпускает ее
:hoverПрименяется, когда пользователь выделяет элемент, но не активизирует его. Например, браузер может применять этот псевдокласс, когда курсор (указатель мышки) находится над данным элементом
:focusПрименяется, когда элемент находится в центре некоторых событий (включая события клавиатуры или другие типы ввода текста)

Рассмотрим применение основных псевдоклассов на наиболее часто встречающееся примере – ссылках:

a:link {color: red} /* не посещенные ссылки */ a:visited {color: blue} /* посещенные ссылки */ a:hover {color: green} /* во время выделения ссылки */ a:active {color: black} /* в момент щелчка по ссылке */ a:focus {background: yellow} /* на время получения фокуса ввода */

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

Псевдокласс :first-child, впервые введенный в CSS уровня 2, сопоставляется элементу, который является первым дочерним элементом некоторого другого элемента. Допустим, мы определили, что все абзацы должны иметь «красную строку» размером в 2 символа:

p {text-indent: 2em}

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

div > p:first-child {text-indent: 0}

К подобному способу нередко прибегают и для выделения первой строки списка:

li:first-child {color: red}

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

ol > li:first-child {color: red} /* только для списков OL */ ol li:first-child {color: red} /* для любого списка, если он вложен в OL */

Пример использования :first-child можно посмотреть в файле pseudocl.html, а в завершение знакомства с псевдоклассами рассмотрим еще один – :lang. Псевдокласс «:lang(X)» сопоставляется элементу, использующему язык «X». Сам язык определяется в документах HTML 4.0 и XHTML 1.0 при помощи атрибута LANG, а в XHTML 1.1 и XML – при помощи XML:LANG. Например, можно определить правило, согласно которому вид кавычек будет изменяться в зависимости от языка, на котором написано окружающее содержимое:

:lang(ru) > q { quotes: '«' '»'} :lang(en) > q { quotes: '"' '"'}

Результат таких манипуляций пока что можно увидеть лишь в Mozilla-браузерах (рис. 3.4), т.к. MSIE не поддерживает ни псевдоклассов CSS 2, ни элемента Q из HTML 4, а у Opera имеются некоторые затруднения с многоязыковой поддержкой.

Псевдокласс :lang и расстановка кавычек

Рис. 3.4. Псевдокласс :lang и расстановка кавычек

Псевдоэлементы

В отличие от псевдоклассов, псевдоэлементы формируют абстрактные представления о дереве документа в дополнение к тем, которые определяются языком документа. Например, в HTML не предусмотрено алгоритмов доступа к первой букве или первой строке содержимого элемента, но при помощи псевдоэлементов CSS вы сможете обращаться к таким объектам, доступ к которым нельзя получить другим способом. Кроме того, псевдоэлементы предоставляют различные способы назначения стиля содержимому, не существующему в исходном документе. Так, псевдоэлементы :before и :after предоставляют доступ к генерируемому содержимому.

Всего в CSS уровня 2 определено 4 псевдоэлемента. Это уже упомянутые :before и :after, а так же :first-line и :first-letter, отвечающие за доступ к первой строке и первой букве текста в блочном элементе, соответственно. Начнем с :first-line. В типичном случае его используют для выделения первой строки в абзаце (P):

p:first-line {text-decoration: underline}

Здесь сразу можно раскрыть суть названия «псевдоэлемент». Допустим, только что определенный нами стиль будет применен к такому фрагменту HTML-документа:

<p>Некоторый абзац текста, первая строка которого будет выделена подчеркиванием при помощи псевдоэлемента :first-line.</p>

Представим себе, что при графическом построении браузером этого документа первая строка закончится на слове «подчеркиванием». В таком случае браузер вставит пару виртуальных (или «псевдо») тегов: открывающий – сразу за P и закрывающий – перед обрывом строки:

<p><p:first-line>Некоторый абзац текста, первая строка которого будет выделена подчеркиванием</p:first-line> при помощи псевдоэлемента :first-line.</p>

Если впоследствии ширина абзаца изменится (скажем, пользователь развернет окно браузера на весь экран), то расположение закрывающего «псевдотега» соответствующим образом изменится, чтобы эффект распространялся только на первую строку абзаца. Аналогичным образом работает и псевдоэлемент :first-letter, его отличие от :first-line состоит лишь в том, что он отвечает только за первую букву текстового блока:

p:first-letter: {font-size: 200%}

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

Несколько интереснее дело обстоит с псевдоэлементами :before и :after. Их можно использовать для вставки генерируемого содержимого до или после содержимого элемента. Например, чтобы выделить подписью некоторые абзацы (скажем, имеющие класс «special»), можно определить такое правило:

p.special:before {content: "Спецабзац! "}

Таким образом, хотя в самом документе такого слова и не будет, при выводе на экран браузер добавит его, как и любое другое содержимое, определенное при помощи свойства content. Остается заметить, что когда псевдоэлементы :first-letter и :first-line сочетаются с псевдоэлементами :before и :after, они применяются к первой букве или строке элемента, включая вставляемый текст:

p.special:first-letter {color: red}

Пример работы приведенных здесь селекторов можно посмотреть в файле pseudoel.html, а подробнее о генерируемом тексте будет рассказано в соответствующей главе.

ПРИМЕЧАНИЕ
Поддержка псевдоэлементов имеется у Opera 5.0 и выше, всех вариантов Mozilla, и MSIE, начиная с версии 5.5, хотя у последнего генерируемый текст, а, следовательно, и псевдоэлементы :before и :after не поддерживаются до версии 8.0.

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

Завершив таким образом знакомство с селекторами, разберемся с тем, как происходит само назначение стилей. Прежде всего, важно знать, что в процессе обработки таблицы стилей, заданные в ней значения проходят до 4-х этапов обработки. Так, после того, как браузер произвел синтаксический анализ исходного текста и создал дерево документа, он должен присвоить каждому свойству каждого элемента этого дерева некоторое значение. На первом этапе происходит самое интересное – свойствам присваивается заданное значение, которое может быть результатом каскадирования CSS, быть унаследованным от родительского элемента, или же являться начальным значением, заданным в определении элемента. Затем заданное значение, если оно было задано в относительных величинах (например, в процентах), будет преобразовано в вычисляемое, которое, после ряда манипуляций и необходимых аппроксимаций (скажем, линия не может быть шириной 14,5 пикселей, а только 14 или 15), приводится к фактическому. Так вот на первом этапе вычисления значения мы сталкиваемся с двумя основополагающими принципами CSS – наследованием и каскадированием.

Многие значения наследуются дочерними элементами в дереве документа. Каждое свойство определяет, является оно наследуемым или нет. Допустим, у нас имеется таблица стилей, определяющая синий цвет для элемента BODY:

body {color: blue}

Если теперь создать использующий такую таблицу документ HTML, то все его элементы (а все выводимые элементы явно или неявно являются вложенными в контейнер BODY) будут синего цвета, по крайней мере, кроме тех, у которых явно не указано иначе:

<body> <p>Абзац синего цвета</p> <div>Тоже синий... <h1>И заголовок синий</h1> Здесь <cite>снова</cite> синий. </div> </body>

Здесь все вложенные в BODY элементы, включая P, DIV, H1 и CITE унаследовали цвет от родительского элемента BODY. Здесь мы видим наследование абсолютного значения (т.е. явно был задан синий цвет), у процентных же значений наследуется не то, что было задано, а результат вычислений. Например, если для BODY установить размер шрифта 10pt, а для заголовка H1 указать размер шрифта 140%, то вычисляемый размер шрифта заголовка будет 14pt, и именно это значение унаследует любой элемент, вложенный в заголовок (а это может быть любой строчный элемент – EM, SITE и т.п.). Пример такого несложного наследования можно посмотреть в файле inheritance.html.

После того, как мы ознакомились с наследованием, пора разобраться с каскадированием. Для начала отметим, что таблицы стилей всегда имеют три источника: разработчика, пользователя и программы просмотра. В качестве разработчика выступает автор страницы, а пользователя – ее посетитель, который может при помощи настроек своего браузера указать собственные стили (рис. 3.5), что, на самом деле – большая редкость, но знать об этом все равно полезно.

адание пользовательского файла со стилями в MSIE 6

Рис. 3.5. Задание пользовательского файла со стилями в MSIE 6.0

Что касается браузера, то он всегда имеет собственную таблицу стилей (разумеется, если он поддерживает CSS), в которой задано стандартное оформление для всех поддерживаемых им элементов: именно благодаря этим стилям заголовки всегда крупные, цитаты – выделены курсивом, а абзацы – выровнены по левому краю. Поскольку области действия этих таблиц могут пересекаться (скажем, в браузере размер кегля для H1 задан в 18pt, а вы указали 20), то для их правильного взаимодействия используется правило каскада. Каскад CSS назначает каждому правилу стиля определенный приоритет. При выполнении нескольких правил преимущество имеет правило с большим приоритетом. По умолчанию правила в таблицах стилей разработчика имеют больший приоритет, чем правила в пользовательских таблицах стилей.

ПРИМЕЧАНИЕ
Для важных правил («!important») ситуация противоположна, поскольку такие правила наделяется преимуществом перед обычным объявлением. Таблицы стилей как разработчика, так и пользователя могут содержать важные объявления, но пользовательские правила «!important» в CSS 2 имеют приоритет над правилами «!important» разработчика.

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

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

В принципе, ничего сложного здесь нет: подходящие объявления выбираются по селектору, а изо всех таблиц объявлений практически всего приходится иметь дело лишь с обычными стилями разработчика (стили браузера нами воспринимаются как нечто само собой разумеющееся, и обращать на них внимание мы не будем). Некоторые вопросы могут возникнуть с 3-м пунктом – по части определения специфичности селектора. Рассмотрим этот вопрос на примере листинга 3.4.

Листинг 3.4. Каскадирование таблиц стилей

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html> <head> <title>Каскадирование</title> <style type="text/css"> h1 {color: green} .special {color: blue} #urgent {color: red} </style> </head> <body> <h1>Просто заголовок H1</h1> <h1 class="special">"Специальный" заголовок H1</h1> <h1 class="special" id="urgent">"Важный" заголовок H1</h1> </body> </html>

Здесь мы определили 3 стиля: зеленый цвет для всех элементов H1, синий цвет – для элементов с классом «special2 и красный – для элементов с идентификатором «urgent». В самом документе имеются три элемента H1, следовательно, правило «зеленый цвет» подходит ко всем им. Однако этот селектор, с точки зрения правил CSS, является более общим, чем селектор класса. Поэтому второй заголовок получит синий цвет. Ну а третий заголовок будет красным, поскольку стиль для него будет получен от наиболее специфичного селектора – имени идентификатора. Теперь можно несколько усложнить задачу, добавив в стили строку:

h1.special {color: black}

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

h1.special#urgent {color: orange}

Если добавить такую строку в таблицу стилей, то последний заголовок изменит свой цвет на оранжевый. В то же время, и это еще не является пределом! Помните правила наследования при определении селектора? Они тоже учитываются. Так что и такое правило можно перекрыть, указав явно, что h1 должен быть наследником BODY:

body h1.special#urgent {color: white}

На этот раз заголовок сольется с фоном. Впрочем, даже такое правило не будет самым значимым, поскольку учитывается еще и расположение правила: чем позже оно объявлено (или чем ближе оно к элементу, если угодно), тем выше его приоритет (см. пункт 4!). Соответственно, если после одного объявления поместить точно такое же, но с другими параметрами, то будет выполнено последнее. Ну а «самым последним» по правилам каскадирования является то, что написано в атрибуте STYLE. Таким образом, наивысший приоритет имеет такое объявление:

<h1 class="special" id="urgent" style="color: yellow">Заголовок</h1>

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

h1 {color: green !important }

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

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

  1. Наиболее специфичным является идентификатор элемента (указание правил в атрибуте STYLE мы тут опускаем);
  2. Следом идет совпадение значения атрибутов, в первую очередь – имен классов, а так же псевдоклассов. При этом, чем большее число атрибутов или классов совпадает, тем более специфичным получается селектор;
  3. Наименее специфичным является имя элемента (или псевдоэлемента), при этом указание «родственности» повышает приоритет.

Примеры каскадирования можно посмотреть в файле cascade.html, и на этом можно завершить знакомство с селекторами и перейти к вопросам собственно оформления – то есть к тому, для чего CSS, собственно и предназначаются.

2011-06-16 // Есть вопросы, предложения, замечания? Вы можете обсудить это на форуме !

Избранное

SNK GSCP
SNK GSCP - новая библиотека для PHP 5!
Web Studio
Web Studio и Visual Workshop
Библиотека:
Стандарты на web-технологии
Монополия
Монополия Android
Загрузки:
скачать программы
Продукция:
программы и книги
Техподдержка / Связаться с нами
Copyright © 1999-2020 SNK. Все права защищены.
При использовании материалов с сайта ссылка на источник обязательна.
Рейтинг@Mail.ru