Вложения 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
... Который я избегаю как чумы как можно больше!