评论区表情面板被裁、切换还抖,原因在 overflow
Firefly 的评论区用的是 Waline。回复某条评论点开表情面板,弹层从输入框上方冒出来,结果下半截连同底部分类 tab 被主题的圆角卡片切了,只能看到半截。切分类时,表情网格和底下 tab 还会左右轻微挪一下,像在抖。
这俩看着像 Waline 的 bug,其实是主题样式的锅。我顺着 DOM 扒,根因全在 overflow 和布局尺寸上,修完提了上游PR#636 。
卡片被自己的 overflow 裁了
Waline 表情面板是绝对定位、浮在评论区之上。它祖宗链上有两层主题元素设了 overflow: hidden:评论卡片 #post-comments 和内容列。浮层要往纵向溢出内容列才能完整显示,可 hidden 把纵向也堵死了,下半截就被切。这不是 Waline 加的限制,是主题为了圆角裁剪在祖先上套的,属于自己裁自己。
我一开始想改 overflow: visible,但只能放纵向,横向还得裁——卡片有圆角装饰 SVG,横向不能溢出去把圆角撑破。然后栽了个跟头:overflow-x: hidden 配 overflow-y: visible 在浏览器里是非法组合。只要一个轴是 visible、另一个是 hidden/scroll/auto/clip 里任一非 visible 值,规范会强制把 visible 那轴降级成 auto,结果浮层还是被关进看不见的滚动容器,照样裁。
正确写法是 overflow-x: clip 配 overflow-y: visible——clip 只裁切、不生成滚动容器,不触发那条降级规则,也不影响列内 sticky 吸顶。我把卡片和内容列都改成这个组合,装饰性 SVG 背景挪到独立的 absolute inset-0 overflow-hidden 裁剪层,圆角交给那层,卡片本体只管放开纵向。
这活在老新架构上做法不一样。早一版主题内容列还叠了 onload-animation 的残留 transform,生成新层叠上下文把页脚抬到浮层之上,分类 tab 点不动,那版得给内容列加 z-20 压回去。后来上游重写主网格布局,页脚那层 transform 没了,层叠关系自然就对了,z-20 也就不需要了。我这次在新架构上改,没动 z-index。
切换分类时左右抖
抖的来源有两处:滚动条槽位和面板高度。
.wl-tab-wrapper 内容多时出现纵向滚动条,一出现挤掉约 6px 宽,里面的表情网格跟着重排,切到分类多的那组就晃一下。我给它加 scrollbar-gutter: stable,浏览器提前把滚动条槽位占住,有没有滚动条列宽都不变,网格就稳了。
另一处是高度。内容不足时网格区按内容收缩,比顶满矮 1px,切换时面板整体高低变一下,肉眼能觉出来在跳。我把 .wl-tab-wrapper 高度钉成 145px——这个数抄自 Waline 自身的 max-height,它内部对表情面板有这个上限,跟着对齐就不会出现钉太高反而比内容矮、或钉太矮内容被截。代价是它大版本改了 max-height,我这边的 145 得跟着改,属于手写耦合。
还有更隐蔽的:Waline 给选中 tab 加 0 1px 1px 边框(上 0、左右 1px、下 1px),激活的 tab 比未激活宽 2px、高 1px。切换时原来没边框的 tab 突然有了边框,相邻 tab 被顶着左右挪——这就是切换时左右抖最明显那一下。我给未选中 tab 补了条等宽透明边框 border: solid transparent; border-width: 0 1px 1px,占位尺寸统一了,切换时谁都不动。
这个面板是 Vue 渲染的,分类切换时 Waline 会销毁重建 .wl-tab-wrapper 节点。所以想在上面再加自定义(比如高亮常用表情、记上次选的分类),每次都得重新 query,不能缓存节点引用——缓存了拿到的是被 Vue 换掉的旧节点。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!











