用 padding-bottom + calc() 配合固定高度按钮是最直接有效的解法,需设 .list-container { padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px)); },60px 为按钮高度,env() 补齐 iPhone 底部安全区。
用 padding-bottom + calc() 配合固定高度按钮是最直接有效的解法,前提是按钮高度确定、不随内容动态变化。
因为 fixed 元素脱离文档流,浏览器滚动时不会为它预留空间,导致列表末尾内容被视觉覆盖——这不是“错位”,而是布局逻辑本就如此。常见于底部操作栏(如“加入购物车”“提交订单”)盖住最后一个 li 或 div.item。
在列表容器上加内边距,值等于按钮高度,并用 calc() 确保不被缩放或视口变化破坏:
.list-container {padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px));}
60px 是按钮的固定高度(需与实际 CSS 中 height 或 min-height 一致)env(safe-area-inset-bottom) 补齐 iPhone X 及后续机型的底部安全区(如 Home Indicator 区域)margin-bottom —— 它对父容器高度无贡献,滚动到底部时依然会被遮style.paddingBottom
这种场景更隐蔽:按钮在滚动到容器底端时“吸底”,但列表本身没撑开足够高度,导致最后一项被压住。此时关键不是留空,而是确保列表容器最小高度能容纳全部内容 + 按钮:
.list-wrapper {min-height: calc(100vh - 60px);}
100vh 是视口高度,减去按钮高,保证即使内容不足一屏,底部也有空间overflow-y: auto 在内部容器上,而不是整个页面,否则 sticky 失效vh 在地址栏展开/收起时的重绘 bug,可改用 dvh(100dvh)替代,但需检查兼容性真正麻烦的是按钮高度动态 + 安全区叠加 + 横竖屏切换三者共存的情况——这时候 padding-bottom 的静态值会失效,得监听 resize 和 orientationchange,用 JS 读取 getBoundingClientRect() 实时更新,但绝大多数业务场景,固定高 + calc() + env() 已经够用。