2
头图
个人公众号「志语自乐」《“IE6” 在 iOS 中复活了》https://mp.weixin.qq.com/s/fDg9BobyA5jJQBVDezVa7A

没用的知识点

这个标题有点标题党的感觉,不过就我个人感受,iOS 中的 Safari 这次的表现真的让我想到了当年的 IE6/7 的感觉。要说为什么呢,主要是让我想到了 hasLayerout 这个词。很多年没见过这个词,也没有人提到这个词了。在 Poe 中问了一下「在浏览器中有一个叫 hasLayerout 的是什么」这个问题,Ta 的回答是这样的:

在浏览器中,"hasLayout" 是一个特定的概念,它与早期版本的 Internet Explorer(IE)浏览器相关。

在 IE 浏览器中,"hasLayout" 是一个用于描述元素布局和渲染行为的属性。它是一个非标准的属性,只在 IE 浏览器中存在。"hasLayout" 属性影响元素的盒模型、浮动、定位和清除浮动等方面。

当元素具有 "hasLayout" 属性时,它会触发一些特定的布局规则,导致元素的渲染行为与其他元素有所不同。例如,当一个元素具有 "hasLayout" 属性时,它可以包含浮动元素,而不会发生高度塌陷的问题。

在 IE 浏览器中,触发 "hasLayout" 属性的方式有多种,包括以下几种常见的情况:

  1. 设置元素的 zoom 属性为非默认值,例如 zoom: 1
  2. 元素具有特定的 CSS 属性,如 position: absolutefloat: leftdisplay: inline-block 等。
  3. 元素具有特定的 CSS 伪类,如 :before:after

需要注意的是,"hasLayout" 属性只在早期版本的 IE 浏览器中存在,对于现代的主流浏览器(如 Chrome、Firefox、Safari),该属性并不适用。开发者应该避免在现代 Web 开发中依赖或使用 "hasLayout" 属性。

在上面提到的触发条件中,有一个非标准的 CSS 属性 zoom。是的,这次一个问题就是因为这个属性触发的。

背景

了解了一点没用的知识点后,再说一下遇到的现象。

手上的一个项目是移动端的,然后需求是可以让用户设置字体大小,并运用到整个项目中。处理方式其实很简单,只要放大就可以了。并不需要去考虑什么 rem 啊之类的各种值计算。

在一个设置页面中修改了缩放后,写入到 storage 中记录用户选择的缩放值。

这个需求是在项目后期中插入,并未在前期的规划中。也就是说,项目所选择的组件库、单位值等方案都已经确定了。

方案选择

提到放大,在移动端中现在最简单的处理方式应该就是:

  • meta 中修改 viewportinitial-scale=1, maximum-scale=1, minimum-scale=1 相关值;
  • 页面整体通过 transform 中的 scale() 去缩放;
  • 通过 zoom 属性去缩放;

正常情况来说,优先考虑使用 scale() 的方式来进行缩放。scale() 是标准属性,且在性能上也优于 zoom,然而这个缩放目前的现状是整体放大了,但是放大了之后,宽度超出了屏幕,无法正常显示。就算是改变了 transform-origin 的话,无非也就是让超出屏幕的部分不同而已。

转而考虑使用 meta 的方式,结果跟 scale() 相似,会超出屏幕。

最后尝试使用 zoom 的方式来放大,给 <body> 下的最外层容器 <div> 增加了一个 zoom: 1.15;,看到效果是整体放大,无论是文字还是其他元素,并且没有超出屏幕之外。符合预期效果!😆

惊现 bug

尝试使用 zoom 的方案让页面元素在屏幕内正常放大,很开心。但在每个页面排查的时候突然发现,有个别地方的文字并没有放大,比如一些 Tab 选项卡中当前选中的 tab 文字还是原来的大小。

十分好奇,在 Mac 上打开 Safari,连接 iPhone,开始排查 bug。通过开发者工具逐层排查样式,最终在样式的“计算结果”面板中发现,当前态的文字是 font-size: 12px; 而其他 tab 的文字是 14px。这就很不正常了。

通过排除法,最终发现当把当前态的 font-weight 去掉,那么就一切正常了。思前想后,也没太明白具体为什么,唯一想到的就是跟 zoom 有关。

想到了当年的 IE 中,很多时候因为浏览器的渲染问题,在页面中状态改变后,都是通过再次添加 zoom: 1; 来重新渲染,触发 hasLayerout 来解决的。

所以,在这个当前态的 tab 中增加了 zoom: 1;,发现文字果然变大了,而且变的比正常态的要大。这又不合理啊!

尝试性加一个 zoom: 1.000001;,在触发类似 IE 中的 hasLayerout 情况基础上,通过很小的小数点去改变变大的值。

Σ(⊙▽⊙"a 居然可以了。正常了!

排查并处理 bug

这神奇的 Safari,难怪大家都说现在的 Safari 就是新标准下的 IE。找到了解决方案,继续排查页面中是否有未变化的元素,然后通过相同的方式添加 zoom: 1.00001; 来解决。

这个可以大胆添加,并不会在 Chrome 中有什么影响。

最后

无用的知识点似乎又增加了一个!


林小志
4.4k 声望1.8k 粉丝