问题
最近工作写了个 H5 应用,本地、测试和正式环境都没啥问题,直接发版~
嗯,然后就出问题了。有位大佬,用着18年的手机点开了应用。首页内容很长,好家伙,内容全部揉在了一块。真真是首屏展示全部。。。
期初我以为是懒加载的问题,可能机型比较老,不支持 IntersectionObserver,直接换成滚动懒加载,还是不行,我凌乱了。。。
排查
由于手机是人家大佬自己的,不可能给我测试用,我们这边也没有能复现的机型,给我整不会了。
既然是老机型,那一定是版本问题呗。打包降级,从 js 到 css,各种打包降级,还是不行。。。没办法,必须找能复现的设备了。
我先试了 android studio 的虚拟机,它还连不上本地网络,之前也没连过,都是写 android 才用,也用不到这种情况,放弃~
苦思冥想之际,我突然想起来,我寻思着找个老版浏览器。想法确实简单,但之前一直被 寻找老旧机型 的思维困住,这一跳出来,还真是如梦初醒。赶紧上网下了个老版的 Chrome。具体下载方法:
下好后,打开,啊哈,复现了。那就确定就是版本迭代问题了。
定位
接下来,就是看是哪里出现了问题,既然数据全部已经渲染,只是样式不对,那大概率应该是 CSS 问题。在有问题的元素上一个一个属性点吧
我复现了一个样例:
最上面大标题是文字自动撑开的,包含了 padding 和 margin,每一个色块(代表真实环境中的每一个具体组件内容)我设置了 200px
的高度,右边是用最新的浏览器打开的,可以正常显示。左边是用老浏览器打开的,它已经挤到了一起。
看到这里,其实已经大体发现问题了。我整个页面用的 display:flex;flex-direction: column
布局,它一定是在哪里出现了自适应。
因为我在最外面使用了高度固定,这样才能往下滚动嘛,所以内部元素一定出现了自适应缩放。果不其然,我在每一个色块中使用了 flex:1
属性。但奇怪的是在新版浏览器中没有任何问题。
当我把它改为 flex: 1 0 auto
后,一切正常了。
原因
同样的代码,在不同版本的浏览器中显示效果有很大差别,这让我很困惑。
查了 w3 flex-shrink,它的默认值就是1,所以如果我们需要正常展示的话,需要手动改变它的属性,也就是 flex-shrink: 0
或者 flex: 1 0 auto
这样的显式声明。
那么问题来了,为啥新版浏览器可以按照我们 预想 的那样展示呢?
这里有一个 stackoverflow 的帖子,说的很详细。
浏览器厂商根据用户习惯,做了强行干预,并把这种 内部元素设定了高度,并且超过容器时,flex 布局强行对内部元素进行缩放 当成了一个 bug,并且这个问题在 Chrome 72(released in January 2019)
中修复。
修复 原文 如下:
When flex items are too big to fit inside their container, those items are instructed (by the flex layout algorithm) to shrink, proportionally, according to their flex-shrink property. But contrary to what most browsers allow, they're not supposed to shrink indefinitely. They must always be at least as big as their minimum height or width properties declare, and if no minimum height or width properties are set, their minimum size should be the default minimum size of their content.
所以,在设置了高度的时候,自动溢出滚动而不缩放成了一种潜规范,这也就导致我们在写代码时已经逐渐忽略了这点,甚至以为它应该就这样。
最后
这个问题,我觉得就是浏览器了解用户需求,把一些反设计的设定进行强行干预,目的是对我们开发者更加友好。这也才有了已经逐渐忘记这些形形色色的属性原本的设计,让我们各种 踩坑。
随着各种工具越来越智能,我们写业务代码基本上已经不动脑子了。但是我们仍然需要知其然,才能知其所以然。这样才能站在 AI 的肩膀上前进,而不是让 AI 站在我们的脑袋上。
文章评论