CSS 写个清除浮动,怎么还蹦出个 hasLayout? *zoom?

清除浮动

前端开发中,清除浮动是一种很常见的操作,最常用的一种方案如下:

less 复制代码
.clearfix {
  *zoom: 1;

  &::after {
    clear: both;
    content: '.';
    display: block;
    font-size: 0;
    height: 0;
    visibility: hidden;
  }
}

clearfix 类中添加 after 伪元素,并在伪元素中使用 clear: both 是很常见的一种清除浮动的方法,但上面的代码中还有一些额外的操作需要注意:

  • 为什么 content 不直接设置为空字符串?

    首先,在伪元素中,如果没有 content 属性,或者 content 属性值为 none 或者 normal 时,伪元素是不会产生的。 然而在一些老版本的浏览器中,content 值为空字符时也不会产生伪元素,所以为了兼容性,这里是随便设置 一个 content 值,然后后面使用font-size: 0;height: 0;visibility: hidden;来消除这个 content 的影响。

  • 为什么 clearfix 类中还要使用 *zoom: 1;

    这是本篇文章的重点,往下看!

zoom 是什么?

zoom 属性最初只是 IE 浏览器上的私有属性,但之后也被一些浏览器所支持,支持情况如下:

zoom 属性主要是用于控制元素的缩放比例,与 transform: scale() 类似,但它会影响元素的布局大小(同样会影响周围元素的布局,会触发回流),效果如下:

网上都说这个属性没什么意义,但我个人认为它还是有一定的使用场景的,如果您正在使用 typora 写 markdown,您可以试试插入图片后调整图片大小,然后再查看源码,您会发现 typora 就是使用 zoom 属性来缩放您的图片的

为什么使用 zoom ?

多加一个 zoom 属性,无非就是两点原因:

  1. 一些老版本 IE 浏览器对伪元素或者一些属性的支持情况不太友好,导致无法使用伪元素来实现清除伪类。
  2. zoom 属性可以在老版本 IE 中起到清除浮动的作用。

为何 zoom 可以在老版本 IE 中起到清除浮动的作用?这就要说起 IE 中对元素布局具有深远影响的 hasLayout 属性!

什么是 hasLayout ?

绝大部分情况下,我们不需要了解 hasLayout 的任何信息,但本着提升自己、扩展知识、提升职业素养的想法,多了解自己领域内的知识,百利而无一害!

其实在 IE 中,hasLayout 并不是一个可以被开发者直接控制的 CSS 属性,它是 IE 渲染引擎的内部属性,主要用来表示元素以何种方式进行渲染

在 IE 中,元素主要有两种渲染方式:

  1. 元素负责调整自身以及后代元素的内容的大小和排列,此时元素对应的 hasLayout 属性为 true(这时可以简单称该元素具有"独立布局")
  2. 元素依赖父元素来调整其内容的大小和排列,此时元素对应的 hasLayout 属性为 false

只有一部分元素,如:bodyhtml(标准模式,非怪异模式)、tableimgbuttoninputiframe等的 hasLayout 属性默认为 true

之所以不让所有元素默认都具有"独立布局"的主要原因是"性能和简单性",如果所有元素都有独立布局,则会对性能和内存使用产生不利影响。

对于 hasLayout 属性为 false 的不具有"独立布局"的元素,因为受限与父元素,在使用时可能会发生一些 BUG。事实上 IE 中很多 CSS 的 BUG 确实是由于这种机制所导致,所以大部分 BUG 也都能通过触发 hasLayout 来解决。

如何触发 hasLayout ?

当一个元素设置了 width 或者 height (除 auto 之外的值)时,该元素的 hasLayout 就会变成 true,如果不想指定元素宽高,也可以使用以下方式来触发:

  • 设置元素为行块盒(inline-block
  • 设置浮动
  • 设置绝对定位
  • writing-mode: tb-rl (tb-rl值目前来说虽已弃用,但这里针对的老版本浏览器还都是支持的)
  • 设置zoom

IE7 中,min-heightmax-heightmin-widthmax-widthoverflow、固定定位等也都可以触发 hasLayout

以上属性,最常用的就是使用 zoom:1,因为它几乎不会产生什么副作用,这也是我们使用 zoom 的原因之一。

为何是之一?

因为还有一个原因:早期时它不是有效的 CSS 属性(非标准,且是 IE 私有的),因此其他浏览器会忽略它。但之后这个属性也被 Chrome 、Safari 等其它一些浏览器给支持了,现在如果我们不想让除 IE 之外的浏览器识别 zoom,可以在其前面添加*前缀(原因后面说)

其实看到这,您应该可以想到 IE 中的 hasLayout 与我们当下流行的块级格式化上下文(BFC)有些许相像,它们都是创建一个独立环境来完成布局,从而避免影响外界或者被外界影响,所以说在 IE 中触发 hasLayout 就能清除浮动也就很好理解了。

为何 zoom 前加 * 前缀 ?

上面已经提到了,如果我们不想让除 IE 之外的浏览器识别 zoom,可以在其前面添加*前缀,这是因为只有 IE7 及以下版本的浏览器才支持具有非字母数字下划线前缀的属性!现代浏览器是无法识别带这种前缀的属性的,并且在 CSS 中直接使用这种前缀时 VS Code 会直接爆红(在 less 中写这种前缀则不会爆红):

浏览器控制台 VS Code

其实个人感觉现在这个 * 前缀加不加无所谓,因为即使被一些浏览器所识别,zoom:1 的设置也不会产生什么明显的副作用。不加的话,还可以避免在直接写 CSS 时 VSCode 爆红,不知各位大佬有何观点?

参考:


如果您有什么建议或者想法欢迎在评论区或者私信交流哦,一起学习,一起进步,加油!

如果本篇文章对你有所帮助,还请客官一件四连!❤️

相关推荐
gongzemin4 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox16 分钟前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
-代号952721 分钟前
【JavaScript】十四、轮播图
javascript·css·css3
树上有只程序猿44 分钟前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼1 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下1 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞2 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行2 小时前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_593758102 小时前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox