Chrome 108来了,图片裁切和视口错乱咋解决?

2,966字
13–19 分钟
in

Chrome 108这次更新搞了两处样式上的大变动,一个跟图片视频的溢出裁切有关,另一个是安卓手机上键盘弹窗时视口尺寸的计算方式变了。不少老项目直接翻车,圆角图片被裁成方块,全屏布局被键盘顶得乱七八糟。下面直接上硬核解决办法。

目录

两处样式变更

替换元素(比如imgvideocanvas)以前在Chrome里完全不搭理overflow这个属性,溢出就溢出,浏览器睁一只眼闭一只眼。从108版本开始,这些家伙突然“懂事”了,会严格按照样式表里写的overflow来干活。另一个变动发生在安卓Chrome的视口机制上——键盘弹出来的时候,布局视口不再缩水,只有视觉视口会动。

解决图片溢出问题

假设一张方形图片,想用border-radius: 50%切成圆形,以前就算图片内容超出了圆框,也会被自动裁掉。Chrome 108之后,因为overflow默认变成了clip(相当于给盒子装了个紧箍咒),超出圆框的部分直接消失不见,圆角效果看起来就像被狗啃过。

实操流程:

  1. 打开浏览器的开发者工具(F12),选中那个圆角图片元素,在样式面板里瞅一眼overflow的计算值。如果是clip或者hidden,说明被新版默认行为坑了。
  2. 强制把溢出行为改回“可见”模式。写一段样式怼进去:
img.avatar {
  border-radius: 50%;
  overflow: visible;  /* 这行是关键,让超出部分别藏起来 */
  object-fit: cover;  /* 配合cover让图片填满又不走形 */
}
  1. 如果图片同时用了object-fit: contain并且宽高比跟容器对不上,图片会产生留白区域,原本溢出的部分现在也可能被裁掉。这时候除了overflow: visible,还得检查父容器有没有设置overflow: hidden。比如一个视频列表页,每个视频卡片用了border-radius圆角,父级又设了overflow: hidden来清除浮动,那就妥妥翻车。得把父级的overflow也改成visibleauto
.video-card {
  border-radius: 12px;
  overflow: visible;  /* 子元素溢出别裁 */
}
.video-card .thumbnail {
  overflow: visible;
  object-fit: cover;
}
  1. 还有一种情况是用了all: inherit这种暴力继承写法,会把overflow属性也继承下来导致意外裁切。排查方法:在控制台运行getComputedStyle(img).overflow,看返回的是不是visible。如果不是,那就单独给这个图片写一条overflow: visible !important临时救急,但长期用还是得改继承逻辑。

一个小坑: 设了overflow: visible之后,图片溢出的部分会盖住旁边的文字或按钮,像个不守规矩的熊孩子。解决方法是给图片容器加个margin或者用clip-path代替border-radius来做裁剪。

解决视口错乱

安卓Chrome 108以前,键盘弹出来的时候,整个布局视口会往上缩,搞得100vh的高度变得跟手机屏幕实际高度对不上,固定定位的底部按钮也被键盘顶到不知道哪里去了。新版改了规则:布局视口大小不变,只有视觉视口变。这就导致键盘弹出来时,底部那些固定元素(比如输入框下方的发送按钮)可能会被键盘挡住。

实操流程(让元素乖乖待在键盘上方):

  1. 先判断当前浏览器是否支持新的动态视口单位(dvhsvhlvh)。Chrome 108已经支持了,Safari和Firefox也早就跟上。动态视口单位会根据键盘弹窗实时调整高度,比老掉牙的100vh靠谱得多。
.modal-bottom {
  height: 100dvh;  /* 动态视口,键盘弹出时自动缩到可用区域 */
  position: relative;
}
  1. 如果项目需要兼容老版本浏览器(比如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);
}
  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;
}
  1. 实在不想折腾新单位,还有一个老办法:监听键盘的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和视口单位这两块拿捏住,页面照样稳如老狗。