CSS-правила и селекторы
Теперь приступим к CSS, и начнём, пожалуй, с расшифровки аббревиатуры CSS. Это Cascading Style Sheets, дословно «каскадная таблица стилей», но:
— Почему же она называется каскадной? — этот вопрос я часто задаю на собеседованиях претендентам. Ответом же будет аналогия, ибо она незыблема как перпендикулярная лягушка: представьте себе каскад водопада, вот вы стоите на одной из ступенек каскада с чернильницей в руках, и выливаете её содержимое в воду — вся вода ниже по каскаду будет окрашиваться в цвет чернил. Так и в CSS: если вы задаёте стиль на определённом уровне, он распространяется вниз по "каскаду" к элементам веб-страницы, окрашивая их в "цвет" вашего стиля.
— Зачем мне всё это? — работая с jQuery, вы должны «на отлично» читать правила CSS, а также уметь составлять CSS-селекторы для поиска необходимых элементов на странице. Практически все задачи, которые вы будете решать с помощью jQuery, начинаются с поиска необходимого элемента на странице, так что знание CSS-селекторов обязательно.
Но давайте обо всём по порядку, возьмём следующий простенький пример вполне семантического 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>
© jQuery for beginners
</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
#wrap .post
ищем все элементы с классом class="post" внутри элемента с id="wrap"
.cls1.cls2
выбираем элементы с двумя классами class="cls1 cls2"
h1, h2, .posts
перечисление селекторов, выберем всё перечисленное
.post > h2
выбираем элементы <h2>, которые являются непосредственными потомками элемента с классом «post»
a + span
будут выбраны все элементы <span> следующие сразу за элементом <a>
a[href^=https]
будут выбраны все элементы <a> у которых атрибут href начинается с https (предположительно, все внешние ссылки)
Это отнюдь не весь список, описание же всех CSS-селекторов можно найти на соответствующей страничке W3C: https://www.w3.org/TR/selectors-3/
Возвращаясь к нашей аналогии с водопадом, представьте, что на следующей ступеньке кто-то выльет чернила другого цвета, мы же в результате получим смешение цветов. Но это в жизни, а в CSS это изменение "перекрасит воду" на всех последующих ступенях, ведь в CSS важен порядок, порядок и приоритеты. Давайте перейдём к сути:
первая ступенька нашего каскада имеет самый низкий приоритет, это стили браузера по умолчанию
как бы не заявляли разработчики, но в разных браузерах эти стили могут отличаться, поэтому всё ещё существует такое явление как CSS Reset, такой себе уравнитель
на второй ступеньке стили, заданные пользователем в недрах настроек браузера; на практике встречаются редко
самые важные для нас — стили автора странички, но и тут всё идёт по порядку
самый низкий приоритет у стилей, что подключены как файл
<link rel="stylesheet" type="text/css" href="...">или встроены внутрь HTML с помощью тега<style>:и естественно, при равенстве приоритетов «тапки» у того, кто объявлен последним
потом те, что захардкодили плохие люди (не вы, вы так делать не будете) в
style="":и тут появляется метка
!important, и всё нам ломает, т.к. правило с такой меткой становится важнее даже inline-стилей, и всё идёт вверх-дном:чтобы перебить такой стиль, остаётся только вариант прописывать inline-стили с меткой
!important:
приключения с
!importantне закончились, если есть пользовательские стили с данной меткой, то теперь их выходи даже браузеры грешат с
!important, и такие стили имеют практически максимальный приоритет
Если голова ещё не болит, то я также упомяну, что при расчёте, чьи же правила главней, анализируется специфичность селекторов, и тут считается следующим образом:
расчёт происходит по трём весовым позициям —
[0:0:0]за каждый идентификатор элемента (
#id) —[1:0:0]за каждый класс (
.class), либо псевдо-класс (:pseudo) —[0:1:0]за каждый тег (
<a>,<div>, и т.д.) —[0:0:1]при этом
[1:0:0]>[0:x:y]>[0:0:x]при равенстве счета — снова «тапки» у того, кто объявлен последним
Пример селекторов, выстроенных по возрастанию приоритета (соответствующий код HTML будет ниже):
тег имеет наименьший приоритет
[0:0:1]
p { color: orange }
добавляем к тегу класс intro
[0:1:1]
p.intro { color: green }
добавляем ещё тег
[0:1:2]
article p.intro { color: blue }
... нам нужно больше классов
[0:2:2]
article.news p.intro { color: red }
идентификатор id="pinned" даже сам по себе важней всех тегов и классов вместе взятых
[1:0:0]
#pinned { color: darkblue }
добавляем тег <p>, и специфичность увеличивается
[1:0:1]
p#pinned { color: darkcyan }
добавляем ещё один идентификатор id="top"
[2:0:1]
#top p#pinned { color: darkgreen }
используем style и переопределяем любые правила из внешних файлов и стилей
¯\_(ツ)_/¯
<p style="color:#333">...</p>
Есть ещё правила расчёта специфичности которые относятся к использованию определенных псевдоселекторов типа :not() и :where(), сам по себе такой селектор не добавляет веса к специфичности, но правило которое находится в скобках имеет вес:
Да, расчёт специфичности может действительно стать нетривиальной задачей, поэтому вот вам пару калькуляторов на выбор:
Запомните, что первоначально при использовании правил CSS ключевым является уровень специфичности селектора. И только случае, когда специфичности совпадают, будет важен порядок подключения стилей:
Ну и повторюсь, метка !important - страшная вещь, использовать следует лишь в крайнем случае, такое правило имеет наивысший приоритет, хотя и не имеет ничего общего со специфичностью.
Домашнее задание
Вот кусочек CSS для тренировки, напишите соответствующий ему HTML (это вопрос с собеседования ;):
И ещё один:
Last updated