为什么CSS变量动画在网络组件中不起作用
我使用实验 @property
功能成功创建了CSS变量动画。
document.addEventListener('DOMContentLoaded', () => {
const rangeInput = document.querySelector('#scale');
const htmlElement = document.querySelector('#html-element');
rangeInput.addEventListener('change', (e) => {
htmlElement.style.setProperty(
'--html-element-scale',
(e.target.value / 100).toFixed(2)
);
});
});
@property --html-element-background-color {
syntax: '<color>';
inherits: false;
initial-value: #00ff00;
}
@property --html-element-rotate {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
@property --html-element-scale {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
#html-element {
transform: rotate(var(--html-element-rotate))
scale(var(--html-element-scale));
border: 1px solid #000;
height: 100px;
width: 100px;
background-color: var(--html-element-background-color);
animation: anim 1s ease-in infinite alternate;
}
@keyframes anim {
100% {
--html-element-rotate: 180deg;
--html-element-background-color: #ff00ff;
}
}
<div id="html-element">HTML Element</div>
<div id="range-container">
<input
type="range"
id="scale"
name="scale"
min="0"
max="100"
value="100"
/>
<label for="scale">Scale</label>
</div>
但是,将其包装在Web组件中时,只有CSS值会更改,但是CSS VAR的值并未动画。此外,旋转不起作用,直到您更改比例滑块或AD AD a :host {-Html-元素尺度:1}
作为默认值...这很奇怪。
const html = `
<style>
@property --web-component-background-color {
syntax: '<color>';
inherits: false;
initial-value: #00ff00;
}
@property --web-component-rotate {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
@property --web-component-scale {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
#web-component {
transform: scale(var(--web-component-scale)) rotate(var(--web-component-rotate));
border: 1px solid #000;
height: 100px;
width: 100px;
background-color: var(--web-component-background-color);
animation: anim 1s ease-in infinite alternate;
}
@keyframes anim {
100% {
--web-component-rotate: 180deg;
--web-component-background-color: #ff00ff;
}
}
</style>
<div id="web-component">Web Component</div>
<div id="range-container">
<input type="range" id="scale" name="scale" min="0" max="100" value="100" />
<label for="scale">Scale</label>
</div>`;
customElements.define(
'web-component',
class WebComponent extends HTMLElement {
shadowRoot = this.attachShadow({ mode: 'open' });
constructor() {
super();
let template = document.createElement('template');
template.innerHTML = html;
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
const rangeInput = this.shadowRoot.querySelector('#scale');
const webComponent = this.shadowRoot.querySelector('#web-component');
rangeInput.addEventListener('change', (e) => {
webComponent.style.setProperty(
'--web-component-scale',
(e.target.value / 100).toFixed(2)
);
});
}
}
);
<web-component></web-component>
最后但并非最不重要的一点是,如果将样式表从Web-Component复制到常规DOM,以便Web-Component继承CSS,则可以再次工作。
问题是,由于功能的实验阶段,这是一个错误,还是我在Web组件中实现它做错了?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它看起来像
@property
定义在Web组件内无法使用。我不确定这是预期的还是错误的,我会将其报告为CSS-Houdini项目的问题。但是,如果您对工作版本只想使用全球定义的CSS变量进行动画感兴趣(在Web-Component的用例中非常有限)
It looks like
@property
definitions do not work inside of web-components. I'm not sure if this is intended or a bug, I will report it as an issue to the css-houdini project.However, if you're interested in what a working version would look like if you only want to use globally defined css variables for animations (which is quite limited in it's use case for a web-component)