使用 scrollbar-gutter CSS 属性解决由滚动条引起的不必要的布局偏移

本文介绍了CSS的新特性`scrollbar-gutter`,用于解决经典滚动条在网页布局中占据空间导致的布局变动问题。经典滚动条会挤压内容区域,而`scrollbar-gutter: stable`可以确保滚动条出现时不会改变布局,因为它预留了滚动条的空间。此外,`scrollbar-gutter: both-edges`可以实现两端对齐的布局。该特性目前仅在Chromium88+支持,并且需要开启实验性功能。通过使用`scrollbar-gutter`,开发者可以创建更稳定的滚动体验,避免滚动条对页面布局的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

当我们在web页面上显示滚动条的时候,会有一个问题就是滚动条展示的时候会影响到我们页面的布局,scrollbar-gutter CSS属性可以帮开发人员更好的解决这个问题。

接下来我们一起看下怎么解决~

👨‍🔬 本文中描述的 CSS 功能目前仅在 Chromium 88+ 中支持,并且通过 chrome://flags 启用了 #experimental-web-platform-features 标志。
💥 为了保证 Chromium 安装干净,建议您不要在 Chromium Stable 中设置此标志,建议使用 Beta / Canary 版本。

正文

Classic vs Overlay Scrollbars

在我们开始之前,我们先来区分两种类型的滚动条:经典滚动条覆盖滚动条

### Classic Scrollbars:经典滚动条是放置在所谓的“Scrollbar Gutter”中的滚动条。 Scrollbar Gutter 是内边框边缘和外填充边缘之间的空间。对于经典滚动条,Scrollbar Gutter 的大小与滚动条的宽度相同。这些滚动条通常是不透明的,并从相邻的内容中占用一些空间。


图解:经典滚动条是从相邻内容中占用了一些空间。

### Overlay Scrollbars:覆盖滚动条是那些放置在内容上的 iOS/macOS 风格的滚动条。它们默认是不显示的,仅在用户滚动时显示。为了保持滚动条下面的内容可见,因此滚动条是半透明的,滚动条样式取决于当前浏览器来确定,滚动条的大小也可能会有所不同。

image


图解:覆盖滚动条是放置在内容上的。

🍏 macOS 的用户可以通过系统偏好设置从覆盖切换到经典滚动条~

问题

当页面结构框的内容变得太大时(例如当它溢出时),默认情况下浏览器将显示一个滚动条。在经典滚动条的情况下,这有一个令人讨厌的副作用:由于滚动条需要一些空间,内容的可用宽度会缩小,因此布局也会发生变化。

image


当内容增加时,滚动条就会出现了!

☝️ 当设置成覆盖滚动条时,就不会有布局转换,因为这些滚动条会在内容上呈现。

解决方案

scrollbar-gutter: stable 就可以解决上述问题 ……

通过将 scrollbar-gutter 设置为 stable 我们可以让 UA 始终显示 Scrollbar Gutter。当结构框中的内容没有溢出时则不显示滚动条。这样我们就有了一个视觉上稳定的布局:当盒子开始溢出时,滚动条将被渲染,但不会发生布局移位,因为这时它的空间已经被保留了。

image


图解:当滚动条显示时,内容不会移动,因为浏览器已经为滚动条装订线保留了空间。

需要注意的是,scrollbar-gutter 属性对滚动条本身的渲染没有影响——它只影响 gutter 的渲染。滚动条的呈现是通过溢出属性控制。

scrollbar-gutter 的默认值是 auto,设置为auto后,行为与问题中描述的行为没有变化。

scrollbar-gutter: stable both-edges可以设置布局两端对齐。

image


图解:滚动条显示的时候,内容也不会移动。除此之外,在相对的边缘也保留了相同的相同宽度的空间。

注意事项

  1. 对于 overflow属性, scrollbar-gutter是通过将滚动条应用于视口替代在根元素上设置滚动条。
  2. 与 overflow 属性不同,浏览器不会从 HTML body 元素传播 scrollbar-gutter

浏览器支持

image

总结

使用 scrollbar-gutter 我们可以防止由滚动条引起的一些不必要的布局更改。

下图总结了本文中涵盖的场景:

image

### 解决 Element UI `el-table` 打印时滚动条内容不全的问题 为了确保 `el-table` 在打印时能够完整展示所有内容,可以采取以下几种策略: #### CSS 调整 通过调整 `.el-table__body-wrapper` 和其他相关类的样式来确保在打印模式下不会因为滚动条的存在而影响布局。具体做法如下: ```css @media print { .el-table__body-wrapper { overflow: visible !important; } /* 移除滚动条 */ .el-table__body-wrapper::-webkit-scrollbar { display: none; } /* 防止因移除滚动条导致的内容偏移 */ .el-table th.gutter, .el-table colgroup col[name='gutter']{ display: table-cell!important; width: auto!important; } } ``` 上述代码片段利用了媒体查询,在仅限于打印的情况下应用特定样式[^1]。 #### JavaScript 动态处理 如果单纯依靠CSS无法解决问题,则可以在页面准备打印前动态调整表格的高度或宽度,使其适应纸张大小。这可以通过监听窗口上的 `beforeprint` 事件实现: ```javascript window.addEventListener('beforeprint', function() { const bodyWrapper = document.querySelector('.el-table__body-wrapper'); if (bodyWrapper) { // 假设最大高度为A4纸一页的高度减去表头部分 let maxHeightForPrint = '792px'; // A4 paper height in pixels minus header space // 设置固定的最大高度以防止溢出 bodyWrapper.style.maxHeight = maxHeightForPrint; // 如果有分页器,也需要相应设置其可见性或其他属性 const paginationElement = document.querySelector('.el-pagination'); if(paginationElement){ paginationElement.style.display = "none"; } // 可选操作:隐藏不必要的元素如工具栏按钮等... } }); // 还原状态 window.addEventListener('afterprint', function() { const bodyWrapper = document.querySelector('.el-table__body-wrapper'); if(bodyWrapper){ bodyWrapper.style.maxHeight = ''; } }); ``` 这段脚本会在浏览器即将执行打印命令之前自动调整表格容器的高度,并且在完成打印后恢复原始样式[^3]。 #### 使用插件辅助 对于更复杂的需求,考虑引入专门用于优化网页打印体验的第三方库,比如 `html-to-image` 或者 `jsPDF` 结合 `html2canvas` 来生成 PDF 文件供用户下载而不是直接调用浏览器自带的打印功能。这种方法能更好地控制最终输出的质量和格式[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值