中必须嵌入才能在js禁用时加载css,否则页面白屏或错乱;它仅响应js被浏览器明确关闭,不处理js加载失败等场景,且必须置于中、路径与preload一致、依赖ssr/ssg输出首屏html。

<noscript></noscript> 本身不能“引入”CSS,它只在 JS 被明确禁用时生效;想让它加载样式,必须配合 <link rel="stylesheet"> 写在里面——否则用户看到的就是白屏或错乱页。
为什么 <noscript><link rel="stylesheet"></noscript> 不是可选项
Chrome、Firefox 等现代浏览器只要检测到 javascript.enabled === false(比如在 chrome://settings/content/javascript 关闭),就会跳过所有 <script></script> 标签,也不执行任何 JS 初始化逻辑。此时若没有 <noscript></noscript> 里的 <link>,页面就只剩空 ,连基础样式都没有。
- 它不处理 JS 加载失败、CSP 拦截、404 的
app.js—— 那些场景下<noscript></noscript>完全不触发 - 必须放在
中,且顺序要在rel="preload"之后、rel="stylesheet"之前(如果有的话) - 路径必须是绝对 URL 或确保能被 HTML 解析器直接解析的相对路径(不依赖 JS 运行时上下文)
<noscript></noscript> 里写 <link> 的常见错误
很多项目把 <noscript></noscript> 塞进 开头,或者跟在 JS 渲染容器后面(比如 <div id="app"></div>
<noscript>...</noscript>),结果 JS 禁用时整个 <div id="app"> 根本没生成,<code><noscript></noscript> 也被丢弃。
- ❌ 错误:
<div id="app"></div> <noscript><link rel="stylesheet" href="/css/main.css"></noscript>—— JS 禁用时<div id="app"> 不输出,<code><noscript></noscript>可能被忽略或未渲染 - ✅ 正确:
...<link rel="preload" href="/css/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="/css/main.css"></noscript> - 路径不一致会失效:preload 用
/css/main.css?v=1.2,<noscript></noscript>里写/css/main.css→ 浏览器当两个资源,降级加载的 CSS 不会被缓存复用 - 有效前提只有:服务端输出了首屏 HTML(SSR/SSG),比如 Next.js Pages Router、Nuxt Universal、Astro、Hugo
- 资源路径要兜底:构建后
/assets/logo.svg在 JS 禁用时大概率 404,建议改用data:image/svg+xml;base64,...或绝对 URL - 内容得真能用:不能写
<button onclick="submitForm()"></button>,得是<form method="post" action="/submit"><button type="submit"></button></form>
纯 CSR 项目里加 <noscript></noscript> 很可能白忙一场
像默认 Create React App、Vite + React Router 这类纯客户端渲染项目,初始 HTML 的 是空的,JS 一禁,HTML 解析器连 <noscript></noscript> 都没机会读到——页面直接白屏。
真正起效的不是标签写了几个,而是是否同时满足:SSR 输出、<noscript></noscript> 在 、路径完全一致、内容原生可用。漏掉任意一环,降级就只是个摆设。











