Есть ли способ разрешить селекторам выбранного элемента иметь приоритет над селекторами родительских элементов?

#css

#css

Вопрос:

Рассмотрим следующий пример: http://jsfiddle.net/j6SpZ /

HTML:

 <div class="container">
    <a>Foobar</a>
    <a class="pink">Pink</a>
    <a class="gray">Gray</a>
</div>
  

CSS:

 a {
    border: 1px solid black;
    padding: 20px;
    display: block;
}
a.gray { background-color: gray; }
a:hover { background-color: teal; }
.container a { background-color: transparent; }
a.pink { background-color: pink; }
  

Результат:


Итак, все происходит в соответствии со спецификацией.

Значения приоритета стиля для последних четырех селекторов равны всем (0,0,1,1): 1 класс 1 элемент. Вы получаете ожидаемый прозрачный фон для первого и третьего полей (даже при наведении курсора мыши), потому что .container a он идет после a.gray и a:hover . Второй элемент окрашивается в розовый цвет, потому что a.pink идет после .container a . Круто (если я неверно истолковал спецификацию, дайте мне знать, но я думаю, что я при деньгах).

Но мой вопрос вращается вокруг семантики, позволяющей селекторам в родительских элементах оказывать такое же влияние на специфику, как селекторы в измененном элементе. Я чувствую, что gray селектор класса определенно «ближе» и более специфичен для элемента, чем container селектор класса в родительском элементе, и что a.gray объявление стиля «должно» иметь больший приоритет.

Есть ли способ на самом деле сделать это так, или философия, которой я могу следовать, чтобы устранить диссонанс в моем мышлении?

Фактическое приложение:

У меня есть стиль кнопки выбора, который сводится к следующему:

 .options a { background-color: gray; }
.options a:hover { background-color: blue; }
  

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

 .env1 .subenv1 .options a { background-color: transparent; }
  

Но теперь это объявление имеет приоритет даже над :hover , а я этого не хочу. Я все еще хочу, чтобы его поведение при наведении было таким же; я просто хочу, чтобы фон по умолчанию был прозрачным. Конечно, я могу повторно объявить стили наведения, но это повторяет ту информацию, которая неидеальна. У меня нет проблем с тем, чтобы принять это и просто повторно объявить, что я и делаю сейчас, но, конечно, должен быть способ заставить это иметь смысл в моей голове.

Комментарии:

1. Было бы неплохо поиграть с упрощенной демонстрацией приложения на jsFiddle.

2. Кстати, спецификация не учитывает, к каким элементам «прикреплен» селектор класса или псевдокласса. Он просто просит браузеры подсчитать количество каждого простого селектора, появляющегося в последовательности, и сложить их, как вы сказали, и я не знаю способа обойти это поведение без изменения селекторов или повторного объявления правил.

3. @BoltClock: Вот так: jsfiddle.net/FSRfN . Ваше наблюдение о том, как работает спецификация, проницательно и правильно. Что касается этого вопроса, я предполагаю, что причина, по которой спецификация работает не совсем так, как в моей голове, заключается в том, что есть какой-то другой, лучший шаблон для достижения того, к чему я стремлюсь. Итак, по сути, я нахожусь в поисках лучшего шаблона, который позволит мне устанавливать стили без наведения для элемента с родительскими селекторами, которые также не переопределяют стили наведения.

Ответ №1:

Что, если переместить :hover объявление в конец? Кажется, работает в вашей скрипке.

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

Комментарии:

1. Но в реальном приложении это не сработает, потому что более конкретный селектор по-прежнему имеет приоритет. Последние 4 селектора в скрипте все одинаково специфичны.

2. :hover будет работать с исправленным исходным примером, но, к сожалению, он перестает работать, когда приоритет предыдущих селекторов становится больше, что имеет место в моем разделе «фактическое приложение». Извините, что так сформулировал мой вопрос; это была ошибка с моей стороны.

Ответ №2:

Если вы всегда хотите, чтобы стиль наведения был в силе, вы можете добавить !important к стилю. Это будет означать, что background-color в :hover будет иметь приоритет над другими объявлениями. Я продемонстрировал это в вашей скрипке здесь.

Рекомендуется избегать использования important, однако, если считается, что это окончательный стиль наведения для этого элемента, его можно использовать.

Комментарии:

1. Хороший момент использования !important . До сих пор я мог сопротивляться в основном из-за того, что мне внушили, что ты не должен это использовать. Теперь, когда я думаю об этом, это действительно может показаться уместным в данном случае. Если я хочу, чтобы стили наведения выполнялись, несмотря на то, что родительские селекторы настолько плохи, возможно, они достаточно «важны», чтобы быть !important

Ответ №3:

Селектор типа «.container a.gray» обладает более высокой специфичностью и должен устранить проблему. Или переместите правило a.gray в конец, более поздние правила имеют более высокую специфичность.

Ответ №4:

@Sam152, @harpo и @chrisdowney вроде как корректны. По сути, вам нужно изменить вес CSS (или специфичность) каждого правила, чтобы оно соответствовало точному порядку, который вы хотите. Добиться такого баланса в этом случае может быть непросто. Вы можете использовать сочетание добавления селекторов (ответ @chrisdowney), упорядочения правил (ответ @harpo) или добавления !важно (ответ @Sam152). Все они изменяют порядок применения правил.

Specificals on CSS specificity — это хорошее руководство о том, как вычислить значение и, следовательно, иметь возможность корректировать любое из правил в соответствии с вашими конкретными требованиями к порядку правил.

Обязательно используйте инструмент разработчика браузера CSS, такой как Firebug (Firefox), Инструменты разработчика (Chrome), «Инструменты разработчика F12» (IE) или аналогичный, чтобы помочь вам определить порядок применения и быстро увидеть последствия ваших настроек.

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

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