其实这个问题来源于吸顶的实现。CSS中定位使用sticky属性,可以直接实现吸顶效果。参考sticky headings。但是好事多磨,较低版本的Android并不支持。而fixed属性在iOS上又有一些问题,所以面对这个需求,采用了判断env的方法,iOS用sticky,Android用fixed,基本可以完美实现。尽管写起来并不太开心,因为对于fixed还要监听滚动事件。

其实也还好,人要知足,这需求只要兼容iOS和Android,不需要考虑IE的。但是问题来了,开发的时候还是要用Chrome的,在Chrome上会发现吸顶后上面有1px的缝隙。

但是吧,我在iPhone上测试没有任何毛病,所以就没太关心这个bug,反正这个网页是放在app里的,不支持浏览器打开。直到,我的leader用他的Android手机打开这个页面,复现了!好端端的怎么就复现了呢?讲道理我是判断了env,Android会自动fixed,不会有这种问题。他说他的手机支持Chromium的内核,版本还挺新。所以不得不去解决。

不过呢,这是一个非常小的细节,并且我还有别的事情要做,就先搁置了。那个「别的事情」就是要优化一下图片加载闪动的问题,提前给图片占位。由于后端给的图片尺寸确定,所以我写死了高度。居然,sticky的1px问题也没了。我反复调试了一下,确实是因为我给它上面的图片写了高度。

尽管我已经解决了问题,但是!

喵喵喵?

感觉像是Chrome没有计算好文档流中前序元素的高度,所以我打开CodePen,也就是文章开头的链接。确实如此,我把前面的h1标签删掉就好了,或者改成一个普通的div也没问题。由此可以认为,这是Chrome自己的处理出了瑕疵,起码不是我的锅了。我测试了Safari on macOS没毛病,Safari on iOS没毛病,wkwebview没毛病,只有Chrome和Chromium for WebView有这个问题。

然后我在爆栈网上看到了类似的问题,没什么回答,就把自己的踩坑过程写了上去Stack Overflow

顺便去Chromium上搜了一下,14小时前有人问过一样的问题…… Chromium,于是我在评论里也吐槽了一把。

解决方案就是在Chromium内核里尽量不用这个属性,以避免遇到这种诡异bug。如果必须要用,或者兼容使用时为了保险,可以尝试在sticky元素的上方元素中调试,比如使用div,写死高度等随缘调试法。