Finesse
@Finesse

Как сделать так, чтобы при нескольких подходящих HTML элементу CSS селекторах с равным весом применялся селектор относящийся к ближайшему родителю?

Есть несколько равноправных с точки зрения семантики CSS стилей:

.style1 a {
  color: red;
}
.style2 a {
  color: green;
}


А в HTML коде есть блоки, к которым эти стили применяются, и которые могут друг в друга вкладываться. Например:

<div class="style2">
    <span>
        <a href="/">Style 2</a>
    </span>
    <div class="style1">
        <div>
            <a href="/">Style 1</a>
        </div>
        <div class="style2">
            <a href="/">Style 2</a>
        </div>
    </div>
</div>


В результате получается, что вторая ссылка («Style1») окрашивается в зелёный цвет. Это происходит из-за того, что тег ссылки подходит под правила .style1 и .style2, и, так как эти правила имеют одинаковый вес, применяется правило .style2, потому что это правило объявлено после правила .style1.

Как, не зная заранее о том, какой блок в какой будет вложен, сделать так, чтобы применялся стиль только ближайшего родительского блока со стилевым классом (то есть вторая ссылка стала красной)?

Песочница с указанным кодом: codepen.io/anon/pen/zvXmOw

P.S. Можно менять HTML код. Но учтите, что ссылки могут быть где угодно.
  • Вопрос задан
  • 284 просмотра
Решения вопроса 1
Finesse
@Finesse Автор вопроса
CSS-переменные элегантно решают эту проблему:

a {
  color: var(--link-color);
}
.style1 {
  --link-color: red;
}
.style2 {
  --link-color: green;
}


HTML-код тот же самый, то в вопросе. Демо: https://codepen.io/anon/pen/aqEmXr.

По данным Can I use эту технологию поддерживают браузеры примерно 80% пользователей. По данным посещений сайтов, к статистике которых я имею доступ (≈300000 посетителей в месяц), эту технологию поддерживают браузеры 88% посетителей.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@nirvimel
В CSS нет понятия "ближайший родитель", поэтому привязаться к этому не получится.
Есть решение, которое накладывает дополнительные условия на код:
  1. Все теги этой группы классов (style1, style2, ...) должны дополнительно помечаться классом группы, например block.
  2. Целевой тег (в примере a) должен лежать не глубже n уровней от ближайшего предка из группы классов (в примере n = 2).

Решение - https://jsfiddle.net/k9jmgauz/
.style1 > a, .style1 > :not(.block) > a {
  color: red;
}
.style2 > a, .style2 > :not(.block) > a {
  color: green;
}

<div class="style2 block">
    <span>
        <a href="/">Style 2</a>
    </span>
    <div class="style1 block">
        <div>
            <a href="/">Style 1</a>
        </div>
        <div class="style2 block">
            <a href="/">Style 2</a>
        </div>
    </div>
</div>
Ответ написан
alexey-m-ukolov
@alexey-m-ukolov Куратор тега CSS
Единственный вариант - явно прописать поведение во всех комбинациях и приправить important'ом:
.style2 .style1 a {
    color: red !important;
}

.style1 .style2 a {
    color: green !important;
}

.style2 a {
  color: green;
}

.style1 a {
  color: red;
}

Но даже это может работать при определенных условиях.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы