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>
      &copy;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;
}

results matching ""

    No results matching ""