You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中border-image conic-gradient示例无法正常运行问题

问题:styled-components实现CSS边框动画无效果

我正在将web.dev博客上的CSS边框动画示例用React TypeScript重构,直接在CSS文件中编写代码时效果正常,但使用styled-components实现时,两种写法均无法显示预期动画效果。

现有App.tsx代码

import React from "react";
import "./App.css";
import styled from "styled-components";

/* Animate when Houdini is available */
const Houdini = styled.div`
width: 400px;
height: 300px;
border-radius: 10px;
padding: 2rem;
margin: auto;

display: grid;
place-content: center;
text-align: center;

font-size: 1.5em;

--border-size: 0.3rem;
border: var(--border-size) solid transparent;

/* Paint an image in the border */
border-image: conic-gradient(
    from var(--angle),
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  )
  1 stretch;
background: rgb(255 255 255 / var(--opacity));

@supports (background: paint(houdini)) {
  @property --opacity {
    syntax: "<number>";
    initial-value: 0.5;
    inherits: false;
  }

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

  @keyframes opacityChange {
    to {
      --opacity: 1;
    }
  }

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

  .rainbow {
    animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
  }

  /* Hide the warning */
  .warning {
    display: none;
  }
}
`;

function App() {
  return (
    <>
      <Houdini>
        <p>
          This demo uses a real border with <code>border-image</code>, a
          background, and finally Houdini to animate.
        </p>
      </Houdini>

      <div>
        <p>
          ⚠️ Your browser does not support{" "}
          *@property*特性
          so the animation won’t work
          <br />
          Please use Chrome.
        </p>
      </div>
    </>
  );
}

export default App;

修改后的变体代码(仍无效)

我尝试了另一种写法(对应原示例的变体),但问题依旧:

const Houdini = styled.div`
// 省略其他相同样式
--border-size: 0.3rem;
border: var(--border-size) dotted transparent;
  background-image: linear-gradient(
      to right,
      rgb(255 255 255 / var(--opacity)),
      rgb(255 255 255 / var(--opacity))
    ),
    conic-gradient(
      from var(--angle),
      #d53e33 0deg 90deg,
      #fbb300 90deg 180deg,
      #377af5 180deg 270deg,
      #399953 270deg 360deg
    );
  background-origin: border-box;
  background-clip: padding-box, border-box;
// 省略其他相同样式
`;

解决方法

  • 绑定触发动画的类名:原示例中动画通过.rainbow类触发,但<Houdini>组件未添加该类名,需补充:
    <Houdini className="rainbow">
      {/* 组件内容 */}
    </Houdini>
    
  • 调整@property作用域:styled-components会封装组件样式,@property需要全局生效。可通过createGlobalStyle定义全局样式:
    import { createGlobalStyle } from 'styled-components';
    
    const GlobalStyles = createGlobalStyle`
      @supports (background: paint(houdini)) {
        @property --opacity {
          syntax: "<number>";
          initial-value: 0.5;
          inherits: false;
        }
    
        @property --angle {
          syntax: "<angle>";
          initial-value: 0deg;
          inherits: false;
        }
      }
    `;
    
    // 在App组件中引入全局样式
    function App() {
      return (
        <>
          <GlobalStyles />
          {/* 其他组件内容 */}
        </>
      );
    }
    
  • 确保动画可被正确引用:将@keyframes定义移到@supports外部或全局样式中,避免样式封装导致的引用问题。

完成以上修改后,边框动画即可正常运行。

内容的提问来源于stack exchange,提问作者user18943198

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:27:28