Нюансы использования цепочек одинаковых классов

Эта короткая публикация — переписка по электронной почте с моим клиентом, который задал мне вопрос о цепочках одинаковых классов (например .foo.foo {}).

Вопрос был, в основном, о количестве «ссылок» в цепочке, и их связи с тем, сколько раз конкретный класс использован в HTML.

Например, соответствует ли селектор .foo.foo {} элементу с классами class="foo foo", а .foo.foo.foo {} — элементу с class="foo foo foo", и так далее?

Клиент:

Привет!

Надеюсь, у тебя все хорошо.

Я хотел бы задать тебе один вопрос про CSS: я был уверен, что текст элементов отобразится тремя разными цветами, но этого не произошло (во всех элементах текст синий), и я не могу нагуглить никакого объяснения этому:

.column { color: red; }
.column.column { color: green; }
.column.column.column { color: blue; }

Демо: jsfiddle.net/otk9661u.

Почему так происходит?

Я:

Привет!

Все хорошо, спасибо. Работаю в солнечном Лондоне с классными клиентами. Как у тебя дела? Как остальные?

Хмм. Это забавно! Удивительно, что всё это один и тот же селектор.

.color {} спрашивает «Есть ли у элемента класс color

.color.color {} не спрашивает «Есть ли два класса color?», он просто задаёт тот же вопрос дважды. В действительности, он ничего не «подсчитывает» в HTML. Это тонкое, но важное различие, как ты уже заметил!

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

[class="column"] { color: red; }
[class="column column"] { color: green; }
[class="column column column"] { color: blue; }

Демо: jsfiddle.net/ssj4recq.

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

А где, собственно, это может пригодиться? Выглядит весьма странно, если честно :P Естественно, я бы порекомендовал избегать этого подхода.

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

Если же по каким-либо причинам вы хотите именно «посчитать» количество классов, вам нужно будет жёстко задать селектор атрибута с точным числом классов. Но такая конструкция будет весьма ненадёжной, так как пробелы — это часть строки, и если ваш шаблон перенесет классы на новую строку (или случится что-то в этом духе), строка перестанет совпадать с селектором. К тому же, на самом деле, мы ничего не подсчитываем: мы просто смотрим на совпадение строк.