У меня есть контейнеры с цветным фоном, которые попадают в одну из трех разных категорий, представленных sass-заполнителями %dark-box
, %light-box
и %gradient-box
. Мне нужно настроить стиль элементов, которые являются потомками этих блоков. Эти элементы могут быть вложены на любую произвольную глубину внутри блока.
Проблема в том, что ящики могут быть вложены друг в друга, причем на любую произвольную глубину, и нет ограничений на количество уровней вложенности. Блоки, внутренние блоки, внутренние блоки и т. д. Таким образом, селекторы, нацеленные на элементы внутри блоков, должны нацеливаться на элементы только в том случае, если этот блок является ближайшим ?-box
предком.
Рассмотрим этот HTML:
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div>
<div>
<p>This should have color:$dark-box-text-color</p>
</div>
</div>
</div>
<div>
<div class = "light-box"> <!-- backgrund-color:$light-box-bg-color -->
<div>
<div>
<div>
<p>This should have color:$light-box-text-color</p>
</div>
<div>
<p>This should have color:$light-box-text-color</p>
</div>
<div>
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div class = "light-box"> <!-- backgrund-color:$light-box-bg-color -->
<div>
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div>
<p>This should have color:$dark-box-text-color</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
С помощью этого scss:
%dark-box {
background-color: $dark-box-bg-color;
// other stuff ...
}
%light-box {
background-color: $light-box-bg-color;
// other stuff ...
}
%gradient-box {
background-color: $gradient-box-bg-color;
// other stuff ...
}
.dark-box {@extend %dark-box;}
.light-box {@extend %light-box;}
.gradient-box {@extend %gradient-box;}
%dark-box-text {
color: $dark-box-text-color;
// other stuff ...
}
%light-box-text {
color: $light-box-text-color;
// other stuff ...
}
%gradient-box-text {
color: $gradient-box-text-color;
// other stuff ...
}
:is(%dark-box) > p,
:is(%dark-box) > /*! n descendants, none of which have a %light-box or %gradient-box class */ > p {
@extend %dark-box-text;
}
:is(%light-box) > p,
:is(%light-box) > /*! n descendants, none of which have a %dark-box or %gradient-box class */ > p {
@extend %light-box-text;
}
:is(%gradient-box) > p,
:is(%gradient-box) > /*! n descendants, none of which have a %dark-box or %light-box class */ > p {
@extend %gradient-box-text;
}
Как я могу создать селектор, нацеленный на первый и последний абзац, но ни на один из абзацев в середине? И наоборот?
Я знаю, что могу сделать что-то, что явно нацелено на каждую возможную глубину абзаца (как показано ниже), но тогда мне придется установить максимальный предел глубины. Это также будет означать неприемлемое увеличение времени предварительной обработки Sass, если учесть, что заполнители блоков могут быть расширены с помощью множества различных селекторов, а абзацы — лишь один из многих элементов, на которые мне нужно будет ориентироваться таким образом.
:is(%dark-box) > p,
:is(%dark-box) > :not(:where(%light-box), :where(%gradient-box)) > p,
:is(%dark-box) > :not(:where(%light-box), :where(%gradient-box)) > :not(:where(%light-box), :where(%gradient-box)) > p,
:is(%dark-box) > :not(:where(%light-box), :where(%gradient-box)) > :not(:where(%light-box), :where(%gradient-box)) > :not(:where(%light-box), :where(%gradient-box)) > p,
// etc...
{
@extend %dark-box-text;
}
Я попробовал несколько вариантов следующего, но пока не нашел ничего работающего.
:is(%dark-box) > p,
:is(%dark-box) :not(:where(:where(%light-box), :where(%gradient-box))) p {
@extend %dark-box-text;
}
🤔 А знаете ли вы, что...
HTML5 внедряет форматирование и стилизацию с помощью CSS3 для создания более привлекательных веб-страниц.
К сожалению, похоже, что вы столкнулись с одной из проблем, которая в будущем будет решена с помощью @scope
at-правила.
Тем не менее, хотя селекторы не учитывают близость ближайшего предка, наследование учитывает. Таким образом, вы можете использовать пользовательские свойства CSS, чтобы решить эту проблему.
div {
padding: 4px;
}
.dark-box, .light-box {
color: var(--text-color);
background-color: var(--background-color);
}
.dark-box {
--text-color: white;
--background-color: midnightblue;
}
.light-box {
--text-color: black;
--background-color: lemonchiffon;
}
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div>
<div>
<p>This should have color:$dark-box-text-color</p>
</div>
</div>
</div>
<div>
<div class = "light-box"> <!-- backgrund-color:$light-box-bg-color -->
<div>
<div>
<div>
<p>This should have color:$light-box-text-color</p>
</div>
<div>
<p>This should have color:$light-box-text-color</p>
</div>
<div>
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div class = "light-box"> <!-- backgrund-color:$light-box-bg-color -->
<div>
<div class = "dark-box"> <!-- backgrund-color:$dark-box-bg-color -->
<div>
<div>
<p>This should have color:$dark-box-text-color</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Кроме того, я должен отметить, что имена классов не имеют точки .
в разметке html; это только для создания селектора CSS.