Наследование и откат переменных CSS

Мой вопрос в том, почему переменные CSS должны были добавить концепцию отката, а не просто полагаться на наследование, как другие свойства CSS.

Например:

:root {
 --color1: red;
}

body {
 color: var(--color1);
}

body p {
 color: var(--color2);
 --color2: blue;
}

body span {
  --color3: green;
  color: var(--color3);
  color: yellow;
  color: var(--color4);
}
<body>
  Text 1
  <p>
    Text 2
  </p>
  <span>
    Text 3
  </span>
</body>

Текст 3 становится красным, а не зеленым или желтым. Несмотря на то, что на уровне есть допустимые свойства, он принимает значение родительского цвета вместо проверки наличия других допустимых значений на том же уровне. Это происходит, когда имя переменной недействительно.

По-видимому, есть специальный запасной вариант для переменных CSS, поэтому вам нужно использовать что-то вроде:

color: var(--color4, yellow);

Но это снова означает дублирование цвета, так как

color: var(--color4, --color3);

не работает. Также нет:

color: var(--color3, yellow, blue);

или любые другие множественные значения.

Также нет поддержки таких ключевых слов, как наследование, currentColor, initial и т. Д. Поэтому я не уверен, как я могу полагаться на наследование, поскольку очевидно Мне нужно быть очень точным с данными значениями. Протестировано в Firefox 57.0.1 и Chrome 63.

Я знаю, что CSS-переменные все еще как Working Draft, так что, возможно, именно поэтому текущее поведение.


person Ecaterina Moraru    schedule 03.01.2018    source источник


Ответы (2)


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

С другой стороны, если вы спрашиваете, почему выражение var() по умолчанию не соответствует следующему наилучшему каскадному значению, это потому, что к тому времени, когда выражение var() оценивается, нет других значений, к которым можно было бы вернуться к < / em>, потому что все остальные объявления в каскаде были стерты. См. Раздел 3.1, в котором определяется термин недействительный при вычисленных -значение времени:

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

Сказав это, вы можете предоставить настраиваемое свойство в качестве резервного значения (при условии, что оно не то же самое, по той же причине, что объяснена выше) - это настраиваемое свойство просто должно появиться в собственном выражении var(), поскольку значение запасного варианта, ну, объявление значение, а не имя свойства.

В результате получается var(), вложенный в другой var():

body span {
  --color3: green;
  color: var(--color3);
  color: yellow;
  color: var(--color4, var(--color3));
}

:root {
 --color1: red;
}

body {
 color: var(--color1);
}

body p {
 color: var(--color2);
 --color2: blue;
}

body span {
  --color3: green;
  color: var(--color3);
  color: yellow;
  color: var(--color4, var(--color3));
}
<body>
  Text 1
  <p>
    Text 2
  </p>
  <span>
    Text 3
  </span>
</body>

person BoltClock    schedule 03.01.2018
comment
Спасибо за ваш ответ. Я постараюсь больше узнать о времени вычисленного значения и времени использованного значения, чтобы уточнить каскадные значения. Также спасибо за то, что вы заявили, что вам нужно вложить определение var (). - person Ecaterina Moraru; 03.01.2018
comment
Опять же, я ожидал, что для запасных вариантов нет ограничений, так как я не знаю других значений, которые можно было бы ограничить до 2. Например, font-family не имеет этого ограничения. - person Ecaterina Moraru; 03.01.2018
comment
@Ecaterina Moraru: У пользовательских свойств грамматика сильно отличается от font-family. Фактически, именно это позволяет кому-то делать что-то вроде это. - person BoltClock; 03.01.2018
comment
Моя проблема возникла из-за того, что color: var(--color3, yellow, blue); недействителен, а font-family: var(--font-body, Verdana, sans-serif); работает. Итак, вам нужно знать свойство, которое вы присваиваете, и то, что оно ожидает: значение, список. Он может автоматически обрезать строку, но я думаю, так безопаснее. Спасибо за Ваш ответ. - person Ecaterina Moraru; 03.01.2018

Первый

Не все свойства в CSS наследуются. Просмотрите эти ссылки, чтобы увидеть, какие свойства CSS наследуются и как применяется наследование:

https://www.w3.org/TR/CSS22/propidx.html
https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance


Второй

Порядок объявления повторяющихся свойств важен.

Если цвет, который вы хотите применить, green, это не то же самое:

// correct way to declare fallback color, it will be green and yellow if --color3 was not defined
body span {
  --color3: green;
  color: yellow;
  color: var(--color3);
}

as:

body span { // incorrect way to declare fallback color
  --color3: green;
  color: var(--color3);
  color: yellow;
  color: var(--color4);
}

Будет использовано свойство color: var(--color4);, поскольку в этом объявлении нет недопустимого синтаксиса, но поскольку переменная, объявленная как --color4, не указана, будет применен унаследованный цвет (в данном случае от body { color: var(--color1) })

Поскольку color является унаследованным свойством


В третьих

Еще одно решение - использовать резервный вариант с var(), но предыдущий вариант является резервным для старых браузеров, не поддерживающих var()

Кроме того, вы используете его неправильно, правильный способ использования отката от var() должен быть следующим:

color: var(--color4, var(--color3));

или это:

color: var(--color4, var(--color3, yellow));

var() принимает только 2 аргумента: значение, которое вы хотите использовать, и резерв.
См. Синтаксис его использования в следующая ссылка


Заключение

Поскольку var() доступен не во всех браузерах пока, я бы предпочел правильное использование дублированных свойств, или вы можете использовать оба варианта.

:root {
 --color1: red;
}

body {
 color: var(--color1);
}

body p {
 color: var(--color2);
 --color2: blue;
}

body span {
  --color3: green;
  color: yellow;
  color: var(--color4, var(--color3));
}
<body>
  Text 1
  <p>
    Text 2
  </p>
  <span>
    Text 3
  </span>
</body>

person Jose Paredes    schedule 03.01.2018
comment
В этом ответе не делается попыток выяснить, почему var () был разработан для использования резервных вариантов вместо возврата к наследованию по умолчанию (хотя тот факт, что не все свойства наследуются, является правдоподобным, если не совершенно очевидным, объяснение). - person BoltClock; 03.01.2018
comment
@BoltClock Я должен был пойти дальше с первым, но также я попытался уточнить, что в вопросе есть ошибки, которые могут вызвать недопонимание с концепцией var, следует ли мне обновить свой ответ? - person Jose Paredes; 03.01.2018
comment
Третий раздел тоже неверен. Резервный вариант в var () используется, когда настраиваемое свойство недоступно. Это не решение для старых браузеров - они все равно не увидят его, поскольку не понимают, что означает сама var (). - person BoltClock; 03.01.2018
comment
Я думаю, что спрашивающий понимает, как работает var (), и на самом деле они тщательно создали свой CSS специально, чтобы продемонстрировать свою точку зрения. Так что особо нечего уточнять. - person BoltClock; 03.01.2018
comment
@BoltClock Когда я ссылаюсь в Третьем на but the previous one is a fallback for older browsers that don't support var(), я имел в виду Второй не то, чтобы var() был запасным вариантом для старых браузеров - person Jose Paredes; 03.01.2018
comment
@BoltClock, тем не менее, спасибо за разъяснения! :) - person Jose Paredes; 03.01.2018
comment
Спасибо за такой подробный ответ и за исправление моей проблемы с вложенным объявлением var (). - person Ecaterina Moraru; 03.01.2018