Frontender Magazine

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

Это короткая публикация — переписка по емейлу с моим клиентом, который задал мне вопрос о цепочках одинаковых классов (например .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ов, в действительности, не считают количество классов в разметке. Они просто задают один и тот же вопрос несколько раз.

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

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Harry Roberts
Автор:
Harry Roberts
Сaйт:
http://csswizardry.com/
Twitter:
@csswizardry
GitHub:
csswizardry
Юрий Матюхин
Переводчик:
Юрий Матюхин
Сайт:
https://ymatuhin.ru/
GitHub:
ymatuhin
Twitter:
@ymatuhin
Email:
ymatuhin@yandex.ru

Комментарии (6 комментариев, если быть точным)

Автар пользователя
ifeature

Я правильно понимаю, что <div class="foo foo foo"></div> является валидным, только потому, что в DTD не представляется возможным указать на уникальность каждого "слова", что находится в значении класса элемента?

Автар пользователя
SilentImp

@ifeature <div class="foo foo foo"></div> определенно является валидным. Интереснее тут скорее возможность использовать селекторы вида .foo.foo.foo для повышения веса. И при этом их не нужно дублировать в class: <div class="foo"></div> отловится по селектору .foo.foo.foo.

Автар пользователя
gwer

И ни слова о том, что <div class="foo foo foo"></div> не попадает под селектор [class="column column"], равно как и наличие любого другого «лишнего» класса у элемента лишит его соответствия селектору. Такой селектор будет требовать точного совпадения значения атрибута class, что, мягко говоря, дико для классов. Автор оригинальной публикации поскромничал с предостережнниями.

Автар пользователя
SilentImp

@gwer есть же масса разных селекторов по атрибуту, например [attr~=value].

Автар пользователя
gwer

@SilentImp, ограничений, накладываемых на вариант автора, это не отменяет (=

Автар пользователя
pokatomnik

не могу представить себе кейс где class="foo foo foo" будет оправдан и при этом не будет способов сделать это как-то лучше.