Переменные CSS не соблюдают приоритет селектора?

У меня есть код, который я пишу для конструктора веб-сайтов, который вызывает у меня проблемы. Мы используем переменные CSS для определения глобальных стилей как для настольных, так и для мобильных устройств, например:

:root {
  --section-padding-top: 2rem;
  --section-padding-right: 8rem;
  --section-padding-bottom: 2rem;
  --section-padding-left: 8rem;
}

@media only screen and (max-width: 767px) {
  #main {
    --section-padding-top: 3rem;
    --section-padding-right: 0rem;
    --section-padding-bottom: 3rem;
    --section-padding-left: 0rem;
  }
}

Мы используем селектор #main в мобильных переопределениях, чтобы обеспечить их сохранение. Причина в том, что мы разрешаем пользователям переопределять глобальные стили, определенные выше для определенных разделов, после чего наш код будет генерировать блок CSS на странице, который выглядит примерно так:

<style>
  .box-794ccd158158463bae325e0eb4c1c939 {
    --section-padding-top: 0rem;
    --section-padding-right: 8rem;
    --section-padding-bottom: 0rem;
    --section-padding-left: 8rem;
  }
  @media only screen and (max-width: 767px) {
    #main .box-794ccd158158463bae325e0eb4c1c939 {
      /* No mobile overrides in this example */
    }
  }
</style>

HTML-код раздела с переопределенным заполнением выглядит примерно так:

<body id = "main">
  <section data-id = "d1b57912-1e94-4014-929e-02a38d893710" class = "section component-1ca0a679fc4a4ba7a1e6b1fd9bec611e section-d1b579121e944014929e02a38d893710">
    <div class = "box box-794ccd158158463bae325e0eb4c1c939 section-box">
      <div class = "box-content">
        <!-- Content -->
      </div>
    </div>
  </section>
</body>

А CSS, применяющий переменные, выглядит так:

.section-box {
  padding: var(--section-padding-top) var(--section-padding-right) var(--section-padding-bottom) var(--section-padding-left);
}

Идея здесь в том, что переопределения рабочего стола, ограниченные классом (.box-794ccd158158463bae325e0eb4c1c939), не будут переопределять глобальные мобильные переменные, область действия которых ограничена идентификатором (#main).

На самом деле браузер (Chrome) соблюдает переопределение рабочего стола, которое определяется позже (на странице), и игнорирует глобальные мобильные переменные с идентификатором, которые были определены ранее во внешней таблице стилей, загруженной в файл .

Глянь сюда:

Есть идеи, почему это может быть? Спасибо!

Обновлено: Обновление для добавления. Я тоже попробовал это с !important, и это все еще переопределяется.

Ожидаемое поведение здесь заключается в том, что глобальное определение будет иметь приоритет, учитывая, что оно использует селектор идентификатора (а теперь еще и определение !important).

Кто-нибудь знаком с поведением переменных CSS, которое игнорирует приоритет селектора? Я не могу найти это документально нигде.

Связано со спецификой Developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Mark Schultheiss 18.06.2024 17:41

Пожалуйста, обновите, чтобы показать ИСПОЛЬЗОВАНИЕ переменных; в противном случае это просто переменные, и ничто не будет использовать их неявно. Дело в том, что ЕГЭ имеет не столько специфику, сколько декларацию. Например, наличие номера телефона не поможет, если у вас нет телефона, на который можно ответить.

Mark Schultheiss 18.06.2024 17:48

@MarkSchultheiss Упс! Хороший улов. Обновлено сейчас.

Steven Moseley 18.06.2024 18:05

Я думаю, что это, хм, особый пункт в MDN. «Стили для элемента с прямым назначением всегда будут иметь приоритет над унаследованными стилями, независимо от специфики наследуемого правила».

Adam 18.06.2024 18:33

@Адам, Адам, интересно, интересно, относится ли это к значениям переменных?

Steven Moseley 18.06.2024 18:56

Похоже так. Я поигрался с этим в codepen.

Adam 18.06.2024 18:58

@Адам подтвердил, что это решает проблему. Хотите отправить ответ, чтобы получить галочку? :D

Steven Moseley 18.06.2024 19:01

Отметим, что вы также можете настроить таргетинг на атрибут данных [data-id = "d1b57912-1e94-4014-929e-02a38d893710"] .section-box {

Mark Schultheiss 18.06.2024 23:29
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
1
8
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из MDN:

«Стили для элемента с прямым назначением всегда будут иметь приоритет над унаследованными стилями, независимо от специфики наследуемого правила».

Итак, похоже, что это правило:

.box-794ccd158158463bae325e0eb4c1c939 {
  --section-padding-top: 0rem;
  --section-padding-right: 8rem;
  --section-padding-bottom: 0rem;
  --section-padding-left: 8rem;
}

имеет приоритет над этим правилом:

@media only screen and (max-width: 767px) {
  #main {
    --section-padding-top: 3rem;
    --section-padding-right: 0rem;
    --section-padding-bottom: 3rem;
    --section-padding-left: 0rem;
  }
}

Это можно исправить, нацелив определенные переменные CSS на общий класс .box, чтобы они имели ту же область действия, что и переопределения, например:

@media only screen and (max-width: 767px) {
  .box {
    --section-padding-top: 3rem!important;
    --section-padding-right: 0rem!important;
    --section-padding-bottom: 3rem!important;
    --section-padding-left: 0rem!important;
  }
}

Другие вопросы по теме