Як підраховуються бали за специфікою CSS


124

Досліджуючи специфіку, я натрапив на цей блог - http://www.htmldog.com/guides/cssadvanced/specificity/

У ньому зазначається, що специфіка є системою бальних оцінок для CSS. Це говорить нам, що елементи вартують 1 бал, класи - 10 балів, а ідентифікатори - 100 балів. Крім того, слід сказати, що ці бали підсумовані, і загальна сума - це специфіка селектора.

Наприклад:

body = 1 бал
body .wrapper = 11 балів
body .wrapper #container = 111 балів

Отже, використовуючи ці пункти, я очікую, що такі CSS та HTML призведуть до того, що текст стане синім:

#a {
    color: red;
}

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o {
  color: blue;
}
<div class="a">
  <div class="b">
    <div class="c">
      <div class="d">
        <div class="e">
          <div class="f">
            <div class="g">
              <div class="h">
                <div class="i">
                  <div class="j">
                    <div class="k">
                      <div class="l">
                        <div class="m">
                          <div class="n">
                            <div class="o" id="a">
                              This should be blue.
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Чому текст червоний, коли 15 класів дорівнювали б 150 балам порівняно з 1 ідентифікатором, що дорівнює 100 балам?

Мабуть, бали не просто нараховуються; вони об'єднані. Детальніше про це читайте тут - http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

Чи означає це, що класи у нашому селекторі = 0,0,15,0АБО 0,1,5,0?

(Мої інстинкти говорять мені , що це перше, як ми знаємо специфічність виглядає селектор як це: 0,1,0,0)


Відповіді:


137

Відповідь Пекка в це практично правильно, і , ймовірно , кращий спосіб думати про проблему.

Однак, як багато хто вже зазначав, у рекомендації W3C CSS зазначено, що "Об'єднання трьох чисел abc (у системі числення з великою базою) надає специфіку". Тож мандрівник у мені просто повинен був зрозуміти, наскільки велика ця база.

Виявляється, що "дуже велика база", яка використовується (принаймні, 4 найпоширенішими браузерами * ) для реалізації цього стандартного алгоритму, становить 256 або 2 8 .

Це означає, що стиль, вказаний з 0 ідентифікаторами та 256 іменами класів, буде перевищувати стиль, вказаний лише з 1 id. Я перевірив це за допомогою декількох загадок:

Отже, фактично існує "точкова система", але це не основа 10. Це база 256. Ось як це працює:

(2 8 ) 2 або 65536, кратна кількість ідентифікаторів у селекторі
+ (2 8 ) 1 або 256, кратна на кількість імен класів у селекторі
+ (2 8 ) 0 або 1, кратна на кількість тегів- імена в селекторі

Це не дуже практично для вправ на конверт для передачі концепції.
Тому, мабуть, тому статті у цій темі використовують базу 10.

***** [Opera використовує 2 16 (див. Коментар Карлкова). Деякі інші селекторні двигуни використовують безмежність - фактично без очок (див. Коментар Саймона Сапіна).]

Оновлення, липень 2014 року:
Як вказував Blazemonger на початку року, веб-браузери (хром, сафарі) тепер, здається, використовують вищу базу, ніж 256. Можливо, 2 16 , як Opera? IE і Firefox все ще використовують 256.


34
Важливо: зауважте, що число 256 відсутнє в специфікації . Таким чином, ця відповідь описує (мабуть корисну) деталь реалізації.
Метт Фенвік

6
Не тільки 256 не є в специфікації, як сказав @MattFenwick, але і вона залежить від впровадження. Мабуть, більше в Opera. У WeasyPrint та cssselect це "нескінченність": я використовую кортеж цілих чисел замість одного цілого числа.
Саймон Сапін

3
Опера @Faust використовує 16 біт замість 8
karlcow

4
Якщо чесно, ця відповідь має більш практичний опис, ніж відповідь Пекки. В основному те, що говорить @Matt Fenwick: те, що ви описуєте, - це практична реалізація специфікації. Недолік у цьому, але не той, про який слід щось робити, будь то автори чи виконавці.
BoltClock

7
256 видається недостатнім у поточних версіях веб-файлів (Chrome та Safari), що ще більше підкреслює точку @ MattFenwick.
Blazemonger

28

Гарне питання.

Я не можу точно сказати - всі статті, які мені вдається знайти, уникають прикладу декількох класів, наприклад тут, - але я припускаю, що якщо мова йде про порівняння специфічності між селектором класу і ідентифікатором , клас отримується значення 15лише, як би воно не було детальним.

Це відповідає моєму досвіду того, як поводиться конкретність.

Однак має бути певна кладка класів, оскільки

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o

є більш конкретним, ніж

.o

Єдине пояснення, яке я маю, полягає в тому, що специфіка складених класів обчислюється тільки один проти одного, але не проти ідентифікаторів.

Оновлення : я на півдорозі отримую це зараз. Це не бальна система, і інформація про класи вагою 15 балів є невірною. Це 4-х частинна система нумерації дуже добре пояснена тут .

Початкова точка - 4 фігури:

style  id   class element
0,     0,   0,    0

Відповідно до пояснення W3C щодо специфічності , значення специфічності для вищезазначених правил:

#a            0,1,0,0    = 100
classes       0,0,15,0   = ... see the comments

це система нумерації з дуже великою (невизначеною?) базою.

Я розумію, що оскільки база дуже велика, жодне число у колонці 4 не може перебити число> 0 у стовпці 3, те саме для стовпця 2, стовпця 1 .... Це правильно?

Мені було б цікаво, чи може хтось із Math краще зрозуміти, ніж я, міг би пояснити систему нумерації та як її перетворити в десяткову, коли окремі елементи перевищують 9.


Це тому, що його між .o & .a .b і т. Д. Таким чином, вони вважали б їх колективно. Але між ID та класом, наприклад: .a та #a, ідентифікатор завжди переважає. Він (я припускаю) рахуватиметься між класами лише тоді, коли немає більш переважного attr. Напр. Клас перейде над елементом, а id - над класом.
Sphvn

@ Ozaki, це я теж припускаю, але це суперечить тому, що говорить ОП про систему балів. У грі повинно бути більше. Я хотів би бачити правила, що стоять за ним.
Печка

Щойно зрозумів, що ми обоє дійшли одного і того ж висновку. Відмінна робота!
Сем

5
Що стосується математики, ми можемо працювати в базі 16 тут (оскільки жодне з окремих чисел не перевищує 15). Так 0,1,0,0 = 0100h = 256 0,0,15,0 = 00f0h = 240 256> 240, тому переможець селектора id.
Меттью Вілсон

1
Так, ви можете вважати, що обчислення специфічності проводиться в системі числення з великою базою. Я думаю, що термін "об'єднання" (також використовується в специфікації) є набагато кращим описом. (Прийшов сюди з відповіді на нове запитання, яке, як виявляється, є справжнім справою, зрозумійте ...)
BoltClock

9

Поточний робочий проект селекторного рівня 4 добре виконує опис специфічності CSS:

Особливості порівнюються, порівнюючи три компоненти за порядком: специфічність з більшим значенням A більш конкретна; якщо два значення А зв'язані, то специфіка з більшим значенням В більш конкретна; якщо два значення B також пов'язані, то специфіка з більшим значенням c більш конкретна; якщо всі значення зв'язані, дві особливості рівні.

Це означає, що значення A, B і C абсолютно незалежні одне від одного.

15 класів не дає вашому селектору оцінку специфічності 150, він присвоює йому B значення 15. Одне значення A достатньо, щоб перебороти це.

В якості метафори уявіть сім’ю з 1 онуком, 1 батьком і 1 дитиною. Це може бути представлено як 1,1,1 . Якщо у батьків є 15 дітей, це не раптом робить їх іншим батьком ( 1,2,0 ). Це означає, що батьки несуть набагато більше відповідальності, ніж вони мали лише 1 дитина ( 1,1,15 ). ;)

Ця ж документація також говорить:

Через обмеження пам’яті в реалізації можуть бути обмежені розміри A , B або c . Якщо це так, значення, що перевищують межу, повинні бути зафіксовані до цієї межі, а не переповнюватись.

Це було додано, щоб вирішити проблему, представлену у відповіді Фауста , згідно з якою реалізація CSS ще у 2012 році дозволила значенням специфіки перепливати одне до одного.

Ще в 2012 році більшість браузерів застосувало обмеження 255, але це обмеження було дозволено переповнювати. 255 класів мали A, B, C специфічність бала 0,255,0 , але 256 класів переповнені і мали А, B, C бал 1,0,0 . Раптом наше значення B стало нашим значенням A. Документація селекторів рівня 4 повністю іррадіює цю проблему, заявляючи, що ліміт ніколи не може бути дозволений переповненню. З цією реалізацією обидва 255 та 256 класи матимуть однаковий бал A, B, c 0,255,0 .

Проблема, вказана у відповіді Фауста, з тих пір виправлена в більшості сучасних браузерів.


8

Зараз я використовую книгу CSS Mastery: Advanced Web Standards Solutions .

Глава 1, сторінка 16 говорить:

Щоб обчислити, наскільки конкретним є правило, кожному вибору селектора присвоюється числове значення. Потім специфіка правила обчислюється шляхом додавання значення кожного з його селекторів. На жаль, специфічність обчислюється не в базі 10, а у високій, невизначеній базовій кількості. Це потрібно для того, щоб високоспецифічний селектор, такий як селектор ідентифікаторів, ніколи не перекривав безліч менш конкретних селекторів, таких як селектори типу.

(наголос мій) і

Специфіка селектора розбивається на чотири складові рівні: a, b, c і d.

  • якщо стиль є вбудованим стилем, то a = 1
  • b = загальна кількість селекторів ідентифікаторів
  • c = кількість селекторів класу, псевдокласу та атрибутів
  • d = кількість селекторів типу та селекторів псевдоелементів

Далі йдеться про те, що ви можете часто робити обчислення в базі-10, але тільки якщо всі стовпці мають значення менше 10.


У ваших прикладах ідентифікатори не варті 100 балів; кожен вартий [0, 1, 0, 0]балів. Таким чином, один id [0, 1, 0, 0]перевищує 15 класів, оскільки він більший, ніж [0, 0, 15, 0]у системі з численними базовими номерами.


4

Я захоплююсь порівнянням рейтингу специфічності з таблицею медалей Олімпійських ігор (перший метод золота - заснований спочатку на кількості золотих медалей, потім срібних, а потім бронзових).

Це також працює з вашим запитанням (величезна кількість селекторів в одній групі специфіки). Специфіка розглянута кожна група окремо. У реальному світі я дуже рідко бачив випадки з більш ніж десятками селекторів).

Існує також досить хороший калькулятор Специфічність доступні тут . Ви можете прикласти свій приклад (#a та .a .b .c .d .e .f .h .h .i .j .k .l .m .n .o) і побачити результати.

Приклад виглядає таблиця медалей Олімпійських ігор в Ріо-2016 введіть тут опис зображення


3

Я не вважаю, що пояснення блогу є правильним. Специфікація тут:

http://www.w3.org/TR/CSS2/cascade.html#specificity

"Очки" від селектора класу не можуть додати більше значення, ніж селектор "id". Це просто не працює так.


Як я сказав у своїй відповіді. ^^ Однак це має значення, якщо у вас є більше одного типу (елемент, клас, ідентифікатор). Але це цілком очевидно, якщо 5-й скажіть червоний, а 3-й синій, а Іма - червоний.
Sphvn

Формулювання навколо специфіки, ймовірно, не сильно змінилося між CSS2 та CSS2.1, але ви дійсно повинні вказувати на специфікацію CSS2.1 у майбутніх дискусіях, оскільки вона повністю випереджає CSS2, який взагалі був зламаний на момент випуску.
Робін Віттлтон

1

Я б сказав, що:

Element < Class < ID

Я думаю, що вони укладаються лише в залежність від того, що ви отримуєте, якщо він кратний одному. Таким чином, Клас завжди буде переважати над елементом та ідентифікатором завжди над Класом, але якщо він знизиться до того, який із 4 елементів, де 3 - синій, а 1 - червоний, - це буде синій.

Наприклад:

.a .b .c .d .e .f .g .h .i .j .k .l
{
color: red;
}

 .m .n .o
{
color blue;
}

Повинен вийти червоним.

Див. Приклад http://jsfiddle.net/RWFWq/

"якщо 5things кажуть червоний та 3 кажуть синій добре Ima go red"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.