Содержание

Сколько весят селекторы? • Про CSS

Все CSS-селекторы имеют свой вес, который определяет как взаимодействуют одинаковые свойства, заданные в разных местах кода одному и тому же элементу.

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

Вот пример проблемы. Есть див с id="container", внутри него некоторый текст и список ссылок.

<div>
  <p><a href="#">link in P</a></p>
  <ul>
    <li><a href="#">Link1</a></li>
    <li><a href="#">Link2</a></li>
  </ul>
</div>

Сначала задаём всем ссылкам внутри #container оранжевый фон:

#container A {
  background: orange;
}

А потом, чтобы в списке .list внутри контейнера ссылки имели зелёный фон, ниже дописываем такое:

.list A {
  background: mediumspringgreen;
}

Казалось бы, ссылки в тексте должны получить оранжевый фон, а ссылки в списке — зеленый, но нет:

Почему так? Потому, что первый селектор содержит ID и перевешивает второй, то есть:

#container A > . list A

Вес селектора

Специфичность селектора рассчитывается по 4-м позициям:

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

Пример:

Вес селекторов (по убыванию):

style=""1,0,0,0

#id0,1,0,0

.class0,0,1,0

[attr=value]0,0,1,0

LI0,0,0,1

*0,0,0,0

У стилей, заданных в атрибуте style, на первой позиции будет единица — 1,0,0,0. Это самая высокая специфичность, которая перевешивает свойства, заданные другими способами.

Переопределить стили, заданные в style, можно дописав !important к значению свойства в таблице стилей.

Обратный вариант — универсальный селектор *, он не имеет веса: 0,0,0,0.

Примеры:

LI0,0,0,1 — селектор по тегу

UL LI0,0,0,2 — селектор c двумя тегами весит больше, чем с одним.

.orange0,0,1,0 — селектор с классом весит больше, чем селектор с тегом.

.orange A SPAN0,0,1,2 — селектор перевесит предыдущий, потому что помимо класса содержит два тега.

#page .orange0,1,1,0 — селектор с ID перевесит всё, кроме inline-стилей.

Теперь сравним селекторы из исходного примера:

#container A0,1,0,1

.list A0,0,1,1

0,1,0,1 > 0,0,1,1 — хорошо видно, что селектор с ID весит больше, чем селектор с классом, поэтому все ссылки имеют оранжевый фон, хотя ниже в коде им задан зеленый.

Варианты решений

1. Добавить !important

#container A {
  background: orange;
}
.list A {
  background: mediumspringgreen !important;
}

Ссылки получат зеленый фон, быстро и легко. Но это плохой способ, потому что код запутывается ещё больше. Со временем для переопределения !important в одном месте может потребоваться добавить его в других местах. Иерархичность начнет работать не сверху низ и от общего к частному, а как попало. В конце-концов поддерживать такой код будет весьма проблематично.

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

2. Следующий очевидный способ — добавить #container ко второму селектору, чтобы увеличить его вес:

#container A {
  background: orange;
}
#container .list A {
  background: mediumspringgreen;
}

Это тоже сработает, но решение так себе: удлиняется цепочка селекторов (что может отразиться на скорости отрисовки страницы) и ухудшается читаемость кода.

Так тоже делать не стоит.

1-й и 2-й способ могут использоваться, если у вас нет доступа к разметке, а в ней нет нужных классов. Если же вы можете редактировать разметку либо классы у элементов таки есть — используйте последний способ, самый правильный:

3. Просто не используйте в стилях селекторы с ID, используйте классы.

Посмотрим на разницу между #container и с .container:

#container A0,1,0,1 — селектор с ID перевешивает всё вне зависимости от своего расположения в коде.

Заменим в разметке страницы id на class:

.container A0,0,1,1 — селектор с классом весит меньше, он менее специфичен.

Селектор ссылок в списке весит столько же:

.list A0,0,1,1

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

В итоге разметка может быть такой:

<div>
  <p><a href="#">link in P</a></p>
  <ul>
    <li><a href="#">Link1</a></li>
    <li><a href="#">Link2</a></li>
  </ul>
</div>

А стили — такими:

.container A {
  background: orange;
}
.list A {
  background: mediumspringgreen;
}

И код работает так, как ожидается:

Если id в вашей разметке уже используется в Js, логичнее будет добавить элементу класс и перевесить стили на него. Если же id участвует только в разметке — лучше заменить его на class.

В качестве общих рекомендаций так же следует упомянуть, что нужно как можно меньше использовать селекторы по тегу и как можно больше — селекторы по классу. Это поможет избежать проблем при повторном использовании блоков сайта, а при использовании «умных» классов — может значительно сократить цепочки селекторов, увеличить читабельность кода и скорость отрисовки страницы.

Спецификации:

  • w3.org/TR/CSS2/cascade.html#specificity
  • w3.org/TR/css3-selectors/#specificity

Понимание веса CSS-селекторов

Введение

Как и любая моя статья, эта начинается с введения. Дабы не говорить на разных языках, начнём с самых основ в мире CSS, то есть с терминологии. Чувствую себя преподавателем в университете — как же это круто.

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

Селектор — это строка, представляющая собой формальное описание структуры, на основе которого выбирается элемент или группа элементов в дереве документа и применяется объявленный блок свойств.

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

Я не буду вдаваться в подробности того, что селекторы должны начинаться с буквы и некоторых других символов. Я также не буду говорить про неинтересные прописные истины, которые можно найти в любой статье на тему основ CSS. Речь в этой статье пойдёт про вес CSS-селекторов, а если говорить простым языком — о его числовом представлении и понимании.

Вес селекторов

Нет, здесь не идёт речь об их реальном весе (его нет), а также о количестве символов. Такой вес нельзя измерить весами, так как он не вещественен в обычном понимании и вообще не существует в нашем с вами мире людей. Зато он есть в виде нулей и единиц. Получается, что селектор можно взвесить, используя некую систему, о которой мы и будем говорить дальше.

Что такое вес селектора?

Вес селектора — это условные четыре позиции x, x, x, x, которые заполняются нулями и единицами в соответствии с содержимым селектора. Каждая из позиций имеет своё содержимое:

  • Инлайн стили
  • Идентификаторы
  • Классы, атрибуты и псевдоклассы
  • Теги и псевдоэлементы

Как это читать?

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

Как заполнять?

Немного сложнее, чем читать. Рассмотрим предложенную систему четырёх позиций на реальном примере для того, чтобы понять всю технологию.

h2 {
  color: #777;
}

В этом примере селектором выступает заголовок h2, который состоит из одного тега. Получается, что напротив столбца «тег» мы ставим единичку. Получается следующая картина: 0, 0, 0, 1.

Всё это замечательно, но в реальных проектах встречается разве что в ядре стилей или normalize, а это значит, что нужно усложнить задачу.

#main .container article.post > header h2.giga {
  color: #777;
}

Пример получился хардкорнее, чем предыдущий и в реальной жизни достоин премии «самого избыточного селектора». Такая избыточность должна преследоваться по закону, но подробнее на эту тему мы поговорим в отдельной части статьи.

Окей, вернёмся к примеру и немного поработаем весами.

Давайте начнём слева, так как в начале стоит единственный идентификатор #main. Далее мы видим три класса .container, .post и .giga, а также три тега article, header и h2. Для ещё большей наглядности я распишу это в виде этапов:

// Селектор
#main .container article.post > header h2.giga
// Начальный вес
0, 0, 0, 0
// Идентификаторы
#main         0, 1, 0, 0
// Классы, атрибуты и псевдоклассы
.container    0, 1, 1, 0
.post         0, 1, 2, 0
.giga         0, 1, 3, 0
// Теги и псевдоэлементы
article       0, 1, 3, 1
header        0, 1, 3, 2
h2            0, 1, 3, 3
// Итог
#main .container article.post > header h2.giga
=>
0, 1, 3, 3

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

// Селектор
body.page-posts #main .container article.post ul.list-unstyled > li:first-child h3. article-title:hover {
  color: #333;
}
// Начальный вес
0, 0, 0, 0
// Идентификаторы
#main             0, 1, 0, 0
// Классы, атрибуты и псевдоклассы
.page-posts       0, 1, 1, 0
.container        0, 1, 2, 0
.post             0, 1, 3, 0
.list-unstyled    0, 1, 4, 0
:first-child      0, 1, 5, 0
.article-title    0, 1, 6, 0
:hover            0, 1, 7, 0
//  Теги и псевдоэлементы
body              0, 1, 7, 1
article           0, 1, 7, 2
ul                0, 1, 7, 3
li                0, 1, 7, 4
h3                0, 1, 7, 5
// Итог
body.page-posts #main .container article.post ul.list-unstyled > li:first-child h3.article-title:hover
=>
0, 1, 7, 5

Ну и напоследок, для полного понимания темы, будет пример с атрибутами и псевдоэлементами.

// Селектор
.main[data-columns]:before {
  content: "3 .column.size-1of3";
}
// Начальный вес
0, 0, 0, 0
// Идентификаторы
0, 0, 0, 0
// Классы, атрибуты и псевдоклассы
.main             0, 0, 1, 0
[data-columns]    0, 0, 2, 0
//  Теги и псевдоэлементы
:before           0, 0, 2, 1
// Итог
.
main[data-columns]:before => 0, 0, 2, 1

Вот такие вот дела.

На самом деле, тема очень простая, но очень важная на практике для посредственного (минимального) понимания того, как браузер определяет какой блок объявлений необходимо применить к тому или иному элементу на странице.

А что, если вес селекторов одинаковый?

Допустим, что у вас есть два или несколько селекторов так или иначе указывающих на один и тот же элемент. И вот так сложилось, что вы посчитали или просто взглянули на них, и вес оказался одинаковым. Не стоит отчаиваться, просто блок объявлений последнего селектора в вашем CSS-коде из этой группы и будет применяться к элементу. Как-то так. Мне кажется это логичным. Прямо как в поговорке «кто не успел, тот опоздал», но наоборот: «кто опоздал, тот и успел».

Зачем это нужно?

Это очень интересный момент, ибо понять какой блок объявлений будет применяться к элементу, можно и без расчёта веса селектора, то есть просто посмотрев на него и слегка подумав. Однако, глазомер может подвести, а вот машина не подведёт, посчитает вес и испортит вёрстку. Ошибка, конечно, не машины, а прослойки между компьютером и стулом, но это уже совсем другая история.

Ещё одним применением такого вот расчёта являются сервисы или скрипты, которые строят диаграммы специфичности CSS. Это может быть очень удобно для анализа и оценки избыточности вашего кода.

Интересным фактом будет то, что единственный раз, когда мне приходилось считать вес селектора, был тестом от Mail.ru на какой-то сертификат. Если интересно, то я поищу этот тест у себя в истории.

Я ленивый и не хочу понимать, как считать вес селекторов, что тогда?

Ох, специально для вас у меня есть сервис, на который я наткнулся при подготовке к изложению этого материала: Specificity Calculator — это простой и эффективный калькулятор веса селекторов.

Специфичность селекторов

Раз уж зашла речь про вес CSS-селекторов, то неизбежно задумываешься о том, как бы его оценить: когда нужно ему худеть, а когда наоборот — поправляться. Как и у человека, у селекторов всё таки есть оптимальный вес.

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

Хорошо, всё это замечательно, но причём тут вес? — да очень просто, он напрямую от этого зависит. Чем больше вложений, тем больше вес. Логично, однако.

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

Выводы

Постарайтесь поддерживать оптимальный вес селекторов и изредка проводите рефакторинг кода. $ не работает ?» и чем ближе утро, тем сильнее начинает волновать именно этот самый последний вопрос.

Чуть ниже я расскажу о том какого чёрта сss селекторы иногда не ведут себя так, как нам кажется правильным, и о том как они на самом деле должны себя вести.

Глава один – идём направо!

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

Итак, взвешиваем — сначала представим пару рядов из 8 чисел:

0,1,0,0,0,0,0,0
1,0,0,0,0,0,0,0

Знакомьтесь — так в числах выглядят некоторые два селектора, чтобы никто ни о чем не догадался назову их условно «верхний» и «нижний»

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

  1. Смотрим на крайние левые числа
  2. Выбираем из них большее. — именно этот селектор и будет самым тяжелым
  3. Если числа одинаковые, сдвигаемся на число вправо и повторяем инструкции из пункта 2.
  4. Если все числа одинаковые то применяются стили из селектора который был объявлен последним
Самая страшная тайна

Если вы это прочитаете, от вас навсегда уйдет душевный покой, но по крайней мере вы сможете спать по ночам.

Раскрывая самую страшную тайну я расскажу, как собственно превратить обычный селектор в такие понятные и красивые цифры? Всё как всегда очень просто:

  1. Теги. за каждый тег в селекторе можно накинуть в самое правое число единичку:
    a – это 0,0,0,0,0,0,0,1
    div a – это  0,0,0,0,0,0,0,2
    

  2. Классы, за каждый класс или псевдокласс в селекторе можно накинуть по единичке во второе число справа
    .head .logo – это  0,0,0,0,0,0,2,0
    .logo.big  –    0,0,0,0,0,0,2,0
    div:first-child – 0,0,0,0,0,0,1,1
    .logog > . big – и это тоже 0,0,0,0,0,0,2,0
    

    Да, вы все верно поняли. Css селектор плевать хотел на все эти ваши изыски типа пробелов или «>».
  3. За каждый ID в селекторе добавляем по единичке в третье справа число.
    #head – это  0,0,0,0,0,1,0,0
    #head  #logo –  тоже  0,0,0,0,0,2,0,0
    

Я думаю суть вы уловили, теперь можно приступать к небольшой викторине, чтобы это проверить:

Викторина
<head>
    <title></title>
    <style>
        span p
        {
            background-color: gray;
        }
        html p
        {
            background-color: red;
        }
    </style>
</head>
<body>
    <div>
        <span><p>?</p></span>
    </div>
</body>

Вопрос: Какого цвета бэкграунд будет в абзаце?
Ответ: Правильно, красного, потому что селектор не волнует что вам там кажется, и расстояние между тэгами его не интересует. А так как вес тэгов равен – применится последний.

<head>
    <title></title>
    <style>
        div.test1
        {
            background-color: gray;
        }
        div > .test1
        {
            background-color: yellow;
        }
        
        div .test1
        {
            background-color: red
        }
    </style>
</head>
<body>
<div>
    <div>?</div>
</div>
</body>

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

<head>
    <title></title>
    <style>
        #id1 div
        {
            background-color: gray;
        }
        #id2
        {
            background-color: red
        }
    </style>
</head>
<body>
<div>
    <div>?</div>
</div>
</body>

Вопрос: Все тот же.
Ответ: А ответ, для разнообразия другой: наш див будет серым. Потому что как я уже упоминал выше селектору абсолютно безразлично что вы там имели ввиду. У первого селектора вес больше, и никого не волнует что скорее всего ожидали вы не такого поведения.

Продолжаем раскрывать секреты

У нас осталось еще так много чисел, и наверняка так хочется узнать что же все они значат – продолжаем раскрывать секреты.

  1. Селектор * абсолютно невесомый, то есть совсем.
  2. Селектор атрибутов это самый обычный псевдокласс и весит он столько же сколько и обычные классы
  3. Любой инлайновый стиль написанный в атрибуте style=”” элемента автоматически получает приоритет0,0,0,0,1,0,0,0, что сразу делает его очень крутым.
  4. А следующие четыре цифры это все наши старые знакомые только с атрибутом !important
    div
    {
        background-color: gray !important;
    }
    Имеет вес при определении свойства background-color -  0,0,0,1,0,0,0,0
    . ="#"] 
        {
            color: red;
        }
        </style>
    </head>
    <body>
    <a href="#">?</a>
    </div>
    </body>
    

    Вопрос: Какого цвета будет знак вопроса в ссылке?
    Ответ: Красного, неважно что селектор на точное совпадение атрибута выглядит более специфичным, чем селектор который выбирает все что «начинается с». Вес они имеют одинаковый.

    <head>
        <title></title>
        <style>
            #id1
            {
                background-color: gray !important;
            }
        </style>
    </head>
    <body>
    <div>?</div>
    </body>
    

    Вопрос: Мой оригинальный запатентованный вопрос.
    Ответ: !important круче всего, даже круче чем инлайн стили – так что бам-бам-бам – серого!

    Исходники всех тестов лежат тут

    P.S. немного порно

    <head>
        <title></title>
        <style>
            #id1
            {
                background-color: gray !important;
            }
        </style>
    </head>
    <body>
    <div>red</div>
    </body>
    

    Специфика CSS

    ❮ Предыдущая Далее ❯


    Что такое специфичность?

    Если есть два или более правила CSS, которые указывают на один и тот же элемент, селектор с наибольшим значением специфичности «выиграет», а его объявление стиля будет применено к этому элементу HTML.

    Думайте о специфичности как о балле/ранге, который определяет, какое объявление стиля в конечном итоге применяется к элементу.

    Посмотрите на следующие примеры:

    Пример 1

    В этом примере мы использовали элемент «p» в качестве селектора и указали красный цвет для этого элемента. Текст будет красным:



     

    Hello World!


    Попробуйте сами »

    Теперь посмотрите на пример 2 :

    Пример 2

    В этом примере мы добавили селектор класса (названный «тест») и указан зеленый цвет для этого класса. Текст теперь будет зеленым (несмотря на то, что мы указали красный цвет для селектора элемента «p»). Это потому, что селектор класса дан более высокий приоритет:



     

    Hello World!


    Попробуйте сами »

    Теперь посмотрите на пример 3:

    Пример 3

    В этом примере мы добавили селектор id (названный «демо»). Теперь текст будет синий, потому что селектор id имеет более высокий приоритет:



     

    Здравствуйте! Мир!


    Попробуйте сами »

    Теперь посмотрите на пример 4:

    Пример 4

    В этом примере мы добавили встроенный стиль для элемент «п». текст теперь будет розовым, потому что встроенный стиль имеет наивысший приоритет:



     

    Привет, мир!


    Попробуйте сами »


    Иерархия специфичности

    Каждый селектор CSS занимает свое место в иерархии специфичности.

    Существует четыре категории, определяющие уровень специфичности селектора:

    • Встроенные стили — Пример:

    • ID — Пример: #навбар
    • Классы, псевдоклассы, селекторы атрибутов — Пример: .test, :hover, [ссылка]
    • Элементы и псевдоэлементы — Пример: h2, :before

    Как рассчитать специфичность?

    Запомните, как рассчитывать специфичность!

    Начните с 0, добавьте 100 для каждого значения идентификатора, добавьте 10 для каждого значение класса (или селектор псевдокласса или атрибута), добавьте 1 для каждого селектора элемента или псевдоэлемента.

    Примечание. Встроенный стиль получает значение специфичности 1000 и всегда дается наивысший приоритет!

    Примечание 2: Есть один исключение из этого правила: если вы используете !important правило, он даже переопределяет встроенные стили!

    В таблице ниже приведены некоторые примеры расчета значений специфичности:

    Селектор Значение специфичности Расчет
    стр. 1 1
    п.тест 11 1 + 10
    р#демо 101 1 + 100

    1000 1000
    #демо 100 100
    .тест 10 10
    п.тест1.тест2 21 1 + 10 + 10
    #navbar p#demo 201 100 + 1 + 100
    * 0 0 (универсальный селектор игнорируется)

    Селектор с наивысшим значением специфичности выиграет и вступит в силу!

    Рассмотрим эти три фрагмента кода:

    Пример

    A: h2
    B: h2#content
    C:

    Заголовок

    Специфичность A равна 1 (селектор одного элемента)
    Специфичность B равна 101 (одна ссылка на идентификатор + один селектор элемента)
    Специфичность C равна 1000 (встроенный стиль)

    Поскольку третье правило (C) имеет наивысшее значение специфичности (1000), этот стиль декларация будет применяться.



    Дополнительные примеры правил специфичности

    Равная специфичность: последнее правило побеждает — Если одно и то же правило дважды записано во внешнюю таблицу стилей, то последнее правило выигрывает:

    Пример

    h2 {background-color: yellow;}
    h2 {background-color: red;}

    Попробуйте сами »


    Селекторы ID имеют более высокую специфичность, чем селекторы атрибутов — Посмотрите на следующие три строки кода:

    Пример

    div#a {цвет фона: зеленый;}
    #a {цвет фона: желтый;}
    div[id=a] {цвет фона: синий; }

    Попробуйте сами »

    первое правило является более точным, чем два других, поэтому оно будет применяться.


    Контекстные селекторы более специфичны, чем одиночный элемент selector — Встроенная таблица стилей находится ближе к элементу, которому нужно придать стиль. Итак, в следующая ситуация

    Пример

    Из внешнего файла CSS:
    #content h2 {background-color: red;}

    В файле HTML:

    будет применяться последнее правило.


    Селектор класса превосходит любое количество селекторов элементов — селектор класса, такой как .intro, превосходит h2, p, div и т. д.:

    Пример

    .intro {фоновый цвет: желтый;} цвет: red;}

    Попробуйте сами »


    Универсальный селектор (*) и унаследованные значения имеют специфичность 0 — Универсальный селектор (*) и унаследованные значения игнорируются!

    ❮ Предыдущий Следующая ❯


    Как рассчитать специфичность селектора CSS | Яхья Джамалдин

    Изображение @heylagostechie на Unsplash.

    Много раз, когда я разговаривал с младшими фронт-разработчиками или людьми, которые только что изучили HTML и CSS из любопытства, они шокировали меня, говоря, что CSS — это простой язык, да, синтаксис CSS кажется простым на первый взгляд или на первый взгляд. месяцев обучения веб-разработке.

    Этот простой синтаксис в CSS может быть самой обманчивой вещью, которую вы когда-либо встречали в самом языке, потому что он содержит сложность алгоритма, который выбирает между многими объявлениями CSS, чтобы определить точное значение для данного свойства CSS, мы говорим про каскадный алгоритм здесь.

    Кроме того, у нас есть головная боль Box Alignment Module, Specificity, , и я могу утверждать, что освоение этих концепций — лишь одна из вещей, которая отличает младшего разработчика CSS от старшего, или, почему бы и нет, мастера CSS? Привет !! Я сказал: только одна из вещей.

    Фотография с сайта developer.mozilla.org (Выравнивание элементов с помощью flexbox).

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

    Фото с сайта toptal.com (f организация файлов в CSS)

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

    Сейчас дела обстоят некрасиво, «глобальный характер CSS», «Специфика». Что, черт возьми, означают эти вещи? Что ж, давайте проясним смысл глобального характера, а затем сосредоточимся на Специфике.

    Вы помните, когда впервые попытались изучить CSS, я думаю, вы создали пару абзацев, используя тег

    , а затем применили определенный цвет к их тексту и фону, используя объявление стиля с параметром р селектор.

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

    Когда появляется «глобальный характер», CSS имеет глобальную область действия, поэтому, когда вы применяете объявление стиля с помощью p селектор элементов, этот стиль будет применяться к каждому элементу

    в вашем HTML-документе, даже если это не было запланированным желанием.

    Фото автора.

    Все становится запутанным, когда вы пытаетесь решить эти глобальные проблемы природы, используя комбинированные или одиночные селекторы, например, div#para p и div. para p , скажем, вы написали два разных объявления стилей с этими двумя селекторами. .

    Div#para p применит красный фон к абзацу, а div.para p применит черный, этот цвет будет применен к фону элемента

    под < div> элемент?

    Фото автора.

    Вы думали, что четвертый абзац будет иметь черный фон? Не красный. Почему это случилось? Вы можете подумать, что это как-то связано с последним объявленным стилем? Нет, последнее объявление стиля использовалось с div.para p селектор, но на четвертый абзац это не повлияло.

    Это вопрос специфичности, и, как я упоминал ранее, он действует как оценка, каждый селектор в CSS имеет оценку специфичности, на основе этой оценки объявление стиля будет применено к нужному элементу, в последнем примере у нас был красный фон, потому что селектор ID имеет высокий балл по своей специфичности.

    Браузер прикрепляет объявленные стили на основе специфичности селекторов, но как определить, какой селектор имеет высокий или низкий показатель специфичности? Что ж, у нас есть несколько правил, которые помогут нам вычислить оценку (значение) специфичности в каждом селекторе.

    Вычисление специфичности селекторов объясняется следующим образом в World Wide Web Consortium (W3C) :

    • подсчет количества селекторов ID в селекторе (= a)
    • подсчет количества селекторов класса, селекторы атрибутов и псевдоклассы в селекторе (= b)
    • подсчитывают количество селекторов типов и псевдоэлементов в селекторе (= c)
    • игнорируют универсальный селектор (*)

    Это кажется немного запутанным но внимательно посмотрите, в одном селекторе значения (a, b, c) объединяются для получения одного значения, давайте будем следовать этим правилам, чтобы определить специфику селекторов, которые мы использовали ранее.

    Div. para p содержит селектор двух типов div и p, с помощью селектора одного класса определяем значения для (a, b, c).

    У нас нет селектора ID в этом комбинированном селекторе выше, это означает a=0, один селектор класса, поэтому b=1 плюс два селектора типа, следовательно, c=2, комбинированный (a= 0, b=1, c=2), что равно (0,1,2) специфичности.

    Для селектора div#para p у нас есть один селектор ID (a=1), два селектора типа (c=2), поэтому значение специфичности равно (1,0,2), в данном случае , у нас есть 0 в значении, потому что у нас нет селекторов, которые относятся к типу b.

    Теперь давайте сравним эти значения специфичности, для этих двух селекторов div#para p (1,0,2) больше, чем (0,1,2) для селектора div.para p , и вернемся к предыдущему примеру: красный фон был применен, потому что селектор div#para p имел высокое значение специфичности.

    Что, если бы у нас было несколько комбинированных селекторов с одинаковым значением специфичности? Например: input[type=text] и ввод.текст.

    В этом случае у нас есть один селектор типа с селектором атрибута или селектором класса, input[type=text] = (0,1,1), input.text = (0,1,1), в такой ситуации будет применен последний селектор, который вы использовали в файле CSS, или тег стиля в документе HTML.

    Фото автора.

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

    Если вы хотите поиграть с приведенным выше примером, вы можете добавить псевдокласс, например: наведите указатель мыши на селектор input[type=text] , после перезагрузки документа каждый раз, когда вы наводите курсор на фон ввода, цвет фона будет меняться к аквамарину, цвету, который сочетает в себе зеленый и синий цвета. input[type=text]:hover

    Добавление псевдокласса hover к селектору input[type=text] изменит его специфичность с (0,1,1) на (0,2,1) и это потому, что псевдоклассы принадлежат селекторам типа b, однако input[type=text]:hover специфичность не изменится, пока вы не наведете курсор на элемент ввода.

    Фото автора.

    Последнее обновление кода Visual Studio поможет вам в расчете специфичности, выберите любой селектор в CSS, и редактор откроет небольшое окно, содержащее значение специфичности, как показано ниже.

    Фото автора.

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

    Создание слишком большого количества комбинированных селекторов и вычисление их значения специфичности, а также проверка того, было ли применено объявление стиля, прикрепленное к селектору с наивысшим значением специфичности, очень помогло мне, так почему бы и нет? Попытайся.

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

    Калькулятор специфичности :specificity.keegan.st

    Имена селекторов с примерами : developer.mozilla.org

    Глубокое погружение в специфику CSS

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

    В этой статье мы рассмотрим следующее:

    • Что такое специфика CSS?
    • Как работает иерархия специфичности CSS?
    • Как рассчитывается специфичность CSS?
    • Превышают ли несколько классов селектор ID?
    • Что такое !important исключение из правила ?
    • Что такое неведение близости?

    Начинаем!

    Что такое специфика CSS?

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

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

    Как работает иерархия специфичности?

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

    Показатель специфичности селектора определяется иерархией специфичности, состоящей из четырех частей:

    1. Селекторы встроенного стиля — это правила стиля, определенные в HTML-документе с использованием атрибута стиля . Этим селекторам присваивается показатель специфичности 1000, и поэтому они имеют приоритет над другими типами селекторов
    2. . Селекторы ID
    3. , такие как #modal , имеют показатель специфичности 100
    4. Селекторы классов, псевдоклассов и атрибутов имеют показатель специфичности 10. .modal , :active и [href] являются примерами селекторов классов и псевдоклассов и атрибутов соответственно
    5. Селекторы элементов и псевдоэлементов имеют показатель специфичности, равный единице. div и :after являются примерами селекторов элементов и псевдоэлементов соответственно

    N.B. , также есть универсальный селектор (обозначается символом * ), который используется для применения стиля CSS ко всем элементам HTML на странице. Универсальный селектор имеет нулевую специфичность; поэтому его правила стиля будут переопределены всякий раз, когда есть конфликтующие селекторы

    Вот визуальное представление иерархии специфичности CSS:

    Теперь давайте рассмотрим еще одно визуальное представление, которое поможет нам полностью понять концепцию специфичности.

    В этом примере мы более подробно рассмотрим следующие селекторы:

    • Встроенный
    • Селектор идентификатора ( # платеж )
    • Селектор класса ( .modal )
    • Селектор элемента ( раздел )

    Встроенный тип

    Когда встроенные правила стиля применяются к элементу, этот элемент будет иметь показатель специфичности встроенного стиля, равный единице, и нулевой показатель для других селекторов, в результате чего общий показатель специфичности CSS будет равен 1000. Это означает, что правила встроенного стиля будут имеют приоритет над любыми правилами стиля, связанными с идентификатором, классом или селектором элемента. Свойство !important может переопределить правило встроенного стиля, но мы рассмотрим это позже в этой статье.

    Селектор ID (

    #платеж )

    Элемент с селектором идентификатора будет иметь показатель специфичности идентификатора, равный единице, в то время как другие селекторы будут иметь нулевой показатель, в результате чего общий показатель специфичности CSS будет равен 100.

    Селектор класса (

    .modal )

    Элемент с селектором класса будет иметь показатель специфичности класса, равный единице, в то время как другие селекторы будут иметь нулевой показатель, в результате чего общий показатель специфичности CSS будет равен 10.

    Селектор элементов (

    раздел )

    Элемент div будет иметь показатель специфичности селектора элемента, равный единице, в то время как другие селекторы будут иметь нулевой показатель, в результате чего общий показатель специфичности CSS будет равен единице.

    Как рассчитывается специфичность?

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


    Более 200 000 разработчиков используют LogRocket для улучшения цифрового взаимодействия

    Подробнее →


    Столбец «Расчет» в приведенной ниже таблице показывает суммирование особенностей отдельных селекторов. Столбец «Значение специфичности» показывает общую рассчитанную специфичность для нескольких селекторов.

    Селектор Расчет Значение специфичности
    раздел 1 1
    .модал 10 10
    #платеж 100 100

    Зарегистрироваться

    <дел>

    Пожалуйста, создайте учетную запись, чтобы получить доступ ко всем последним функциям

    Давайте стилизуем элемент p , используя два разных селектора, чтобы продемонстрировать, как именно работает специфичность.

    Вот первый селектор:

     .modal .desc p{
      цвет синий;
    }
     

    Вот второй селектор:

     #деск-текст{
      цвет:желтый;
    }
     

    Как вы думаете, какой из этих двух селекторов будет применен к элементу p ? Если вы выбрали второй селектор, вы правы! Вот почему:

    Как показано ниже, второй селектор, #desc-text , имеет более высокий показатель специфичности по сравнению с первым селектором, modal .desc p . Поэтому правила стиля второго селектора будут применены к элементу p . В этом примере элемент p будет желтым .

    Селектор Расчет Значение специфичности
    .modal .desc p 10 + 10 + 1 21
    #описание-текст 100 100

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

    Распространенное заблуждение относительно CSS состоит в том, что селекторы применяются в соответствии с каскадом. Это не совсем правильно. Чтобы проиллюстрировать этот момент, вот живой пример с теми же двумя селекторами, за исключением того, что на этот раз селектор #desc-text помещается перед модальным селектором .desc p в каскаде.

    Как видите, несмотря на изменение порядка появления, стиль селектора #desc-text по-прежнему применяется к элементу p , так как этот селектор имеет самый высокий показатель специфичности:

    См. пример специфичности CSS Pen
    от King nelson (@D_kingnelson)
    на CodePen.

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

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

    См. пример 2 специфичности CSS Pen
    от King nelson (@D_kingnelson)
    на CodePen.

    Превышают ли несколько классов селектор ID?

    Наши расчеты до этого момента показывают простыми словами, как селектору присваивается оценка специфичности и как эта оценка используется для взвешивания селектора.

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

    Что такое

    !important исключение из правила ?

    Когда правило !important используется в объявлении стиля, оно имеет приоритет над любыми другими объявлениями, и его стиль применяется к элементу. Однако, опираясь на !важное правило для каждого случая является плохой практикой, и его следует избегать. Правило !important усложняет отладку, потому что нарушает обычное каскадирование в таблицах стилей.

    Когда два объявления с правилом !important противоречат одному и тому же элементу, применяется объявление с большей специфичностью.

    Вот пример:

     <дел>
      

    Пустой элемент div

     .пусто{
      background-color: #010101 !важно;
    }
    дел {
      background-color: #d40000 !важно;
    }
     

    В этом примере к селектору класса будет применено правило стиля к элементу, поскольку он имеет более высокую оценку специфичности, чем селектор элемента.

    Если два объявления с правилом !important имеют одинаковую специфичность, то победит объявление, следующее в каскаде. Каскад вступает в игру, когда специфичность уже не имеет достаточной решающей силы.

    Что такое неведение близости?

    Игнорирование близости просто означает, что не имеет значения, насколько глубоко вложен селектор по сравнению с элементом, на который указывает ссылка, поскольку это не влияет на специфичность.

    Вот пример:

    <раздел>
      <дел>
        

    Спасибо, что дочитали до этого момента, вы потрясающие!

     дел p {
      размер шрифта: 20 пикселей;
    }
    раздел р {
      размер шрифта: 30px;
    }
     

    В этом примере не имеет значения, что элемент p находится в непосредственной близости от элемента div . Это не влияет на его специфику. Оба селектора имеют одинаковую оценку специфичности; поэтому вступает в силу каскадное правило CSS и применяется последний селектор.

    Унаследованные стили против непосредственно целевых элементов

    CSS-элементы могут иметь правила стиля, непосредственно предназначенные для них, или они могут наследовать правила стиля от родительских элементов. Стили для непосредственно целевого элемента всегда будут иметь приоритет над унаследованными стилями, независимо от специфики унаследованного правила.

    В приведенном ниже примере селектор #parent имеет показатель специфичности 100. Однако его правило стиля не будет применяться к элементу p , поскольку это унаследованный стиль.

     <дел>
        

    Поздравляем, вы зашли так далеко!

     #родитель {
      цвет синий;
    }
    п {
      цвет: желтый;
    }
     

    Заключение

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

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

    Ваш интерфейс загружает ЦП ваших пользователей?

    Поскольку веб-интерфейсы становятся все более сложными, ресурсоемкие функции требуют от браузера все большего и большего.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *