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

Я пытался заставить это работать какое-то время.

Дело в том, что внутренний div будет иметь некоторую форму и, вероятно, их будет больше одного (поэтому я использовал селектор nth-child). Предполагается, что этот внутренний div будет отображаться, а затем снова скрываться в течение определенного времени. проблема в том, что я хотел бы анимировать все (позже) несколько внутренних div в одной анимации. Для этого я думал, что могу использовать переменные CSS, но, похоже, это не работает.

То, что я пытаюсь заархивировать в этом примере, — это внутренний div, который просто мигает с помощью переменной. Но мой результат в Firefox — просто черный ящик.

Я что-то упустил? Я уже искал, можно ли вообще использовать переменные CSS в @keyframes, и, конечно же, вы можете. Единственная проблема с ними в анимации, по-видимому, заключается в том, что они не интерполируются между ними, а внезапно переключаются, что в данном случае не является проблемой.

@keyframes test{
    from{
        --one: 0;
    }
    to{
        --one: 1;
    }
}

#test{
    width: 100px;
    height: 200px;
    background-color: black;
    animation: test 1s infinite;
}
#test :nth-child(1){
    width: 20px;
    height: 20px;
    margin: auto;
    background-color: white;
    opacity: var(--one,0);
}
<div id="test">
    <div></div>
</div>


person Johann150    schedule 02.06.2018    source источник


Ответы (2)


Этого можно добиться, определив переменные с помощью (на момент написания статьи, плохо поддерживаемой) @property. , что позволяет объявлять типы и позволяет браузеру понять, например, что определенное свойство (переменная) является Числом, а затем он может постепенно анимировать/перемещать эту переменную возможно.

Пример кода:

@property --opacity {
  syntax: '<number>'; /* <- defined as type number for the transition to work */
  initial-value: 0;
  inherits: false;
}

@keyframes fadeIn {
  50%{ --opacity: 1 }
}

html{
  animation: 2s fadeIn infinite;  /* "forwards pesists the last keyframe styles */
  background: rgba(0 0 0 / var(--opacity));
}

Текущие разрешенные типы включают:

  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident (строка пользовательского идентификатора)

Полезные статьи:

  1. https://web.dev/at-property/#writing-houdini-custom-properties
  2. https://css-tricks.com/using-property-for-css-custom-properties
  3. крутые демонстрации Houdini
person vsync    schedule 13.10.2020
comment
круто, ищу это, а не нахожу ссылку MDN - person pery mimon; 14.11.2020
comment

Как указано в спецификации:

Анимация: нет

а также

Примечательно, что их можно даже перемещать или анимировать, но, поскольку ПА не имеет возможности интерпретировать их содержимое, они всегда используют поведение переворотов на 50%, которое используется для любого другая пара значений, которые не могут быть разумно интерполированы. Однако любое настраиваемое свойство, используемое в правиле @keyframes, становится испорченным анимацией, что влияет на то, как оно обрабатывается при обращении к нему через функцию var() в свойстве анимации.


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

@keyframes test {
  from {
    --one:0;
    opacity: var(--one);
  }
  to {
    opacity: var(--one);
    --one: 1;
  }
}

#test {
  width: 100px;
  height: 200px;
  background-color: black;
}

#test :nth-child(1) {
  width: 20px;
  height: 20px;
  margin: auto;
  background-color: white;
  animation: test 1s  infinite;
  
}
<div id="test">
  <div></div>
</div>

Кстати, вы можете заставить его работать, если используете его как transition, потому что в этом случае вы будете применять переход к непрозрачности, а не к пользовательскому свойству:

#test {
  width: 100px;
  height: 200px;
  background-color: black;
}

#test:hover {
  --one:1;
}

#test :nth-child(1) {
  width: 20px;
  height: 20px;
  margin: auto;
  background-color: white;
  opacity: var(--one,0);
  transition:1s all;
}
<div id="test">
  <div></div>
</div>

person Community    schedule 02.06.2018
comment
Я подумал, что здесь подойдет использовать поведение флипов на 50%. Почему нет? Потому что, как я уже сказал, в данном случае это было бы прекрасно. Возможно, я неправильно понимаю испорченную анимацию. - person Johann150; 03.06.2018
comment
@ Johann150, если честно, испорченная анимация также сбивает с толку, е :) Я много искал это, так как я тоже хочу иметь возможность анимировать пользовательское свойство, но после долгих исследований это было только раздел Спецификации, где я обнаружил, что это невозможно при использовании внутренних ключевых кадров. Кстати, давайте подождем, может быть, вы получите больше ответов;) - person Temani Afif; 03.06.2018
comment
Столкнувшись с связанной проблемой, и если я правильно прочитал цитируемый текст и спецификации, то animation-tainted относится только к значению var(), когда используется в свойстве animation, оно не должно влиять на свойства в @keyframes, хотя наличие его в @keyframes делает его испорченным для animation. Вот где это используется. (Может быть, это обходной путь для того, что могло быть источником бесконечного цикла?). Обратите внимание, что ваш первый пример отлично работает в Firefox. - person Kaiido; 06.10.2020
comment
@Kaiido, эта проблема не может быть в этой области, потому что вы не анимируете какие-либо пользовательские свойства, а анимируете rotate (). При этом нет анимации-испорченной. Даже если вы используете var() внутри animation, поведение, испорченное анимацией, также не будет нарушено. В спецификациях указано Однако любое пользовательское свойство, используемое в правиле @keyframes, становится испорченным анимацией --› это означает, что оно используется как --c:1 а не как property:var(-c). Последнее нормально. - person Temani Afif; 06.10.2020
comment
Я не имел в виду, что связанная проблема была такой же, только связанной, и это должно дать представление о том, почему я пришел сюда (другое несоответствие между браузерами). Я хочу сказать, что даже если вы используете непрозрачность с var() в ключевых кадрах, она не будет анимироваться, это неверно, или, по крайней мере, это не подразумевается цитатой ранее. Цитата говорит только о том, что если вы сделаете --foo: 2s; animation: anim-name var(--foo) infinite; } @keyframes anim-name { from { --foo: 0s } to { --foo: 15s } }, значение, используемое в animation: anim-name var(--foo) infinite; }, останется 2s. Это не говорит о том, что opacity не должно использовать обновленное значение. - person Kaiido; 06.10.2020
comment
В спецификациях сказано, что влияет на то, как оно обрабатывается при ссылке через функцию var() в свойстве animation, а не где-либо еще. (на самом деле с тех пор я нашел эту проблему, где указано, что display также касается при некоторых условиях и то все non-animatable будет. - person Kaiido; 06.10.2020
comment
Итак, чтобы быть ясным, ваше непонимание состоит в том, что вы думали, что становится анимацией испорченной означает, что его значение каким-то образом заблокировано в этом контексте @keyframes, в то время как на самом деле происходит то, что когда этот флаг установлен, он только блокирует алгоритм замены переменной только для свойство animation. Первый также хорош по характеристикам. - person Kaiido; 06.10.2020
comment
@Kaiido Я хочу сказать, что даже если вы используете непрозрачность с var() в ключевых кадрах, она не будет анимироваться, это неверно, --› это правда, учитывая первое объяснение, где написано UA не может интерпретировать их содержимое. Я использую эту часть, чтобы объяснить, почему они не могут иметь переход и анимацию (оба). Я сказал, что в другом вопросе нет анимации, потому что вы не используете какое-либо пользовательское свойство внутри ключевых кадров, поэтому это предложение не применяется в вашем случае. - person Temani Afif; 06.10.2020
comment
@Kaiido, мы не можем анимировать / перемещать настраиваемое свойство, потому что браузеру сложно понять их содержимое (целое число, число с плавающей запятой, строку и т. Д.). Испорченная анимация — это дополнительный вывод, если вы используете пользовательское свойство внутри ключевых кадров. - person Temani Afif; 06.10.2020
comment
@Temani нет и нет :-) вы можете очень хорошо анимировать пользовательские свойства в ключевом кадре, он просто будет использовать флипы на 50%. Анимация испорчена не для случая, когда пользовательское свойство используется в ключевом кадре, а для случая, когда оно используется в animation-, и скоро будет для случая, когда оно используется в неанимируемом свойстве. Контекст @keyframes — это то, что вызывает заражение пользовательского свойства, но ни в одном из ваших примеров это пользовательское свойство не используется в правиле animation-, поэтому даже если оно испорчено анимацией, оно не имеет никакого эффекта. на вашем коде вообще. Ваш первый фрагмент и ОП должны анимироваться. - person Kaiido; 07.10.2020
comment
@Kaiido хорошо, спецификация ясно сказала animatable: No (w3.org/TR /css-variables-1/#defining-variables), поэтому они не предназначены для анимации (по крайней мере, в текущей спецификации). В некоторых случаях браузер может решить сделать это по-другому, но это Нет, если только вам не повезет найти работающий пример. Что касается испорченной анимации, это отдельная история, и я сказал, что она выходит за рамки, потому что в ваших ключевых кадрах нет --c:something (это то, что я назвал используется в ключевых кадрах). Я не использую его, чтобы объяснить вещи, не связанные с животными (вероятно, я не использую хороший английский, чтобы объяснить это хорошо). - person Temani Afif; 07.10.2020
comment
Еще раз я никогда не говорил, что связанная проблема была той же самой вещью. Вы не понимаете, как работает флаг animation-tainted , и поэтому я пытаюсь объяснить вам, что он не имеет никакого отношения к вашему ответу здесь. Тот факт, что пользовательская переменная не является анимируемой, означает только то, что она будет переворачиваться при 50% поведении. Даже в вашей цитате ясно сказано: Примечательно, что их можно даже трансформировать или анимировать. - person Kaiido; 07.10.2020