CSS Transitions
撰写时间:2025-11-30
修订时间:2025-11-30
应用CSStransitions,可在我们指定的CSS属性值发生变化时,自动产生平滑的过渡效果。
注,本文各个例子仅显示核心代码,但均使用以下代码作为后台支撑:
color-scheme-iframe.js
const MEDIA_STR = '(prefers-color-scheme: light)';
function initIframe(partialSrcdoc) {
pc.appendInlineStyle(`
ul.pageconsole-output {
> li {
padding-left: 0em;
display: flex;
align-items: center;
> iframe {
border-width: 0px;
width: 100%;
}
}
}
`);
let iframe = document.createElement('iframe');
assembleSrcdoc(iframe, partialSrcdoc);
iframe.onload = (evt) => {
let doc = iframe.contentDocument;
applyColorScheme(doc);
handleColorSchemeChanged(doc);
autoHeight(iframe, doc);
appendResetBtn(doc);
doOnIframeLoaded(doc);
};
pc.appendChild(iframe);
}
function appendResetBtn(doc) {
let resetBtn = doc.querySelector('#reset');
if (!resetBtn) {
resetBtn = doc.createElement('button');
resetBtn.textContent = 'Reset';
resetBtn.onclick = () => {
doc.location.reload();
};
doc.body.appendChild(resetBtn);
}
}
function assembleSrcdoc(iframe, partialSrcdoc) {
let srcdoc = `
<style>
:root {
color-scheme: 'light dark';
}
body {
color: light-dark(#000, #ACB7C4);
background-color: light-dark(#FFF, #2B2B2B);
}
button {
margin: 1em 0;
padding: 0.7em;
border-radius: 0.3em;
border-width: 1px;
}
<<UI_STYLE_PART>>
</style>
<body>
<<UI_BODY_PART>>
</body>
`;
let uiStylePart = /<style>(.+)<\/style>/s.exec(partialSrcdoc)[1];
srcdoc = srcdoc.replace('<<UI_STYLE_PART>>', uiStylePart);
let uiBodyPart = /<body>(.+)<\/body>/s.exec(partialSrcdoc)[1];
srcdoc = srcdoc.replace('<<UI_BODY_PART>>', uiBodyPart);
iframe.srcdoc = srcdoc;
}
function autoHeight(iframe, doc) {
iframe.style.height = '0px';
iframe.style.height = `${doc.documentElement.scrollHeight}px`;
}
function getCurrColorTheme() {
let currColorTheme = localStorage.getItem('color-theme');
if (currColorTheme) {
return currColorTheme;
} else {
let themeStr = /\(prefers-color-scheme: (.+)\)/.exec(MEDIA_STR)[1];
if (matchMedia(MEDIA_STR).matches) {
return themeStr;
} else {
return themeStr === 'light' ? 'dark' : 'light';
}
}
}
function handleColorSchemeChanged(doc) {
matchMedia(MEDIA_STR).onchange = (evt) => {
applyColorScheme(doc);
};
window.addEventListener('color-scheme-changed', (evt) => {
applyColorScheme(doc);
});
}
function applyColorScheme(doc) {
let currColorScheme = getCurrColorTheme();
doc.documentElement.style.colorScheme = currColorScheme;
}
function doOnIframeLoaded(doc) {
}
基本用法
let partialSrcdoc = `
<body>
</body>
`;
initIframe(partialSrcdoc);
function doOnIframeLoaded(doc) {
doc.querySelector('button').onclick = () => {
let divElement = doc.querySelector('div');
divElement.style.width = '300px';
};
}
使用transition-property指定需要产生平滑过渡效果的CSS属性名,使用transition-duration指定平滑过渡的时间。
上面,按下按钮后,div的width属性值将从原来的100px变成300px,由于我们为其width属性设定了平滑过渡效果,则整个过程将在指定的时间内平滑地完成,从而产生平滑的动画效果。
同时指定多个属性
transition-property的值可为多个属性名,中间用,
号隔开。相对地,transition-duration的值也使用中间用,
号隔开。
let partialSrcdoc = `
<body>
</body>
`;
initIframe(partialSrcdoc);
function doOnIframeLoaded(doc) {
doc.querySelector('#change-value').onclick = () => {
let divElement = doc.querySelector('#demo');
divElement.style.width = '300px';
divElement.style.opacity = 0;
};
}
transition-timing-function
transition-timing-function用以设置动画开始、动画结束的速度。
let partialSrcdoc = `
<body>
</body>
`;
initIframe(partialSrcdoc);
function doOnIframeLoaded(doc) {
doc.querySelector('#change-value').onclick = () => {
let divElement = doc.querySelector('#demo');
divElement.style.width = '300px';
divElement.style.opacity = 0;
};
}
具体参见CSS Animations: animation-timing-function。
transition-delay
transition-delay指定隔多久后才开始动画。
let partialSrcdoc = `
<body>
</body>
`;
initIframe(partialSrcdoc);
function doOnIframeLoaded(doc) {
doc.querySelector('#change-value').onclick = () => {
let divElement = doc.querySelector('#demo');
divElement.style.width = '300px';
divElement.style.opacity = 0;
};
}
transition综合属性
语法:
transition: <single-transition>#
<single-transition> =
[ none | <single-transition-property> ] || <time> || <timing-function> || <time>
因为有2个动画时间,若只提供1个动画时间,则为transition-duration的值;若提供2个动画时间,第2个为transition-delay的值。
let partialSrcdoc = `
<body>
</body>
`;
initIframe(partialSrcdoc);
function doOnIframeLoaded(doc) {
doc.querySelector('#change-value').onclick = () => {
let divElement = doc.querySelector('#demo');
divElement.style.width = '300px';
divElement.style.opacity = 0;
};
}