动态创建并插入标签加载css最直接,需挂载到才生效;可监听onload/onerror处理状态;insertrule()适合注入少量样式;用预设class配合onload可缓解fouc。

动态创建 <link> 标签并插入 DOM
最直接的方式是用 JavaScript 创建 <link> 元素,设置 rel="stylesheet" 和 href,再插入到 中。浏览器会立即发起请求并应用样式。
关键点:
-
link必须在插入 DOM 后才开始加载,不能只创建不挂载 - 推荐插入到
末尾,避免阻塞渲染(相比开头更安全) - 插入前可检查是否已存在同名样式表,避免重复加载
function loadCSS(url) {
if (document.querySelector(`link[href="${url}"]`)) return;
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
}
loadCSS('/styles/theme-dark.css');
监听 link.onload 和 link.onerror 处理加载状态
样式表加载是异步的,但 <link> 元素支持 onload 和 onerror 事件(现代浏览器均支持,IE9+)。不能依赖 onload 来判断样式“已生效”,因为样式计算和重排可能稍有延迟。
常见误用:
立即学习“Java免费学习笔记(深入)”;
- 把
onload当作“样式已就绪可操作 DOM”的信号 —— 实际上此时 CSSOM 可能刚构建完,但未参与渲染流程 - 忽略
onerror,导致 404 样式表静默失败,UI 异常无提示
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = '/styles/animation.css';
link.onload = () => console.log('CSS loaded');
link.onerror = () => console.error('Failed to load CSS:', link.href);
document.head.appendChild(link);
用 CSSStyleSheet.insertRule() 动态注入规则(无需网络请求)
如果只是追加少量样式(比如主题色、响应式断点调整),比加载外部文件更快更可控。需先获取或创建一个 CSSStyleSheet 对象。
注意兼容性细节:
-
document.styleSheets是只读类数组,但可通过document.styleSheets[i].insertRule()修改已有表 - 新建
<style></style>并插入 DOM 是最兼容方式;CSSStyleSheet构造函数(new CSSStyleSheet())仅在 Chrome 85+/Firefox 94+ 支持 -
insertRule()的第二个参数是插入位置索引,传0表示最前,省略则默认追加到末尾
const style = document.createElement('style');
document.head.appendChild(style);
const sheet = style.sheet;
sheet.insertRule('.btn { background: #007bff; }', 0);
sheet.insertRule('.btn:hover { opacity: 0.8; }');
避免 FOUC 和样式闪烁的时机控制技巧
动态加载 CSS 最容易暴露的问题是 FOUC(Flash of Unstyled Content):页面先按无样式渲染,样式到位后突然跳变。这不是 JS 能完全消除的,但可以缓解。
有效做法:
- 在
或上预先加一个 class(如loading-css),初始 CSS 隐藏关键区域或设占位样式 - 在
link.onload触发后移除该 class,并可配合requestAnimationFrame确保样式应用后再操作 DOM - 慎用
link.disabled = true控制启用时机 —— 它只禁用样式应用,不中断下载,且 IE 不支持
真正难处理的是跨域样式表(Cross-Origin)的 onload 事件不可靠,此时只能靠定时检测 document.styleSheets 长度或尝试读取规则数量(受限于 CORS 策略),实际项目中应尽量避免跨域 CSS 动态加载。










