Как сбросить переменную CSS (она же настраиваемые свойства) и использовать резервную?

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

Что-то типа:

:root {
  --border-width-top: 0;
  --border-width-right: 0;
  --border-width-bottom: 0;
  --border-width-left: 0;
  --border-width: 0;
}
div {
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div {
  --border-width-top: 10px;
}

Это не будет работать, так как если ширина границы имеет значение по умолчанию, то оно всегда будет иметь приоритет над резервными значениями. Не уверен, что есть способ сделать это в настоящее время, но я чувствую себя так близко к поиску решения.

Вот стек-блиц, с которым я играю: stackblitz

Ответ Куккуза работает для вашего конкретного примера, но я боюсь, что вы действительно спрашиваете, есть ли способ «отменить определение» переменных, определенных выше в дереве DOM. Или я слишком много думаю?

Mr Lister 10.04.2019 16:51

@MrLister, вы правы, посмотрите решение Темани

kukkuz 10.04.2019 17:05
Приемы 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 сценарий полностью изменился.
7
2
773
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Значение отступать работает, только если переменная --border-width не определена:

The custom property's fallback value, which is used in case the custom property is invalid in the used context.

MDN

См. демо ниже:

:root {
  --border-width-top: 0;
  --border-width-right: 0;
  --border-width-bottom: 0;
  --border-width-left: 0;
  /*--border-width: 0;*/
}

div {
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}

div {
  --border-width-top: 10px;
}
<div id = "app">
  <h1>TypeScript Starter</h1>
</div>

Да, это тоже было моим пониманием. Я ищу способ определить переменную, но не присвоить ей значение. Это делается для того, чтобы он присутствовал в документации, но не влиял на границу, если не задан явным образом. Спасибо за ответ.

masimplo 10.04.2019 17:18
Ответ принят как подходящий

Вы можете отменить значение, используя initial, чтобы использовать резервное значение:

:root {
  --border-width-top: 2px;
  --border-width-right: 2px;
  --border-width-bottom: 2px;
  --border-width-left: 2px;
  --border-width: 0;
}
div {
  margin:5px;
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div.box {
  --border-width:initial;
  --border-width-top: 10px;
}
<div>some content</div>
<div class = "box">some content</div>

из спецификация:

The initial value of a custom property is an empty value; that is, nothing at all. This initial value has a special interaction with the var() notation, which is explained in the section defining var().

а также

To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property. Otherwise,
  3. if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at computed-value time

прикольно... немного опоздал :)

kukkuz 10.04.2019 17:03

Хороший. Я не знал, что о первоначальном. Ваш пример немного усложняет использование, так как я должен убедиться, что я определяю --border-width как начальный, иначе боковое значение игнорируется. Однако я попытался установить его как значение по умолчанию внутри корня, и, похоже, он делает именно то, что мне нужно. Есть ли что-то, что я могу упустить, пойдя по этому пути?

masimplo 10.04.2019 17:19

@masimplo нет, это то же самое. Установка начального значения внутри корня или внутри элемента будет делать то же самое, поскольку во время оценки оно будет начальным, поэтому нам все равно, куда вы установите начальное значение. Мы просто заботимся о значении VAR при проведении оценки.

Temani Afif 10.04.2019 17:24

Как объяснил @Temani, вы можете использовать --varName: initial, чтобы установить фактически пустое, но недопустимое значение для переменной. Тогда будет использоваться любые объявленные резервные значения в var(....).

Поэтому, если вы определяете --text_color: initial, используйте селектор: color: var(--text_color, hotpink) ваш текст будет розовым, а не черным (как было бы, если бы вы прямо написали color: initial).


Затем я подумал, не мог бы я использовать unset вместо initial. Просто казалось более естественным отменить определение переменной с помощью --text_color: unset. Это более интуитивно понятно, и, поскольку вы, вероятно, редко используете unset, вы запомните свое намерение.

Однако оказывается, что unset не работает точно так же, как initial, но иногда может быть полезен, если вам нужно наследовать переменные, объявленные выше.

--text_color: initial

  • Устанавливает значение переменной в пустое значение (см. указанную спецификацию в ответе Тамани)
  • Любые узлы-предки, которые устанавливают --text_color, будут переопределены этим объявлением.
  • Мне нравится думать об этом, как если бы вы могли установить --text_color: null

--text_color: unset

  • Эффективно полностью удаляет переменную из этого узла DOM. Он не устанавливает для него магический пустое значение — он ведет себя так же, как если бы вы просто полностью удалили его из своего кода.
  • Это позволяет использовать любое значение унаследовал.
  • Мне нравится думать об этом, как если бы вы могли установить --text_color: undefined
  • Поэтому, если какой-либо узел-предок DOM определяет --text_color: green, а ваш узел объявляет --text_color: unset вместе с color: var(--text_color, blue), он будет зеленым, а не синим.

Это было полезно для меня, потому что я динамически устанавливаю множество переменных, и мне нужно было сбросить их, как если бы они никогда не устанавливались.

Я не могу обещать, является ли это фактическим поведением спецификации :-)

Вы также можете сделать это в Javascript:

element.style.setProperty('--button_icon_active_color', '')
element.style.setProperty('--button_icon_active_color', null)

Они оба «сбросят» значение, как будто его никогда не было.

Если вы запустите эту команду в консоли браузера, вы увидите, что она исчезнет из стилей.

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