Chrome 108这次更新搞了两处样式上的大变动,一个跟图片视频的溢出裁切有关,另一个是安卓手机上键盘弹窗时视口尺寸的计算方式变了。不少老项目直接翻车,圆角图片被裁成方块,全屏布局被键盘顶得乱七八糟。下面直接上硬核解决办法。
两处样式变更
替换元素(比如img、video、canvas)以前在Chrome里完全不搭理overflow这个属性,溢出就溢出,浏览器睁一只眼闭一只眼。从108版本开始,这些家伙突然“懂事”了,会严格按照样式表里写的overflow来干活。另一个变动发生在安卓Chrome的视口机制上——键盘弹出来的时候,布局视口不再缩水,只有视觉视口会动。
解决图片溢出问题
假设一张方形图片,想用border-radius: 50%切成圆形,以前就算图片内容超出了圆框,也会被自动裁掉。Chrome 108之后,因为overflow默认变成了clip(相当于给盒子装了个紧箍咒),超出圆框的部分直接消失不见,圆角效果看起来就像被狗啃过。
实操流程:
- 打开浏览器的开发者工具(F12),选中那个圆角图片元素,在样式面板里瞅一眼
overflow的计算值。如果是clip或者hidden,说明被新版默认行为坑了。 - 强制把溢出行为改回“可见”模式。写一段样式怼进去:
img.avatar {
border-radius: 50%;
overflow: visible; /* 这行是关键,让超出部分别藏起来 */
object-fit: cover; /* 配合cover让图片填满又不走形 */
}- 如果图片同时用了
object-fit: contain并且宽高比跟容器对不上,图片会产生留白区域,原本溢出的部分现在也可能被裁掉。这时候除了overflow: visible,还得检查父容器有没有设置overflow: hidden。比如一个视频列表页,每个视频卡片用了border-radius圆角,父级又设了overflow: hidden来清除浮动,那就妥妥翻车。得把父级的overflow也改成visible或auto。
.video-card {
border-radius: 12px;
overflow: visible; /* 子元素溢出别裁 */
}
.video-card .thumbnail {
overflow: visible;
object-fit: cover;
}- 还有一种情况是用了
all: inherit这种暴力继承写法,会把overflow属性也继承下来导致意外裁切。排查方法:在控制台运行getComputedStyle(img).overflow,看返回的是不是visible。如果不是,那就单独给这个图片写一条overflow: visible !important临时救急,但长期用还是得改继承逻辑。
一个小坑: 设了overflow: visible之后,图片溢出的部分会盖住旁边的文字或按钮,像个不守规矩的熊孩子。解决方法是给图片容器加个margin或者用clip-path代替border-radius来做裁剪。
解决视口错乱
安卓Chrome 108以前,键盘弹出来的时候,整个布局视口会往上缩,搞得100vh的高度变得跟手机屏幕实际高度对不上,固定定位的底部按钮也被键盘顶到不知道哪里去了。新版改了规则:布局视口大小不变,只有视觉视口变。这就导致键盘弹出来时,底部那些固定元素(比如输入框下方的发送按钮)可能会被键盘挡住。
实操流程(让元素乖乖待在键盘上方):
- 先判断当前浏览器是否支持新的动态视口单位(
dvh、svh、lvh)。Chrome 108已经支持了,Safari和Firefox也早就跟上。动态视口单位会根据键盘弹窗实时调整高度,比老掉牙的100vh靠谱得多。
.modal-bottom {
height: 100dvh; /* 动态视口,键盘弹出时自动缩到可用区域 */
position: relative;
}- 如果项目需要兼容老版本浏览器(比如Chrome 107及更早),用
-webkit-fill-available这个黑科技垫底。这套写法让元素占满键盘弹起后剩下的空间,而不是整个物理屏幕。
html {
height: -webkit-fill-available; /* 让html撑满剩余区域 */
}
body {
min-height: 100vh;
min-height: -webkit-fill-available; /* 降级方案,老浏览器忽略这行 */
margin: 0;
padding: 0;
}
.fixed-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #fff;
box-shadow: 0 -2px 8px rgba(0,0,0,0.1);
}- 对于完全不想被键盘影响的场景(比如全屏游戏画布),直接把
position: fixed的元素改成position: sticky或者用absolute配合dvh来模拟。举个例子:一个聊天输入框,希望键盘弹出来时输入框跟着上浮而不是被遮住。
<div class="chat-container">
<div class="messages">...</div>
<div class="input-area"> <!-- 这个区域要跟着键盘走 -->
<input type="text" placeholder="说点啥">
<button>发送</button>
</div>
</div>.chat-container {
display: flex;
flex-direction: column;
height: 100dvh; /* 动态高度,键盘弹起时容器缩小 */
}
.input-area {
margin-top: auto; /* 自动贴底,键盘弹出时会被推上来 */
background: #f5f5f5;
padding: 8px;
}- 实在不想折腾新单位,还有一个老办法:监听键盘的
resize事件,动态计算可用高度。不过这套方案性能差,不如直接用dvh干净利落。
window.visualViewport.addEventListener('resize', () => {
const viewportHeight = window.visualViewport.height;
document.querySelector('.dynamic-area').style.height = viewportHeight + 'px';
});注意这个骚操作: -webkit-fill-available在Chrome 108上依然有效,但未来的版本会不会移除没人打包票。最稳妥的姿势是同时提供dvh和-webkit-fill-available两套样式,让浏览器自己选能用的那个。
快速自检清单
| 场景 | 症状 | 修复代码 |
|---|---|---|
| 圆角图片被裁 | 圆形变方形 | overflow: visible |
| 键盘挡住按钮 | 底部栏消失 | height: 100dvh |
| 视频超出被切 | 画面不全 | video { overflow: visible } |
| 全屏布局错位 | 滚动异常 | min-height: -webkit-fill-available |
最后提醒一下,改完样式记得在真实手机(不是模拟器)上测一遍键盘弹起和图片圆角的表现。Chrome 108这波操作虽然坑了不少老项目,但只要把overflow和视口单位这两块拿捏住,页面照样稳如老狗。
