Руководство по HTML5
Адам Фриман
Каскады и наследование стилей
Ключом к пониманию стилей является понимание их каскадирования и наследования. Смысл каскадирования и наследования заключается в том, что с их помощью браузер определяет, какие значения следует использовать для свойства, когда он отображает элемент. У каждого элемента имеется ряд CSS свойств, которые будут использоваться, когда браузер отображает страницу. Для работы с каждым из этих свойств браузер должен перемещаться по всем источникам стилей, которые у него есть. Вы видели три различных способа определения стилей (внутренний, встроенный и внешняя таблица стилей), но есть два других источника стилей, о которых вы должны знать.
Браузерные стили
Браузерные стили (более известные как стили пользовательского агента) являются стилями по умолчанию, которые браузер применяет к элементу, если не были указаны другие стили. Эти стили немного различаются у разных браузеров, но они, как правило, в целом аналогичны. В качестве примера рассмотрим, как браузер отображает элемент а
, гиперссылку, когда нет других стилей, определенных в HTML документе. В листинге 4-10 показан простой HTML документ, который не содержит никаких стилей.
Листинг 4-10: HTML документ, который не содержит стилей
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
Этот листинг является всего лишь вариацией предыдущего примера, только без всякого стиля. Вы можете увидеть, как браузер отображает элементы, на рисунке 4-7.
Рисунок 4-7: Стиль по умолчанию для элементов гиперссылки
Мы так привыкли видеть стили, которые браузеры используют для показа ссылок, что уже не обращаем на это никакого внимания. Однако если мы остановимся и внимательно на них посмотрим, то сможем увидеть детали стиля. Текстовое содержимое ссылки отображается синим цветом, и оно подчеркнуто. Можно немного отвлечься и представить себе, что браузер применяет стиль, похожий на тот, что показан в листинге 4-11.
Листинг 4-11: Создание стиля, сходного тому, который использует браузер по умолчанию для элемента a
a {
color: blue;
text-decoration: underline;
}
У браузеров нет стилей по умолчанию для каждого HTML элемента, но многие элементы отображаются с помощью таких стилей. В каждой главе этой книги, которая описывает HTML элементы, я расскажу о стилях по умолчанию, обычно применяемых браузерами. Вы можете посмотреть описание элемента a
в главе 8.
Пользовательские стили
Большинство браузеров позволяют пользователям определять свои собственные таблицы стилей. Стили, которые содержатся в этих таблицах, называются пользовательскими стилями. Это не является широко используемой возможностью, но пользователи, которые определяют свои собственные таблицы стилей, часто придают этому большое значение, не в последнюю очередь потому, что в состоянии сделать это и потому что пользовательские стили делают страницы более доступными.
У каждого браузера есть свой собственный механизм для пользовательских стилей. Google Chrome, например, создает файл в папке профиля пользователя с именем Default\User StyleSheets\Custom.css
. Любые стили, добавленные в этот файл, применяются к любому сайту, который посещает пользователь, при условии соблюдения правил каскадирования, которые я опишу в следующем разделе. В качестве простого примера в листинге 4-12 показан стиль, который я добавил в мой файл custom.css
.
Листинг 4-12: Добавление стиля в пользовательскую таблицу стилей
a {
color: white;
background:grey;
text-decoration: none;
padding: 2px;
}
Этот стиль применяется к элементу a
и переопределяет браузерный стиль по умолчанию. На рисунке 4-8 показан результат использования моего пользовательского стиля, когда я перезагружаю HTML документ листинга 4-9.
Рисунок 4-8: Определение пользовательских стилей
Каскадирование стилей
Теперь, когда вы видели все источники стилей, из которых браузер должен выбирать нужный, вы можете посмотреть, в каком порядке браузер будет искать значение свойства, когда дело дойдет до отображения элементов. Этот порядок является очень точным:
- Внутренние стили (стили, которые определяются для элемента с помощью глобального атрибута
style
) - Встроенные стили (стили, которые определены элементом
style
) - Внешние стили (стили, которые импортируются при помощи элемента
link
) - Пользовательские стили (стили, которые были определены пользователем)
- Браузерные стили (стили по умолчанию, которые применяются браузером)
Представьте себе, что пользователю нужно отобразить элемент a
. Одной из вещей, которую должен знать браузер, является цвет отображения текста. Чтобы решить этот вопрос, нужно найти значение CSS свойства color
. Во-первых, браузер будет проверять, имеет ли обрабатываемый элемент внутренний стиль, который определяет значение цвета, например:
<a style="color: red" href="http://apress.com">Visit the Apress website</a>
Если внутреннего стиля нет, браузер будет искать элемент style
, содержащий стиль, который применяется к обрабатываемому элементу, например:
<style type="text/css">
a {
color: red;
}
</style>
Если такого элемента style
нет, браузер ищет в таблицах стилей, которые были загружены при помощи элемента link
, и так далее, пока браузер не найдет нужного значение свойства color
; это обозначает, что если он такового не найдет, то будет использовать значение, заданное в браузерных стилях по умолчанию.
Первые три источника свойства (внутренние стили, встроенные стили и таблицы стилей) в совокупности именуются авторскими стилями. Стили, определенные в пользовательских таблицах стилей, известны как пользовательские стили; и стили, определенные в браузере, известны как браузерные стили.
Изменение порядка при помощи стилей important
Вы можете изменить обычный порядок каскада, отметив ваши значения свойств как important, что показано в листинге 4-13.
Листинг 4-13: Обозначение свойств стиля как important
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
a {
color: black !important;
}
</style>
</head>
<body>
<a style="color: red" href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
Вы отмечаете отдельные значения как важные, добавляя в объявление !important
. Браузер отдает предпочтение важным стилям (стилям с !important
), независимо от того, где они определены. Вы можете увидеть результат использования стиля с !important
на рисунке 4-9, где встроенное значение свойства color
переопределяет внутреннее значение. (Возможно, это немного трудно понять по печатной странице).
Рисунок 4-9: Значения !important
свойства переопределяют внутренние значения свойства
Совет
Единственным, что будет иметь приоритет над важным значением (
!important
), которое вы определяете, является важное значение, определенное в пользовательских таблицах стилей. Для обычных значений авторские стили используются прежде чем пользовательские стили, но это порядок меняется, когда речь идет о значениях!important
.
Вычисление специфичности и порядка использования стилей с равным приоритетом
Вы сталкиваетесь с равным приоритетом стилей (tie-breaking), если существуют два стиля, которые могут применяться к элементу, и они определенны на одном и том же уровне, и оба содержат значения CSS свойства, которое ищет браузер. Чтобы решить, какие значения использовать, браузер оценивает специфичность каждого стиля и выбирает тот, который наиболее специфичен. Браузер определяет специфичность стиля, подсчитывая три разные характеристики:
- Число значений
id
в селекторе стиля - Число атрибутов и псевдо-классов в селекторе
- Число имен элементов и псевдо-элементов в селекторе
Я объясню, как создать селекторы, которые содержат все эти различные характеристики в главах 17 и 18. Браузер подсчитывает значения каждой оценки и применяет значение свойства наиболее специфичного стиля. Очень простой пример специфичности представлен в листинге 4-14.
Листинг 4-14: Специфичность стилей
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
a {
color: black;
}
a.myclass {
color: white;
background: grey;
}
</style>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a class="myclass" href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
При оценке специфичности вы создаете число в виде a-b-c
, где каждая буква является итоговой суммой одной из трех подсчитываемых характеристик. Это не трехзначное число: более специфичным является тот стиль, чье значение a
является наибольшим. Только если a
значения равны, браузер сравнивает значения b
: стиль с большим значением b
является более специфичным в данном случае. Только если оба значения a
и b
равны, браузер рассматривает значение с
. Это обозначает, что специфичность 1-0-0 является более приоритетной, чем 0-5-5.
В нашем случае селектор a.myclass
включает в себя атрибут класса, а это значит, что специфичность стиля равна 0-1-0 (0 значений id
+ 1 другой атрибут + 0 имен элементов). Другой стиль имеет специфичность равную 0-0-0 (то есть, он не содержит id
, других атрибутов или имен элементов). Браузер находит значение свойства color
при обработке a
элемента, который был назначен классу myclass
. Для всех остальных a
элементов будет использоваться значение другого стиля. Вы можете увидеть, как браузер выбирает и применяет значения для данного примера, на рисунке 4-10.
Рисунок 4-10: Применение значений нужных стилей, основываясь на их специфичности
Если есть значения, определенные в стилях с одинаковой специфичностью, браузер выберет нужное значение, основываясь на порядке, в котором значения были определены: будет использоваться то значение, которое было определено последним. В листинге 4-15 показан документ, который содержит два стиля с одинаковой специфичностью.
Листинг 4-15: Стили с одинаковой специфичностью
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
a.myclass1 {
color: black;
}
a.myclass2 {
color: white;
background: grey;
}
</style>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a class="myclass1 myclass2" href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
Оба стиля, определенные в элементе style
, имеют одинаковые оценки специфичности. Когда браузер будет представлять второй элемент а
на странице, он выберет значение white
для обозначения свойства color
, потому что это значение определено в последнем стиле. Вы можете увидеть результат на рисунке 4-11.
Рисунок 4-11: Выбор значения свойства на основании порядка, в котором определены стили
Вы можете изменить порядок следования стилей, чтобы убедиться, что именно таким образом браузер выбирает значение свойства color
, как показано в листинге 4-16.
Листинг 4-16: Изменение порядка определения стилей
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
a.myclass2 {
color: white;
background: grey;
}
a.myclass1 {
color: black;
}
</style>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a class="myclass1 myclass2" href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
Как и ожидалось, значением, которое браузер выберет для свойства color
, теперь будет black
, что и показано на рисунке 4-12.
Рисунок 4-12: Результат изменения порядка определения стилей
Выбор значения базируется на специфичности и порядке следования, осуществляемыми по парадигме «свойство-за-свойством». В примерах, приведенных в этом разделе, я также определил значение для свойства background
. Поскольку это значение не было определено в обоих стилях, соответственно, не возникло никакого конфликта и, следовательно, не нужно было искать альтернативные значения.
Наследование
Если браузер не может найти значение свойства в одном из доступных стилей, он будет использовать наследование, то есть он будет использовать значение свойства, определенного родительским элементом. В листинге 4-17 представлен пример.
Листинг 4-17: Наследование CSS свойства
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
p {
color: white;
background: grey;
border: medium solid black;
}
</style>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a class="myclass1 myclass2" href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
В этом примере мы заинтересованы в свойствах, которые браузера применяет к элементу span
, чьим родительским элементом является элемент p
. Вы можете увидеть, как браузер обрабатывает этот документ, на рисунке 4-13.
Рисунок 4-13: Применение унаследованного значения CSS свойства
Нигде в этом документе я не определял в стиле значение для свойства color
, которое применяется к элементу span
, но браузер использует значение white
для отображения текстового содержания. Это значение было унаследовано от родительского элемента p
.
Это может показаться странным, но не все CSS свойства наследуются. Как правило, те, которые относятся к представлению элементов, наследуются (цвет текста, шрифт и т.д.), а те, которые относятся к расположению элементов на странице, не наследуются. Вы можете специально задать в стиле наследование с помощью особого значения inherit
, которое явно указывает браузеру использовать для свойства значения родительского элемента. В листинге 4-18 показано, как используется значение inherit
.
Листинг 4-18: Использование специального значения inherit
<!DOCTYPE HTML>
<html>
<head>
<title>Example</title>
<style type="text/css">
p {
color: white;
background: grey;
border: medium solid black;
}
span {
border: inherit;
}
</style>
</head>
<body>
<a href="http://apress.com">Visit the Apress website</a>
<p>I like <span>apples</span> and oranges.</p>
<a class="myclass1 myclass2" href="http://w3c.org">Visit the W3C website</a>
</body>
</html>
В этом примере я создал стиль, который будет применен к элементу span
и унаследует значение свойства border
родительского элемента. Вы можете увидеть результат на рисунке 4-14. Сейчас вокруг элемента span
есть рамка, и она содержится в элементе p
.
Рисунок 4-14: Использование наследуемого свойства