CSS: выберите элемент и все его потомки
Чтобы выбрать элемент и все его дочерние элементы:
.media, .media * {color: #f00;}
Можно ли использовать только один селектор вместо двух, разделенных запятой? Я ищу более эффективный способ напечатать это.
3 ответа
В 2023 году недавние дополнения к синтаксису CSS и доступные псевдоклассы откроют несколько интересных альтернативных способов решения этой проблемы (хотя они все еще не так идеальны, как действительно нативный комбинатор «я» или «потомок »).
Давайте рассмотрим гипотетический.prose
класс, который идентифицирует авторский контент сайта, который может быть доставлен, например,<article>
или<section>
блоки с вложенной структурой или, например, элементы, которые непосредственно содержат текст.
Имея только строгие комбинаторы потомков и традиционный синтаксис CSS, такие элементы, как<p>
и<blockquote>
требуют добавления (потенциально несемантической) оболочки, такой как<div>
элемент.
Альтернативно, правила CSS могут быть написаны таким образом, чтобы они соответствовали как себе, так и потомкам, но это предполагает повторяющийся (и подверженный ошибкам) шаблон:
h1.prose, .prose h1 {...}
h2.prose, .prose h2 {...}
h3.prose, .prose h3 {...}
h4.prose, .prose h4 {...}
h5.prose, .prose h5 {...}
h6.prose, .prose h6 {...}
p.prose, .prose p {...}
blockquote.prose, .prose blockquote {...}
/* And so forth... */
Используя последние разработки CSS, вышеизложенное можно переписать следующим образом:
.prose, .prose * {
&:is(h1) {...}
&:is(h2) {...}
&:is(h3) {...}
&:is(h4) {...}
&:is(h5) {...}
&:is(h6) {...}
&:is(p) {...}
&:is(blockquote) {...}
/* Alternatively, the :where() pseudo-class can also be used,
which differs in how specificity is calculated. */
}
Очевидно,&:is(...)
часть по-прежнему является шаблонной, но повторение значительно сокращено, что можно считать улучшением.
Предостережение: по состоянию на май 2023 года поддержка браузером встроенной вложенности CSS все еще находится в стадии разработки (см. https://caniuse.com/css-nesting ), и код CSS, использующий эту возможность, должен быть преобразован в невложенный. синтаксис (с использованием, например, плагина postcss-nesting ). :is()
псевдокласс пользуется более широкой поддержкой (см. https://caniuse.com/?search=is).
Вот еще один интересный способ решения этой проблемы, который использует переменные CSS (также известные как пользовательские свойства ), подходящие для переключения отдельных свойств при наличии того, что можно было бы назвать «контекстными классами», независимо от того, определены ли такие классы на самом элементе или на одном из его предки.
:root {
--ctx-media: ;
--ctx-not-media: initial;
}
.media {
--ctx-media: initial;
--ctx-not-media: ;
}
* {
color: var(--ctx-media, #f00)
var(--ctx-not-media, inherit);
}
Переменная определяется одним пробелом в корневом элементе и не определена (теперь
Переходя к свойству цвета : какая бы переменная CSS ни была определена, она расширяется до одного пробела, а неопределенная — до своего резервного значения. Поскольку пробелы вокруг значений свойств семантически инертны, результирующее значение остается действительным. Наследуемое значение может быть заменено любым значением , которое требуется для немедийного контента. Обратите внимание, что оба случая должны быть включены в определение значения свойства. Если пропустить один случай, это приведет к недопустимому CSS:
* {
/* WRONG!!! Will resolve to `color: ;` when --ctx-media is defined */
color: var(--ctx-media, #f00);
}
Теперь значение наследования — или любое другое «немедийное» значение — может вызвать проблемы в ситуациях, когда свойство не наследуется (например, поля или отступы ), или когда оно может иметь несколько других значений в зависимости от контекста, и вы просто хочу, чтобы оно осталось неизменным. В таких ситуациях есть одно решение, не предполагающее создания
:root {
--ctx-media: ;
--ctx-not-media: initial;
}
.media {
--ctx-media: initial;
--ctx-not-media: ;
}
@layer media {
* {
color: var(--ctx-media, #f00)
var(--ctx-not-media, revert-layer);
}
}
Обратите внимание, что полное исключение слоев и использование значения по умолчанию revert вместо revert-layer не будет работать, поскольку тогда значение будет возвращено к тому, которое было до применения всей таблицы стилей, а не к его переопределенному определению в той же таблице стилей.
Это, конечно, более многословно, чем простое
Как слои CSS, так и пользовательские свойства широко поддерживаются браузерами.