CSS-правила и селекторы
Теперь приступим к CSS, и начнём, пожалуй, с расшифровки аббревиатуры CSS. Это Cascading Style Sheets, дословно «каскадная таблица стилей», но:
— Почему же она называется каскадной? — этот вопрос я часто задаю на собеседованиях претендентам. Ответом же будет аналогия, ибо она незыблема как перпендикулярная лягушка: представьте себе каскад водопада, вот вы стоите на одной из ступенек каскада с чернильницей в руках, и выливаете её содержимое в воду — вся вода ниже по каскаду будет окрашиваться в цвет чернил. Применив эту аналогию на HTML — создавая правило для элемента, вы автоматически применяете его на все дочерние элементы (конечно, не все правила так работают, но исключения обсудим позже) — то есть, происходит «наследование стилей от элементов-родителей».
— Зачем мне всё это? — работая с jQuery, вы должны «на отлично» читать правила CSS, а также уметь составлять CSS-селекторы для поиска необходимых элементов на странице. Практически все задачи, которые вы будете решать с помощью jQuery, начинаются с поиска необходимого элемента на странице, так что знание CSS-селекторов обязательно.
Но давайте обо всём по порядку, возьмём следующий простенький пример вполне семантического HTML (см. html.example.html):
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="UTF-8"/>
<title>Page Title</title>
<link rel="shortcut icon" href="/favicon.ico"/>
<style>
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
h1, h2, h3 {
color: #333333;
}
header, section, footer {
position: relative;
max-width: 800px;
margin: 16px auto;
}
article {
padding: 16px;
margin-bottom: 16px;
}
#content {
padding-bottom: 16px;
}
.box {
border:1px solid #ccc;
border-radius:4px;
box-shadow:0 0 2px #ccc;
}
</style>
</head>
<body>
<header>
<h1>Page Title</h1>
<p>Page Description</p>
</header>
<section id="content">
<h2>Section Title</h2>
<article class="box">
<h3>Article Title</h3>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing...</p>
</article>
<article class="box">
<h3>Article Title</h3>
<p>Morbi malesuada, ante at feugiat tincidunt...</p>
</article>
</section>
<footer>
©copyright 2018
</footer>
</body>
</html>
Это пример простого и правильного HTML с небольшим добавлением CSS. Давайте разберём селекторы в приведённом CSS-коде (я умышленно не выносил CSS в отдельный файл, ибо так наглядней):
body
— данные правила будут применены к тегу<body>
и всем его потомкам, запомните: настройки шрифтов распространяются вниз «по каскаду»h1,h2,h3
— мы выбираем теги<h1>
,<h2>
и<h3>
, и устанавливаем цвет шрифта для данных тегов и их потомков#content
— выбираем элемент с «id="content"», настройки отступов не распространяются на потомков, они будут изменяться только для данного элемента.box
— выбираем элементы с «class="box"», и изменяем внешний вид границ элементов с заданным классом
Теперь подробнее и с усложнёнными примерами:
селектор | |
---|---|
h1 |
ищем элементы по имени тега |
#container |
ищем элемент по идентификатору «id=container» (идентификатор уникален, значит, на странице он должен быть только один) |
div#container |
ищем <div> c идентификатором «container», но предыдущий селектор работает быстрее, а этот важнее |
.news |
выбираем элементы по имени класса «class="news"» |
div.news |
все элементы <div> c классом «news» (так работает быстрее в IE8, т.к. в нём не реализован метод getElementsByClassName() ) |
#wrap .post |
ищем все элементы с классом «post» внутри элемента с «id="wrap"» |
.cls1.cls2 |
выбираем элементы с двумя классами «class="cls1 cls2"» |
h1,h2,.posts |
перечисление селекторов, выберем всё перечисленное |
.post > h2 |
выбираем элементы <h2> , которые являются непосредственными потомками элемента с классом «post» |
a + span |
будут выбраны все элементы <span> следующие сразу за элементом <a> |
a[href^=http] |
будут выбраны все элементы <a> у которых атрибут «href» начинается с «http» (предположительно, все внешние ссылки) |
Это отнюдь не весь список, описание же всех CSS-селекторов можно найти на соответствующей страничке W3C: https://www.w3.org/TR/selectors-3/
Возвращаясь к нашей аналогии с водопадом, представьте, что умников с чернильницей больше чем один и цвета разные, мы же в результате получим смешение цветов. Но это в жизни, а в CSS работают правила приоритетов, если кратко и по делу:
- самый низкий приоритет имеют стили браузера по умолчанию — в разных браузерах они могут отличаться, поэтому придумали CSS Reset (гуглится и юзается), и все будут на равных
- чуть важнее — стили, заданные пользователем в недрах настроек браузера; встречаются редко
- самые важные — стили автора странички, но и там всё идёт по порядку
- самый низкий приоритет у тех, что подключены файлом в мета-теге
<link rel="stylesheet" type="text/css" href="...">
- затем те, что встроили внутрь HTML с помощью тега
<style>
- потом те, что захардкодили плохие люди (не вы, вы так делать не будете) в атрибуте «style=""» при тегах
- самый высокий приоритет у правил с меткой
!important
- при равенстве приоритетов тапки у того, кто объявлен последним
- самый низкий приоритет у тех, что подключены файлом в мета-теге
Если голова ещё не болит, то я также упомяну, что при расчёте, чьи же правила главней, анализируется специфичность селекторов, и тут считается следующим образом:
- расчёт происходит по четырём весовым позициям
[0:0:0:0]
- стили заданные в атрибуте «style=""» имеют наибольший приоритет и получают единицу по первой позиции —
[1:0:0:0]
- за каждый идентификатор элемента (
#id
) —[0:1:0:0]
- за каждый класс (
.class
), либо псевдо-класс (:pseudo
) —[0:0:1:0]
- за каждый тег (
<a>
,<div>
) —[0:0:0:1]
- при этом
[1:0:0:0]
>[0:x:y:z]
>[0:0:x:y]
>[0:0:0:x]
- при равенстве счета — снова тапки у того, кто объявлен последним
Пример селекторов, выстроенных по возростанию приоритета (все селекторы кликабельны, результат работы можно посмотреть чуть ниже):
селектор с описанием | приоритет |
---|---|
тег имеет наименьший приоритет | [0:0:0:1] |
p { color: orange } | |
добавляем к тегу класс «.intro» | [0:0:1:1] |
p.intro { color: green } | |
добавляем ещё тег | [0:0:1:2] |
article p.intro { color: blue } | |
... нам нужно больше классов | [0:0:2:2] |
article.news p.intro { color: red } | |
идентификатор «id="pinned"» даже сам по себе важней всех тегов и классов вместе взятых | [0:1:0:0] |
#pinned { color: darkblue } | |
добавляем тег <p> , и специфичность увеличивается |
[0:1:0:1] |
p#pinned { color: darkcyan } | |
добавляем ещё один идентификатор «id="top"» | [0:2:0:1] |
#top p#pinned { color: darkgreen } |
Не имеет значение в каком порядке вы будете добавлять данные стили на страницу, тут имеет вес только специфичность CSS-селектора.
Во втором параграфе прописан «style="color:#333"», именно поэтому он не изменяет свой цвет, так как его приоритет наивысший
[1:0:0:0]
Метка
!important
- страшная вещь, использовать следует лишь в крайнем случае, вот посмотрите что она творит - p { color: darkred !important }Говорят, что правило с 255 классами будет выше по приоритету, нежели правило с одним «id», но я надеюсь, такого кода в реальности не существует
Вот кусочек CSS для тренировки, напишите соответствующий ему HTML (это вопрос с собеседования ;):
#my p.announce, .tt.pm li li a:hover + span {
color: #f00;
}
И ещё один:
#my > li, dd.dd.tt ~ span {
text-decoration: underline;
}