CSS 渐变动画在 Svelte 组件中不起作用

问题描述 投票:0回答:1

我正在开发一个 Svelte 组件,我想在其中创建一个带有渐变动画的闪亮号召性用语按钮。该按钮应该具有随时间变化的线性和圆锥渐变的组合。但是,渐变动画没有按预期工作。

这是我的 Svelte 组件的代码: 这是我使用的代码笔https://codepen.io/Daniel-Johan-S-rby/pen/gOVrBbN

<script>
    // Her kan du legge til eventuelle Svelte-script hvis nødvendig
</script>

<style>
    @import url("https://use.typekit.net/tzv3rms.css");

    :root {
        --shiny-cta-bg: #000000;
        --shiny-cta-bg-subtle: #1a1818;
        --shiny-cta-fg: #ffffff;
        --shiny-cta-highlight: #3772ff;
        --shiny-cta-highlight-subtle: #1a243e;
    }

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

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

    @property --gradient-percent {
        syntax: "<percentage>";
        initial-value: 5%;
        inherits: false;
    }

    @property --gradient-shine {
        syntax: "<color>";
        initial-value: white;
        inherits: false;
    }

    .shiny-cta {
        --animation: gradient-angle linear infinite;
        --duration: 3s;
        --shadow-size: 2px;
        isolation: isolate;
        position: relative;
        overflow: hidden;
        cursor: pointer;
        outline-offset: 4px;
        padding: 1.25rem 2.5rem;
        font-family: inherit;
        font-size: 1.125rem;
        line-height: 1.2;
        border: 1px solid transparent;
        border-radius: 360px;
        color: var(--shiny-cta-fg);
        background: linear-gradient(var(--shiny-cta-bg), var(--shiny-cta-bg))
            padding-box,
        conic-gradient(
            from calc(var(--gradient-angle) - var(--gradient-angle-offset)),
            transparent,
            var(--shiny-cta-highlight) var(--gradient-percent),
            var(--gradient-shine) calc(var(--gradient-percent) * 2),
            var(--shiny-cta-highlight) calc(var(--gradient-percent) * 3),
            transparent calc(var(--gradient-percent) * 4)
        )
        border-box;
        box-shadow: inset 0 0 0 1px var(--shiny-cta-bg-subtle);
    }

    .shiny-cta::before,
    .shiny-cta::after,
    .shiny-cta span::before {
        content: "";
        pointer-events: none;
        position: absolute;
        inset-inline-start: 50%;
        inset-block-start: 50%;
        translate: -50% -50%;
        z-index: -1;
    }

    .shiny-cta:active {
        translate: 0 1px;
    }

    .shiny-cta::before {
        --size: calc(100% - var(--shadow-size) * 3);
        --position: 2px;
        --space: calc(var(--position) * 2);
        width: var(--size);
        height: var(--size);
        background: radial-gradient(
            circle at var(--position) var(--position),
            white calc(var(--position) / 4),
            transparent 0
        )
        padding-box;
        background-size: var(--space) var(--space);
        background-repeat: space;
        mask-image: conic-gradient(
            from calc(var(--gradient-angle) + 45deg),
            black,
            transparent 10% 90%,
            black
        );
        border-radius: inherit;
        opacity: 0.4;
        z-index: -1;
    }

    .shiny-cta::after {
        --animation: shimmer linear infinite;
        width: 100%;
        aspect-ratio: 1;
        background: linear-gradient(
            -50deg,
            transparent,
            var(--shiny-cta-highlight),
            transparent
        );
        mask-image: radial-gradient(circle at bottom, transparent 40%, black);
        opacity: 0.6;
    }

    .shiny-cta span {
        z-index: 1;
    }

    .shiny-cta span::before {
        --size: calc(100% + 1rem);
        width: var(--size);
        height: var(--size);
        box-shadow: inset 0 -1ex 2rem 4px var(--shiny-cta-highlight);
        opacity: 0;
    }

    .shiny-cta {
        --transition: 800ms cubic-bezier(0.25, 1, 0.5, 1);
        transition: var(--transition);
        transition-property: --gradient-angle-offset, --gradient-percent,
        --gradient-shine;
    }

    .shiny-cta,
    .shiny-cta::before,
    .shiny-cta::after {
        animation: var(--animation) var(--duration),
        var(--animation) calc(var(--duration) / 0.4) reverse paused;
        animation-composition: add;
    }

    .shiny-cta span::before {
        transition: opacity var(--transition);
        animation: calc(var(--duration) * 1.5) breathe linear infinite;
    }

    .shiny-cta:is(:hover, :focus-visible) {
        --gradient-percent: 20%;
        --gradient-angle-offset: 95deg;
        --gradient-shine: var(--shiny-cta-highlight-subtle);
    }

    .shiny-cta:is(:hover, :focus-visible),
    .shiny-cta:is(:hover, :focus-visible)::before,
    .shiny-cta:is(:hover, :focus-visible)::after {
        animation-play-state: running;
    }

    .shiny-cta:is(:hover, :focus-visible) span::before {
        opacity: 1;
    }

    @keyframes gradient-angle {
        to {
            --gradient-angle: 360deg;
        }
    }

    @keyframes shimmer {
        to {
            rotate: 360deg;
        }
    }

    @keyframes breathe {
        from,
        to {
            scale: 1;
        }
        50% {
            scale: 1.2;
        }
    }
</style>

<button class="shiny-cta">
    <span>Prøv Oss!</span>
</button>

问题:

渐变动画未按预期工作。按钮出现,但渐变没有动画效果。我已验证我的浏览器支持 CSS 自定义属性和 @property。

我尝试过的事情

通过在简单样式中使用 CSS 自定义属性来验证它们是否正确应用。 单独测试基本动画以确保它们正常工作。 检查浏览器的开发人员工具中的元素以查看是否应用了样式和动画。

css-animations svelte codepen css-gradients value-of-css-property
1个回答
0
投票

似乎存在范围界定问题。默认情况下,所有选择器和关键帧都通过向其添加哈希值来将其范围限定为当前组件,但这里对关键帧的引用显然没有正确调整。

解决方法是取消

@keyframes
的作用域,请注意,这会“污染”已定义动画的全局命名空间,因此如果其他组件也使用相同的名称定义未作用域的
@keyframes
,则会发生冲突。

要取消范围,请在名称前添加

-global-

@keyframes -global-gradient-angle {
    to {
        --gradient-angle: 360deg;
    }
}
@keyframes -global-shimmer {
    to {
        rotate: 360deg;
    }
}
@keyframes -global-breathe {
    from,
    to {
        scale: 1;
    }
    50% {
        scale: 1.2;
    }
}

(使用站点仍应使用不带此前缀的名称。)

© www.soinside.com 2019 - 2024. All rights reserved.