<p>两列加margin后总宽超100%是因为margin不参与width计算,实际占用空间为50%+50%+20px;正确做法是用calc((100% - 20px) / 2)提前扣除间距。</p>
不是浏览器算错,而是 margin 本身不参与 width 计算。当你写 .col-1 { width: 50%; margin-right: 20px; } 和 .col-2 { width: 50%; },两列内容区加起来是 100%,但右侧多出的 20px 是额外叠加在外部的——实际占用空间 = 50% + 50% + 20px,必然溢出父容器。
常见现象包括:第二列被挤到下一行、水平滚动条意外出现、右侧按钮被截断。
box-sizing: border-box,子元素又带 padding 或 border,误差进一步放大float 却没清浮动,渲染顺序错乱导致宽度计算失准margin 隔开列,而没启用原生 gap
核心逻辑:把“间距”从总宽里提前扣掉,再平分剩余空间。假设两列间需 20px 水平间距,那每列宽度应为 (100% - 20px) / 2。
必须写成:width: calc((100% - 20px) / 2);
100% - 20px / 2 会被解析为 100% - 10px,不是你想要的calc((100% - 20px) / 2) ✅,calc((100%-20px)/2) ❌(IE9+ 会失效)padding: 12px 或 border: 1px solid,且希望视觉宽度严格对齐,需额外加 box-sizing: border-box
IE9–11 不支持 / 和 * 运算,calc((100% - 20px) / 2) 在这些环境里直接退化为无效声明,回退到 width: auto,布局完全崩坏。
max-width 限制,例如 width: 48%; max-width: 480px;
display: flex 替代 float 或 inline-block,并设 gap: 20px —— Flex gap 在 IE11 不支持,但现代浏览器已全覆盖;如真需兼容 IE11,可用 margin + :last-child { margin-right: 0; } 手动控制calc(calc(100% / 2) - 10px) 多数浏览器不认,纯属浪费调试时间calc() 能“算出一个数”,但它不会响应文字换行、图片加载失败、字体加载延迟等运行时变化。一旦某列内容撑开(比如长单词无断行、图片未设 max-width: 100%),整行就可能溢出,而 flex-wrap: wrap 或 grid-template-columns: repeat(auto-fit, minmax(...))) 会自动折行。
gap 是语义化的间距控制,它不侵占子项的 width,也不影响 box-sizing 行为,更易维护24px,你得手动改三处:两个 width 值 + 可能存在的 margin