最稳妥方案是用body::before伪元素:设position: fixed、transform: translate(-50%,-50%) rotate(-30deg)、color: rgba(0,0,0,0.08)、z-index: -1、pointer-events: none,并确保body有position: relative且content带引号。

index.html 里加水印,不是往 HTML 标签上写个属性就能生效的事——浏览器根本不认识 watermark 这种标签,所有“水印”都是靠 CSS 层叠或 JS 动态绘制模拟出来的视觉效果。真要覆盖全页、不被滚动截断、不影响点击,必须用对定位方式和渲染层。
用 body::before 伪元素实现最轻量全屏水印
这是唯一不依赖 JS、兼容 IE9+、上线最快的方式,适合内部系统或低敏感内容。
关键点不在“画”,而在“固定 + 居中 + 不挡事”:
-
position: fixed是硬性要求,absolute会被局部滚动容器(比如overflow: auto的 div)截断,水印只出现在局部区域 -
transform: translate(-50%, -50%) rotate(-30deg)必须一起用:只写top: 50%; left: 50%再加rotate,文字会绕左上角旋转飞出屏幕 -
z-index: -1要生效,得先给body加position: relative,否则负值可能被忽略 -
pointer-events: none必须写,否则用户点不到底下的按钮、输入框、下拉菜单 -
content值必须是带引号的字符串,比如content: "内部使用";写成content: 内部使用(没引号)或空值,伪元素直接不渲染
示例 CSS(可直接塞进 index.html 的 <style> 块里):
立即学习“前端免费学习笔记(深入)”;
body {
position: relative;
}
body::before {
content: "张三 - 20260610";
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: translate(-50%, -50%) rotate(-30deg);
font-size: 48px;
color: rgba(0, 0, 0, 0.08);
z-index: -1;
pointer-events: none;
user-select: none;
}用 canvas 动态绘制水印并设为背景图
当你要嵌入用户 ID、时间戳、IP 哈希等动态内容,或者想提高删除门槛(不能靠删 DOM 节点就干掉),就得走 Canvas 路线。
它不是“画一次就完”,而是把 canvas 绘制成一张 base64 图,再赋给 body.style.backgroundImage,本质是换了个更难删的背景图:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- canvas 宽高至少设为
window.innerWidth * 2和window.innerHeight * 2,否则平铺时接缝明显 -
ctx.fillText()字体大小必须用固定单位(如24px),别用rem或vw,缩放页面时文字会突变 - 旋转角度建议 -25° 到 -35° 之间:太小看不出斜纹,太大干扰阅读
- 透明度控制在
0.08–0.12:再低肉眼难辨,再高影响内容可读性 - 网格间距(spacing)设 100–150px:太密性能差,太疏中间留白
注意:toDataURL() 在跨域图片上会抛 SecurityError,必须提前设置 img.crossOrigin = 'anonymous',且该行必须写在 img.src = ... 之前。
为什么不能用 background-image: url(...) 直接平铺 PNG?
能用,但容易踩坑:
- 如果用普通 PNG,高分屏上会模糊;推荐用 Base64 编码的 SVG:
background-image: url("data:image/svg+xml,%3Csvg%3E..."),缩放不失真 -
background-attachment: fixed让水印相对视口固定(滚动时不动);若设为scroll,水印会随内容一起滚,观感像“贴在文字上”,失去覆盖感 - 别依赖
opacity控制整体透明度——它会让整个背景(包括水印和底色)一起变淡;透明度应在 SVG 或 PNG 文件里预设好 - 图片尺寸建议从 200×100px 起步,太小(如 100×50px)在 Retina 屏上显颗粒感
打印时默认照常渲染水印,用户 Ctrl+P 就能输出带水印的 PDF。如需隐藏,得在 @media print 里重置:body::before { display: none; }。
真正难的不是“怎么加”,而是“加在哪一层”
前端水印没有法律效力,审查元素删节点、禁用 JS、改 CSS —— 全都能绕过。你写的每个字都在用户浏览器里运行,不是服务器。
判断层级的关键是风险等级:
- 内部文档预览页:CSS 伪元素够用
- 客户登录后看到的报表页:Canvas + 用户 ID + 时间戳,会话级绑定
- 商业授权内容、PDF 下载源、版权敏感图:必须服务端预处理,把水印像素级写进文件,连 EXIF 都带上元数据
最容易被忽略的是打印场景和跨域图片加载时机——这两处一出错,水印要么糊成一片,要么干脆不出现。


















