CSS @property делает невозможное возможным

внешний интерфейс CSS

В этой статье в основном рассказывается об очень новой функции CSS, CSS @property, ее появление значительно расширяет возможности CSS!

согласно сMDN -- CSS Property, @property CSS at-rule является частью CSS Houdini API, который позволяет разработчикам явно определять свои настраиваемые свойства CSS, позволяя проверять типы свойств, устанавливать значения по умолчанию и определять, можно ли наследовать настраиваемое свойство.

CSS Houdiniчто это такое,CSS HoudiniОткройте базовый API CSS для разработчиков, чтобы разработчики могли сами расширять CSS через этот интерфейс, и предоставьте соответствующие инструменты, позволяющие разработчикам вмешиваться в процесс стиля и компоновки механизма рендеринга браузера, чтобы разработчики могли писать браузеры, которые могут анализировать код CSS для создания новых функций CSS. Конечно, это не тема этой статьи, а скорее описание.

CSS PropertyКак это использовать? Мы быстро начнем с нескольких простых примеров и сосредоточимся на ключевой роли, которую они играют в CSS-анимации, и на том огромном улучшении, которое они привносят в анимацию CSS.

Пример

Обычно мы определяем и используем пользовательское свойство CSS следующим образом:

:root {
    --whiteColor: #fff;
}

p {
    color: (--whiteColor);
}

и имеют@propertyПосле правила мы также можем определить пользовательское свойство CSS, например следующий код:

<style>
@property --property-name {
  syntax: '<color>';
  inherits: false;
  initial-value: #fff;
}

p {
    color: var(--property-name);
}
</style>

Просто прочитайте:

  • @property --property-nameсередина--property-nameимя пользовательского свойства, которое можно передать в CSS после определенияvar(--property-name)Цитировать
  • синтаксис: правила грамматики пользовательского атрибута, которые также можно понимать как тип определенного пользовательского атрибута.
  • наследует: разрешить ли наследование
  • начальное значение: начальное значение

в,@propertyСинтаксис и наследуемые дескрипторы в правилах обязательны.

Кстати, способ его определения в JavaScript тоже очень прост:

<script>
CSS.registerProperty({
  name: "--property-name",
  syntax: "<color>",
  inherits: false,
  initialValue: "#c0ffee"
});
</script>

Поддерживаемые типы синтаксиса синтаксиса

syntaxПоддерживаемые типы синтаксиса очень богаты, в основном охватывая все типы, которые вы можете себе представить.

  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident (a custom identifier string)

в синтаксисе+,#,|символ

Определенный CSS@propertyСинтаксис переменной допускает некоторые специальные определения типов.

  • syntax: '<color#>': принимает список значений цвета, разделенных запятыми.
  • syntax: '<length+>': принимает список значений длины, разделенных пробелами
  • syntax: '<length | length+>': принимает одну длину или список значений длины, разделенных пробелами.

Хорошо, так много предзнаменований, так зачем использовать такой громоздкий синтаксис для определения пользовательских свойств CSS? В чем преимущество пользовательских переменных, определенных CSS Houdini? Давайте поговорим об этом один за другим.

использоватьcolorсинтаксис тип синтаксиса, применяемый к градиентам

Давайте посмотрим на пример, где у нас есть такой шаблон градиента:

<div></div>
div {
    background: linear-gradient(45deg, #fff, #000);
}

Давайте изменим приведенный выше код и вместо этого используем пользовательские свойства CSS:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
}

В результате получается та же карта градиента:

Добавим эффект перехода:

:root {
    --colorA: #fff;
    --colorB: #000;
}
div {
    background: linear-gradient(45deg, var(--colorA), var(--colorB));
    transition: 1s background;
    
    &:hover {
        --colorA: yellowgreen;
        --colorB: deeppink;
    }
}

Посмотрите, что происходит при наведении курсора мыши:

Хотя мы установили анимацию перехода 1 сtransition: 1s background, но, к сожалению, CSS не поддерживает прямое изменение перехода цвета фонового градиента, мы получаем только изменение между двумя кадрами.

Модернизация с помощью CSS @property

Хорошо, тогда мы главные герои этой статьи, использующие пользовательские свойства CSS в Houdini API для замены исходных пользовательских свойств CSS.

Просто измените его, используйтеcolorсинтаксис тип синтаксиса:

@property --houdini-colorA {
  syntax: '<color>';
  inherits: false;
  initial-value: #fff;
}
@property --houdini-colorB {
  syntax: '<color>';
  inherits: false;
  initial-value: #000;
}
.property {
    background: linear-gradient(45deg, var(--houdini-colorA), var(--houdini-colorB));
    transition: 1s --houdini-colorA, 1s --houdini-colorB;
    
    &:hover {
        --houdini-colorA: yellowgreen;
        --houdini-colorB: deeppink;
    }
}

мы использовали@propertyСинтаксис, определяет две настраиваемые переменные CSS Houdini.--houdini-colorAа также--houdini-colorB, при изменении наведения измените два цвета.

Важно отметить, что оператор перехода, который мы установилиtransition: 1s --houdini-colorA, 1s --houdini-colorB,это здесь,Мы устанавливаем переходы для пользовательских переменных CSS Houdini, а не дляbackgroundУстановите анимацию перехода, и посмотрите на эффект на этот раз:

Ого, получилось, смена цвета градиента сменилась с двухкадровой покадровой анимации на твин-анимацию, реализовав эффект перехода от одного цвета градиента к другому! И все это благодаря возможностям пользовательских переменных CSS Houdini!

Демонстрация CodePen — пользовательская переменная CSS Houdini для достижения анимации градиентного перехода цвета

Градиентная анимация перехода цвета фона с использованием CSS @property

В приведенном выше DEMO мы использовали пользовательские переменные CSS Houdini для определенияbackgroundЭффект перехода привит кcolorКроме того, CSS поддерживает преобразование одного цвета в другой, таким образом мы ловко реализуем анимацию перехода градиентного цвета фона.

Ранее мы обсуждали, сколько способов анимировать градиентные переходы цвета фона в CSS.Смело анимируйте цветовые градиенты фона!, на сегодняшний день у нас есть еще один способ добиться этого!


@property --colorA {
  syntax: '<color>';
  inherits: false;
  initial-value: fuchsia;
}
@property --colorC {
  syntax: '<color>';
  inherits: false;
  initial-value: #f79188;
}
@property --colorF {
  syntax: '<color>';
  inherits: false;
  initial-value: red;
}
div {
    background: linear-gradient(45deg,
        var(--colorA),
        var(--colorC),
        var(--colorF));
    animation: change 10s infinite linear;
}

@keyframes change {
    20% {
        --colorA: red;
        --colorC: #a93ee0;
        --colorF: fuchsia;
    }
    40% {
        --colorA: #ff3c41;
        --colorC: #e228a0;
        --colorF: #2e4c96;
    }
    60% {
        --colorA: orange;
        --colorC: green;
        --colorF: teal;
    }
    80% {
        --colorA: #ae63e4;
        --colorC: #0ebeff;
        --colorF: #efc371;
    }
}

Полный код можно найти здесь:

Демонстрация CodePen — пользовательская переменная CSS Houdini для достижения анимации градиентного перехода цвета 2

conic-gradient с CSS @property для анимации круговой диаграммы

Хорошо, выше мы продемонстрировалиsyntaxдляcolorСлучай типа синтаксиса. В начале статьи мы также перечислили множествоsyntaxТипы.

Теперь давайте попробуем другие типы, используяpercentageпроцентный тип илиangleУгловой тип, реализует анимацию при наведении круговой диаграммы.

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

<div></div>
.normal {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: conic-gradient(yellowgreen, yellowgreen 25%, transparent 25%, transparent 100%); 
    transition: background 300ms;
    
    &:hover {
        background: conic-gradient(yellowgreen, yellowgreen 60%, transparent 60.1%, transparent 100%); 
    }
}

будет иметь такой эффект, посколькуconic-gradientАнимация перехода также не поддерживается, и результатом является прямая смена одного кадра на другой:

Хорошо, давайте изменим его с помощью пользовательских переменных CSS Houdini:

@property --per {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 25%;
}

div {
    background: conic-gradient(yellowgreen, yellowgreen var(--per), transparent var(--per), transparent 100%); 
    transition: --per 300ms linear;
    
    &:hover {
        --per: 60%;
    }
}

Взгляните на эффект после преобразования:

Демонстрация CodePode — конический градиент с CSS @property для реализации анимации круговой диаграммы

Раньше было очень сложно использовать чистый CSS для достижения эффекта, и если его можно легко достичь, я должен вздохнуть.CSS @propertyМощная способность!

синтаксис символа |

Кстати, давайте продемонстрируем немного более сложное использование синтаксиса при определении пользовательских переменных Houdini.

существуетconic-gradient, мы можем использовать проценты или углы в качестве ключевых слов, и вышеприведенное DEMO также может быть преобразовано в это:

@property --per {
  syntax: '<percentage> | <angle>';
  inherits: false;
  initial-value: 25%;
}
...

Указывает, что наше пользовательское свойство может быть либо значением в процентах, либо значением угла.

Кроме|Кроме символов есть+а также#Символы указывают на то, что атрибуты, разделенные пробелами и запятыми, принимаются, и вы можете попробовать их сами, если вам это интересно.

использоватьlengthТип действует на некоторые изменения длины

Обладая вышеуказанными навыками, мы можем использовать возможность пользовательских переменных Houdini для заполнения и исправления некоторых эффектов, которые ранее не могли напрямую переходить анимацию.

В прошлом мы хотели реализовать эффект наведения с подчеркиванием текста следующим образом:

p {
    text-underline-offset: 1px;
    text-decoration-line: underline;
    text-decoration-color: #000;
    transition: all .3s;
    
    &:hover {
        text-decoration-color: orange;
        text-underline-offset: 10px;
        color: orange;
    }
}

потому чтоtext-underline-offsetАнимации перехода не поддерживаются, и результат следующий:

Используйте пользовательские переменные Houdini для трансформации, превратите распад в магию:

@property --offset {
  syntax: '<length>';
  inherits: false;
  initial-value: 0;
}
div {
    text-underline-offset: var(--offset, 1px);
	text-decoration: underline;
	transition: --offset 400ms, text-decoration-color 400ms;
    
    &:hover {
        --offset: 10px;
        color: orange;
	text-decoration-color: orange;
    }
}

Вы можете получить эффект шелковистого перехода:

CodePen Demo - Underlines hover transition(Chrome solution with Houdini)

На практике используйте CSS @property с фоном для достижения анимации заставки.

Что ж, из-за существования CSS @property работа, которая раньше требовала большого количества кода CSS, внезапно стала проще.

мы пытаемся использоватьCSS @propertyС фоном реализована простая анимация заставки.

мы используемbackgroundВы можете просто получить такой график, код выглядит следующим образом:

html, body {
    width: 100%;
    height: 100%;
}
body {
    background-image:
        radial-gradient(
            circle at 86% 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at 15% 16%,
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at 75% 99%,
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(rgb(34, 222, 237), rgb(135, 89, 215));
}

Эффект следующий, довольно хорошее статичное фоновое изображение:

image

Как обычно, мы хотим сделать этопошевеливайся, на самом деле требует определенных усилий, и теперь, черезCSS @property, измените некоторые детали элементов, которые мы хотим анимировать, и мы сможем получить очень хорошие анимационные эффекты:

body,
html {
    width: 100%;
    height: 100%;
}

@property --perA {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 75%;
}

@property --perB {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 99%;
}

@property --perC {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 15%;
}

@property --perD {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 16%;
}

@property --perE {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 86%;
}

@property --angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

body {
    background-image: 
        radial-gradient(
            circle at var(--perE) 7%,
            rgba(40, 40, 40, 0.04) 0%,
            rgba(40, 40, 40, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 50%,
            rgba(200, 200, 200, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perC) var(--perD),
            rgba(99, 99, 99, 0.04) 0%,
            rgba(99, 99, 99, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 50%,
            rgba(45, 45, 45, 0.04) 100%
        ),
        radial-gradient(
            circle at var(--perA) var(--perB),
            rgba(243, 243, 243, 0.04) 0%,
            rgba(243, 243, 243, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 50%,
            rgba(37, 37, 37, 0.04) 100%
        ),
        linear-gradient(var(--angle), rgb(34, 222, 237), rgb(135, 89, 215));
    animation: move 30s infinite alternate linear;
}

@keyframes move {
    100% {
        --perA: 85%;
        --perB: 49%;
        --perC: 45%;
        --perD: 39%;
        --perE: 70%;
        --angle: 360deg;
    }
}

Эффект следующий (потому что размер загрузки Gif ограничен, скорость увеличена, а часть перехвачена, просто как подсказка):

property1

Общий эффект довольно хороший, вы можете щелкнуть здесь для полной демонстрации:

CodePen Demo -- CSS @property PureCSS Wrapper

использованная литература:

наконец

Что ж, это конец этой статьи, представляющий часть CSS @property API CSS Houdini и использующий ее для достижения некоторых анимационных эффектов, которые не могли быть легко достигнуты в прошлом, я надеюсь, что это поможет вам :)

Если вы хотите получить самую интересную информацию о CSS, не пропустите мой официальный аккаунт --Интересные факты о внешнем интерфейсе iCSS😄

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

Если у вас есть какие-либо вопросы или предложения, вы можете общаться больше.Оригинальные статьи ограничены в написании и знаниях.Если в статье есть какие-либо неточности, пожалуйста, дайте мне знать.

Категории