全局样式必须写在<head>里,HTML规范强制要求;<style>放<body>中不会被解析为有效样式,导致样式失效、层叠失效及响应式查询被忽略。

全局样式必须写在 <head> 里,不是“建议”,是 HTML 规范强制要求;写到 <body> 里的 <style> 根本不会被解析为有效样式上下文。
为什么 <style> 放在 <body> 里会失效
浏览器只在 <head> 内解析 <style> 为样式规则。一旦塞进 <body>(哪怕紧贴开头),body { margin: 0; } 不生效、自定义类不匹配、@media 查询被忽略——这不是兼容性问题,是规范层面的否定。
- 第三方 SDK 注入的按钮样式调不动?很可能它的
<style>在<head>末尾,而你的在<body>开头,压根没参与层叠 - 动态插入时务必用
document.head.appendChild(styleEl),别 append 到document.body - 多个
<style>共存时,顺序即优先级:后写的同选择器规则覆盖前面的
* { box-sizing: border-box; } 是高危操作
它看似统一盒模型,实则无差别打穿所有元素,包括 Ant Design、Element Plus 等 UI 库内部已精细控制的结构。典型表现:表单控件高度塌陷、卡片 padding 错位、折叠面板展开后内容溢出。
- 更安全的写法是限定作用域:
.template-root * { box-sizing: border-box; } - 或分层继承:
html { box-sizing: border-box; }+*, *::before, *::after { box-sizing: inherit; } - 若项目用 rem 布局,必须确认
html { font-size: 16px; }存在,否则body { font-size: 14px; }会导致所有 rem 计算偏移
基础重置不能只清 body 的 margin
body { margin: 0; } 只解决最表层,<h1>、<p>、<ul>、<pre> 等自带用户代理样式的元素仍各自留白,造成视觉断层。
立即学习“前端免费学习笔记(深入)”;
- 推荐模板级基础重置组合:
*, ::before, ::after { margin: 0; padding: 0; border: 0; } -
ul, ol { list-style: none; }—— 清掉<ul>前的小黑点 img { display: block; max-width: 100%; height: auto; }-
input, button, select, textarea { font: inherit; }—— 防止表单控件字体脱节 - 慎用
all: unset:它会清掉font-family、color等关键继承属性,补全成本远高于收益
外部样式表才是真·统一管理的核心
把样式写进 <style> 标签再复制到每个页面,本质还是人工同步,极易漏改、错改。真正可靠的是外部 CSS 文件 + 构建时注入或服务端模板继承。
- Vite 用户用
vite-plugin-html,支持<!-- @include ./components/header.css --> - Webpack 用户配合
html-loader+html-webpack-plugin,可require('./common.css') - 服务端模板(Jinja2/Twig)用
{% block css %}{% endblock %}分离公共与页面专属样式 - 路径必须相对构建根目录,不是相对于当前 HTML 文件
- 避免 SSI(
<!--#include file="header.css" -->):本地开发无法预览,且无法传参或条件渲染
最难的从来不是“怎么让样式出现在每个页面”,而是“当设计改了字体大小、导航加了新菜单项、页脚要动态显示版权年”,你能不能在一处改完,全站自动生效——这取决于你从第一天就选对了样式组织方式,而不是靠后期缝合。



















