Вложения CSS-селекторов без повышения специфичности

Возьмем эти три селектора, отсортированные с наивысшей специфичностью до самого низкого:

.special-section p { }
.weird-font        { }
p                  { }

Многие гуру CSS рекомендуют против вложенности, как в первом селекторе .special-section p, потому что его специфика достаточно высока, что вы не можете переопределить его простым классом типа .weird-font. Я хотел бы найти способ по-прежнему достичь вложенности, как в .special-section p, но без увеличения специфики. Что-то вроде этого:

 .weird-font { }
 .special-section p /* with hack to decrease specificity */ { }
 p { }

Случай использования:

Это довольно безопасно применять умолчания для типографики и такого документа, используя простые селектора, такие как p. Тем не менее, я хотел бы изменить эти значения по умолчанию для определенного раздела, похожие на .special-section p, без необходимости использовать хаки для увеличения специфичности селекторов типа .weird-font. Я предпочел бы использовать хак, чтобы уменьшить специфичность .special-section p, чем использовать взломать, чтобы повысить специфичность .weird-font. Есть ли способ сделать это?

Ответ 1

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

.weird-font, /* Normal weird font */
.special-section p.weird-font /* Override for special section */ 
  { }

Но, как вы видите, это скользящая шкала. Таким образом, эти гуру, вероятно, правы. Если вы удалите .special-section p и вместо этого предоставите те P свой собственный селектор .special-section-para или что-то еще, тогда у вас не будет этой проблемы.

Но лично я не возражаю, чтобы добавлять исключение, подобное тому, которое вы делали сейчас. Я думаю, что вся эта особенность существует для этой цели, и если вам нужен более конкретный селектор, чтобы что-то придумать, мне кажется, что это правильно.

Общепринятым решением является использование !important. Проблема с! Важно в том, что существует только один уровень переопределения. Если вы сделаете более конкретный селектор, вы можете переопределить его снова с еще более конкретным селектором. После использования! Важно, у вас нет вариантов. Что еще более важно, использование !important может помешать специальным таблицам стилей, которые пользователь может иметь для повышения удобочитаемости. По этой причине я никогда не использую !important в такой ситуации.

Но опять же, я не считаю себя гуру CSS.;)

Ответ 2

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

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

Таким образом, ваш единственный выход на уровень выбора - это увеличить его. Можете ли вы это сделать без использования хаков, зависит от вашего определения "взломать".

Следующее - это то, что я считаю взломом, потому что он использует синтаксически законный, но семантически бессмысленный селектор, например :not(_), который не имеет очевидной цели, но добавьте значение специфичности селектора для сложного селектора (что далеко не очевидно, особенно для непосвященных):

.special-section p { }
.weird-font, :not(_).weird-font { }

Следующее - это не то, что я считаю взломом, потому что это то, что вы обычно делали бы в любом случае. В значительной степени единственной "проблемой" в этом является то, что это явное повторение селектора одиночного класса:

.special-section p { }
.weird-font, .special-section p.weird-font { }

Если вы рассматриваете какой-либо посторонний селектор ради повышения специфичности, хак, который является совершенно разумным POV, не ошибитесь, тогда следующая лучшая вещь, которая не является взломом, - !important.

Лично я бы выбрал специфический взлом. !important имеет, гм, важные последствия, которые не связаны со спецификой взлома - помните, что !important и специфика имеют разную семантику. Например, вы не можете переопределить объявление !important с помощью встроенного стиля или JavaScript, если они не отмечены как важные. 1


1 Фактически, это был мой ответ Лие Вероу, когда она провела обсуждение в Twitter некоторое время назад относительно специфичности hacks против !important.

Ответ 3

Мне нравится быть таким конкретным, как в настоящее время необходимо. Мне нравится оставлять место для будущих изменений CSS, поэтому не используйте для этого как можно более конкретные, например:

.great-grandfather .grandfather .father .child { }

Я, если потребуется, конечно. Но, взяв пример выше, если бы я хотел переопределить .child для определенного элемента, который использует этот класс, который имеет стиль, который может быть таким:

.child {
   color: black;
}

Я бы поехал с одним родителем выше, чтобы по возможности переопределить его:

.father .child {
   color: white;
}

Далее по строке, если элемент на определенной странице использует класс .child, и в этом случае мне нужно переопределить как .father .child, я пойду еще на один уровень специфичности:

.grandfather .father .child {
   color: red;
}

Выполнение этого гарантирует, что вам не нужно использовать !important... Который я избегаю как чумы как можно больше!