正确:<frameset>与<body>互斥,二者不能共存于同一HTML文档中;浏览器解析时若遇<frameset>会忽略<body>内容,且<frameset>必须作为<html>的直接子元素。

HTML <frameset> 已被 HTML5 废弃,现代项目中不应使用;若维护旧系统,必须注意它与 <body> 互斥、无响应式能力、SEO 不友好等硬伤。
为什么 <frameset> 不能和 <body> 共存
浏览器解析时遇到 <frameset> 就会忽略后续所有 <body> 内容——哪怕你写了 <body><h1>Hello</h1></body>,只要前面有 <frameset>,这部分就完全不渲染。
常见错误现象:Uncaught DOMException: Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is opened with document.open()(其实是页面结构错乱导致脚本执行环境异常)。
-
<frameset>必须作为根元素直接放在<html>内,且 不能嵌套在<body>中 - 如果用了
<frameset>,整个页面就不能写<body>标签,否则是无效 HTML - 替代方案:用
<iframe>+ CSS Grid/Flexbox 模拟多窗格,保留语义和可访问性
cols 和 rows 的实际计算逻辑
两者不是“百分比优先”,而是按字符串顺序逐项解析,* 是占位符,代表“剩余空间”,不是通配符。
例如:<frameset cols="20%,30%,*"> 表示:第一列占视口宽度 20%,第二列占 30%,第三列占剩下 50%;但 <frameset cols="20%,*,30%"> 会出问题——因为 * 出现在中间,浏览器无法确定“剩余”从哪算起,部分老浏览器会忽略第三项或强制重排。
-
cols值中多个*等分剩余空间,如"*,*,*"→ 三等分 - 像素值(如
"150,*,200")优先级高于百分比,150px固定,200px固定,中间自适应 -
rows同理,但注意:高度单位不支持vh或em,只认%、px、*
frame 的 name 和 target 必须严格匹配
这是实现“左栏导航、右栏加载”的唯一通信机制。不设 name,<a target="xxx"> 就找不到目标框架,链接会在当前窗口跳转,破坏布局。
典型错误:在 <frame src="nav.html"> 上漏写 name="menu",却在 nav.html 里写 <a href="content.html" target="main"> ——结果 target="main" 找不到对应 <frame name="main">,浏览器新开标签页。
-
<frame name="right">和<a target="right">的字符串必须**完全一致(区分大小写)** - 避免用纯数字或特殊符号做
name,如name="1"或name="frame-1",某些 IE 版本解析异常 - 若需默认加载某页,把该
<frame>的src设为目标 URL,而非依赖 JS 注入
边框、滚动条、缩放控制的实际效果
frameborder 和 scrolling 是视觉关键属性,但行为不统一:Chrome 和 Firefox 对 frameborder="0" 渲染一致,但 IE 可能仍留 1px 灰线;scrolling="no" 在内容溢出时可能被忽略。
-
frameborder="0"或frameborder="no"都有效,但frameborder="false"无效 -
scrolling="auto"(默认)在内容超框时才显示滚动条;"yes"强制显示,"no"强制隐藏(可能造成内容不可见) -
noresize属性让框架不可拖拽调整大小,但仅对用户鼠标操作生效,JS 仍可通过window.frames[i].location控制内容 -
<frameset framespacing="0" bordercolor="#fff">可进一步弱化分割线感,但无法彻底消除跨浏览器差异
真正麻烦的不是怎么写,而是当某个 <frame> 加载失败(404 或 CORS),整个 <frameset> 页面会卡住、空白、或只显示部分框架——这种故障难以捕获,也没有 onerror 事件可用。

















