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
相关产品推荐
相关产品推荐

