Запутывающий приоритет правил CSS - PullRequest
6 голосов
/ 12 ноября 2010

У меня есть (упрощенная) разметка:

<ul id="topnav">
    <li>one</li>
    <li>two</li>
    <li id="last-nav">last</li>
</ul>

и эти правила CSS:

#topnav li {
  list-style-type: none;
  float: left;
}

#last-nav {
    float: right;
}

К моему удивлению, второе правило отменяется первым.Если я переключаю селектор на li#last-nav, он работает.Почему это так?

(Отказ от ответственности: я проверял это только в Firefox)

Ответы [ 8 ]

8 голосов
/ 12 ноября 2010

Каскад работает следующим образом:

  1. Применяется более важное правило.
  2. Если не менее важно, применяется более конкретное правило.
  3. Если оно равно конкретно,применяется последнее правило.

Здесь #topnav li имеет специфичность , равную 101, а #last-nav имеет специфичность 100, поэтому выигрывает первый.Селектор li#last-nav или #topnav #last-nav будет более конкретным.

6 голосов
/ 12 ноября 2010

Правила выбора: расчет специфичности

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

  • Подсчитать количество атрибутов идентификатора в селекторе.
  • Подсчитать количество атрибутов CLASS в селекторе.
  • Подсчитать количество имен тегов HTML в селекторе.

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

#id1         {xxx} /* a=1 b=0 c=0 --> specificity = 100 */
UL UL LI.red {xxx} /* a=0 b=1 c=3 --> specificity = 013 */
LI.red       {xxx} /* a=0 b=1 c=1 --> specificity = 011 */
LI           {xxx} /* a=0 b=0 c=1 --> specificity = 001 */

В вашем примере #topnav li - это 101, а #last-nav - только 100, поэтому 101 выигрывает.

Цитируется по http://htmlhelp.com/reference/css/structure.html

6 голосов
/ 12 ноября 2010

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

http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html
http://meyerweb.com/eric/css/link-specificity.html

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

2 голосов
/ 12 ноября 2010

Вы можете объяснить это со спецификой.

Думайте об этом так:

Elements etc: 0, 0, 0, 1
Classes: 0, 0, 1, 0
IDs: 0, 1, 0, 0
Inline: 1, 0, 0, 0

#topnav li = 0, 1, 0, 1
#last-nav = 0, 1, 0, 0

Итак, #topnav li более конкретен и, таким образом, получает приоритет.

Конечно, каскадирование и наследование, и даже использование! Важное может повлиять на CSS, но в этом случае #topnav li более конкретно

1 голос
/ 12 ноября 2010

Последнее правило имеет более низкую специфичность.Попробуйте изменить на:

li#last-nav {  }

К вашему сведению: вы можете использовать этот инструмент для расчета специфичности: Калькулятор специфичности

0 голосов
/ 12 ноября 2010

Это связано с тем, что ваш первый стиль имеет больше специфики, чем ваш второй. Проверьте этот сайт для более подробной информации. Чтобы ваш второй стиль работал правильно, попробуйте использовать:

#topnav #last-nav
0 голосов
/ 12 ноября 2010

Я не уверен, хотя подозреваю, что первое правило имеет приоритет, потому что оно применяется к определенному элементу (в данном случае, li). Второе правило теоретически может применяться к любому элементу с идентификатором last-nav.

В игру могут войти специфические правила: http://www.w3.org/TR/CSS2/cascade.html#specificity

Современные браузеры, вероятно, позволят вам получить:

#topnav li:last-child {

float: right; }

... и достичь того же результата, что и вы.

НТН,

G

0 голосов
/ 12 ноября 2010

Использование:

#topnav #last-nav {
    float: right;
}

или

#last-nav {
    float: right !important;
}
...