Перейти к содержимому
Tags

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

13/10/2009

Сегодня довелось познакомиться поближе с понятием CSS specificity. Началось всё со странного (с моей точки зрения) поведения браузеров. Код был примерно таким:


	<head>
	<style>

		table {
			width: 80%;
		}

		table.rating td {
			text-align: left;
			border: 1px solid gray;
			border-collapse: collapse;
		}

		td.number {
			text-align: center;
		}
	</style>
	</head>
	<body>

		<table class="rating">
			<tr>
				<th>Head 1</th>
				<th>Head 2</th>
				<th>Head 3</th>
			</tr>
			<tr>
				<td>10</td>
				<td class="number">20</td>
				<td class="number">30</td>
			</tr>
		</table>

	</body>
	</html>

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

Стало быть, проблема в стилях, а не в браузерах, решил я, и перед тем как постить вопрос на StackOverflow решил прошвырнуться по документам W3C о сортировке правил в CSS.

Итак, оказалось что правила сортируются в три этапа. Вначале — по источнику и важности, в таком порядке:

  • user-agent declarations
  • user normal declarations
  • author normal declarations
  • author important declarations
  • user important declarations

Чем правило ниже в этом списке, тем больше у него приоритет. Т.е. обычные стили сайта перекрывают обычные пользовательские стили, но перекрываются важными стилями автора и пользователя. Что меня тут удивило – то что правила автора вставлены “между” правилами пользователя. Я с пользовательскими правилами пока дела не имел, так что сталкиваться не приходилось, но поведение любопытное.

На втором этапе сортировки правила сортируются по специфичности (specificity). Специфичность считается так:

Сама специфичность состоит из трёх чисел: a,b,c,d , и рассматривается как четырёзначное число в большой системе счисления.

  • a принимается равной 1 если правило находится в атрибуте style в HTML и 0 в остальных случаях. Это сразу выделяет правила в style в “отдельный класс”, всегда имеющий более высокий приоритет
  • b это число id-атрибутов в селекторе. При прочих равных правила с id-атрибутами всегда стоят выше чем правила без них
  • c это число других атрибутов и псевдоклассов
  • d – число имён элементов и псевдоэлементов

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

Итак, в моих стилях у селекторов одинаковое происхождение и важность. Посмотрим какая у них будет специфичность:

  • table: 0,0,0,1 (Одно имя элемента)
  • table.rating td: 0,0,1,2 (Один класс, два имени элемента)
  • td.number: 0,0,1,1 (Один класс, одно имя элемента)

Если вам понадобится вычислить специфичность правил (ни один из известных мне dev tools для браузеров этого не делает), можно воспользоваться онлайн-калькулятором.

Ну что ж, ещё один день прошёл не зря, я лучше понял CSS и в следующий раз уже не попадусь так просто на подобном поведении браузера. Чего и Вам желаю :)

Комментарии (2)
  1. Да есть такая штука. Поэтому всегда делаю полное наследование, т.е. типа:
    table.rating td{…}
    table.rating td.number{…}

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

Fill in your details below or click an icon to log in:

Логотип WordPress.com

You are commenting using your WordPress.com account. Log Out / Изменить )

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 501 other followers