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 爆红,不知各位大佬有何观点?

参考:


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

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

相关推荐
dream_ready1 小时前
linux安装nginx+前端部署vue项目(实际测试react项目也可以)
前端·javascript·vue.js·nginx·react·html5
编写美好前程1 小时前
ruoyi-vue若依前端是如何防止接口重复请求
前端·javascript·vue.js
flytam1 小时前
ES5 在 Web 上的现状
前端·javascript
喵喵酱仔__1 小时前
阻止冒泡事件
前端·javascript·vue.js
GISer_Jing1 小时前
前端面试CSS常见题目
前端·css·面试
八了个戒1 小时前
【TypeScript入坑】什么是TypeScript?
开发语言·前端·javascript·面试·typescript
不悔哥2 小时前
vue 案例使用
前端·javascript·vue.js
anyup_前端梦工厂2 小时前
Vuex 入门与实战
前端·javascript·vue.js
你挚爱的强哥3 小时前
【sgCreateCallAPIFunctionParam】自定义小工具:敏捷开发→调用接口方法参数生成工具
前端·javascript·vue.js
米老鼠的摩托车日记3 小时前
【vue element-ui】关于删除按钮的提示框,可一键复制
前端·javascript·vue.js