一道面试题目引发的思考

起因

多列布局是前端一个经典的反复被提及的面试题目,最典型的即两列,左列定宽菜单栏,右列变宽为内容区域。

通常得到的答案无外乎左列浮动定宽,然后右列或浮动,或设置外边距,或绝对定位等等。偶尔会有面试者给出设置右列overflow属性的答案,心里就会有些惊喜,继而会继续追问,为什么这么设置就能实现效果,期待能有进一步惊喜,但基本大部分面试者都止步于这样设置,并不清楚原因。非常少的面试者会提到这样设置能够触发块级格式化上下文(Block Formatting Conext, BFC),如果继续追问触发BFC的原因,几乎没有一个面试者能给出比较满意的答案。

本文就是由这道面试题目引发的一些思考。针对设置overflow属性这一方法,做进一步的探讨。

overflow属性

overflow属性最常见的一个使用场景就是规定当内容溢出元素框时发生的事情。可能的值如下:

  • visible 默认值。元素内容不会被裁剪,元素框之外的内容仍然会呈现。
  • hidden 元素内容会被裁剪,并且元素 框之外的内容是不可见的。
  • scroll 元素内容会被裁剪,但是浏览器会显示滚动条以便查看其余的内容。
  • auto 浏览器自动处理元素内容的溢出,如果元素内容被裁剪,则浏览器会显示滚动条以便查看其余的内容。
  • inherit 规定应该从父元素继承 overflow 属性的值。

除此之外,也会经常看到通过overflow属性实现的一些效果,比如清除浮动,以及上面提到的两栏布局的实现。这些效果的实现,可能跟overflow属性的本意相差甚远,就像两种不相关的事务被硬生生的牵扯到了一起。其实不然,CSS Spec规范文档中还明确记录着overflow属性的另外一个重要作用。

overflow属性跟布局的关系

The CSS2.1 spec mandates that overflow other than visible establish a new "block formatting context".

CSS2.1规范中已经明确提出,设置overflow属性(非visible)能触发块级格式化上下文(Block Formatting Conext, BFC)。

BFC是个很大的话题,此处不展开,这里给出一个简化不精确的解释,BFC概念的引入,一定程度是为了特殊情况下布局计算的方便,元素触发BFC之后,其作用就相当于一个根容器,其内部的子元素会跟外界完全隔离开,子元素布局以及尺寸相关的计算都会以该元素容器为基础。

为什么overflow非visible值会触发BFC?

首先,设置overflow属性为visible的话,是一种默认情况,就相当于正常默认的布局,所有超出元素框的内容仍然会正常显示,不会被裁剪,也不会出现滚动条。但对于其它几种值的话(hidden, scroll, auto),元素的内容可能会被裁剪,此时,对于某些情况下可能出现的特殊布局处理就会出现争议。

比如对于垂直方向紧贴着的两个元素A和B,其中元素A中浮动的子元素可能会遮住元素B的部分文字区域,此时如果元素B的overflow属性设置为visible,则内容会包裹在元素A浮动子元素的周围,这种情况比较容易理解,如下图。

overflow属性设置为visible
overflow属性设置为visible

图1 overflow属性设置为visible

但当元素B的overflow属性设置为非visible的值时,各版本规范的规定就会出现差异。

CSS2.0规范规定,设置非visible属性值后,元素B的内容仍然包裹浮动元素,如图2所示。

overflow属性设置为novisible,CSS2.0规范中的处理
overflow属性设置为novisible,CSS2.0规范中的处理

图2 overflow属性设置为novisible,CSS2.0规范中的处理

此后如果元素B内容发生滚动,每次滚动行为,元素B中发生折叠的内容(图3中元素B中文字内容滚动后发生变化)全部要重新计算重绘,实际上这将会带来很大的性能问题,对滚动体验也会造成比较大的影响。

overflow属性设置为novisible,CSS2.0规范中发生滚动时的处理
overflow属性设置为novisible,CSS2.0规范中发生滚动时的处理

图3 overflow属性设置为novisible,CSS2.0规范中发生滚动时的处理

但这里存在进一步的疑问,即使按此规范的约定,元素B内容滚动时存在性能以及体验问题,但是非visible属性中的hidden值,难以理解,元素内容已经被裁剪掉了,为什么跟其它值auto, scroll归为一类?这里面就存在一个误区,overflow设置为hidden值并不代表内容不可滚动,此时浏览器只不过没有提供可滚动的UI,被"裁剪"掉的内容可以通过JavaScript脚本来控制滚动,这也是脚本模拟滚动条的基础。比如,可以通过JavaScript脚本设置元素的scrollTop实现图4的效果,更友好的方式可以自定义一个滚动条。

overflow属性设置为hidden,CSS2.0规范中发生滚动时的处理
overflow属性设置为hidden,CSS2.0规范中发生滚动时的处理

图4 overflow属性设置为hidden,CSS2.0规范中发生滚动时的处理

事实上各大浏览器厂商也都没有遵照CSS2.0来实现这一部分规范。取而代之,实现的是CSS2.1中的规范内容,即当元素B的overflow属性设置为非visible值时会触发BFC,元素B会创建自己的块级格式化上下文,并会被整体推向右侧,如图5所示。

overflow属性设置为nonvisible,CSS2.1规范中的处理
overflow属性设置为nonvisible,CSS2.1规范中的处理

图5 overflow属性设置为nonvisible,CSS2.1规范中的处理

备注 上面各图均来自于参考文献3

收尾

事实上,一些常见的其它布局技巧也都是基于上述的原理点,比如overflow属性非visible值可以用于清除浮动。如果一个面试者,能够比较清楚地讲出上面的各点,相信每个面试官心里面都会比较惊喜,上面只是自己的一些想法,可能会有些许的钻牛角尖,但单从这种对细节的钻研把控程度,候选人就一定不会太差,对候选人来说必然会有很大程度的加分。

上面只是针对两列布局这道题目一种方案的单方面探讨,这种方案有哪些优缺点等等都未提及,如果对每种方案都进行类似程度的拓展,将会发现这其中会涵盖很多前端知识点,所以看似简单的题目其实并不简单。越发觉得前端领域的水很深,伙伴们一起来努力探索实践吧!

参考文献

  • block formatting contexts
  • The impact of 'overflow' values other than 'visible' on the block formatting context
  • Re: CSS21 Why do overflow values other than 'visible' establish a new block formatting context?
  • How does the CSS Block Formatting Context work?

Written by Hong


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp弹出框_uniApp上拉刷新,下拉加载,以及筛选功能

uniApp插件市场有很多友好的插件,今天举一个例子如上图所示,实现上拉刷新,下来加载,右上角点击弹出筛选框,只需要在插件市场搜索刷新选择你想要的效果(也可以下载后自己改动效果)点击导入插件,会自动打开项…

乐高无限的服务器怎么建,乐高无限悬空房子怎么建造 建造方法介绍

乐高无限悬空房子怎么建造?很多玩家对此还不是很清楚,下面给大家带来乐高无限悬空房子建造方法,还不知道怎么建造的朋友一起来看看吧!建造方法悬空房子非常容易搭建,如果我们想要将已经搭建的房子悬空,就只需要将建筑下方的土地挖…

Hibernate学习(一)

搭建环境 1、创建普通的Java工程 2、添加相应的jar包,下载链接:https://files.cnblogs.com/files/AmyZheng/required.rar 第一个实例 1、引用jar包 2、创建数据库和表 DROP TABLE IF EXISTS t_customer ;CREATE TABLE t_customer (id INT(5) PRIMARY KE…

使用Spring Webservices构建SOAP Webservices代理模块

前一段时间,我想看看使用Spring Web Services编写Web服务代理(wsproxy)有多么容易。 所以,我想我会在Github上分享结果。 可以随意使用它 (Apache v2许可证)或将其用作自己开发的基础。 本文的其余部分将解…

joc杂志影响因子2019_排名 ‖ 2019年中国体育学期刊影响因子

近日,由中国科学文献计量评价研究中心、清华大学图书馆研制,《中国学术期刊(光盘版)》电子杂志社有限公司出版的《中国学术期刊影响因子年报》(2019版)发布。该年报是中国科学文献计量评价研究中心自2002年…

Vue中的Js动画与Velocity.js 的结合

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Vue中的Js动画与Velocity.js的结合</title><script src"./vue.js"></script><script src"./velocity.min.js&quo…

服务器端如何开启GZIP压缩功能

我们知道做好负载均衡对网站的正常运行&#xff0c;用户体验相当重要。在负载均衡中有一个必须要做的事情就是给服务器开启GZIP压缩功能&#xff0c;对用户请求的页面进行压缩处理&#xff0c;以达到节省网络带宽&#xff0c;提高网站速度的作用。 GZIP是若干文件压缩程序的简…

在服务器中开虚拟机,可以在云服务器上开虚拟机

弹性云服务器 ECS弹性云服务器(Elastic Cloud Server)是一种可随时自助获取、可弹性伸缩的云服务器&#xff0c;帮助用户打造可靠、安全、灵活、高效的应用环境&#xff0c;确保服务持久稳定运行&#xff0c;提升运维效率三年低至5折&#xff0c;多种配置可选了解详情Linux云服…

Confluence 6 MySQL 3.x 字符集编码问题

MySQL 3.x is 已知在大写和小写转换的时候有些问题&#xff08;non-ASCII&#xff09;。 问题诊断 请按照 Troubleshooting Character Encodings 页面中的内容对问题进行诊断。如果大小写字符串编码诊断显示不同&#xff0c;那么有可能是你数据库导致的。一个错误的数据库大小写…

将社交登录添加到Spring MVC Web应用程序:配置

过去&#xff0c;用户使用用户名和密码组合登录。 尽管如今有些人仍然偏爱传统方式&#xff0c;但越来越多的用户希望使用其社交媒体帐户登录。 这就是使Spring Social&#xff08;及其子项目&#xff09;成为Spring项目组合有用的补充的原因。 但是&#xff0c;将Spring Soci…

[leetcode] 35. 搜索插入位置(Java)(二分)

35. 搜索插入位置 二分&#xff0c;太简单&#xff0c;没啥好说的 class Solution {public int searchInsert(int[] nums, int target) {if (nums.length 0) return 0;int i 0, j nums.length;int mid (i j) / 2;while (i < j) {if (nums[mid] target) {return mid;} …

UI设计中颜色的前进色与后退色

暖色调的颜色属于前进色。膨胀色可以使物体的视觉效果变大&#xff0c;而收缩色可以使物体的视觉效果变小。颜色的另外一种效果。有的颜色看起来向上凸出&#xff0c;而有的颜色看起来向下凹陷&#xff0c;其中显得凸出的颜色被称为前进色&#xff0c;而显得凹陷的颜色被称为后…

手型向下 点击一下 福昕_PPT多张缩略图点击放大展示

↑点击上方“菜鸟PPT”关注&#xff0c;教你玩转PPT&#xff01;多张图片单击放大展示&#xff0c;以前做过一个比较复杂的&#xff0c;在同一页PPT里面做&#xff0c;加了很多个“进入”和“退出”的动画&#xff0c;维护起来比较麻烦。今天&#xff0c;菜鸟菌跟大家一起来学习…

6个经典的JavaScript报错分析

代码报错是经常发生的一件事&#xff0c;我们要确定是什么原因造成的&#xff0c;以及如何避免错误。 1. Uncaught TypeError: Cannot read property 该错误说明没有某个属性&#xff0c;一般是该属性前面的值是undefined或者是null的情况会出现。 2. TypeError: ‘undefined…

编写自动调试器以在测试执行期间捕获异常

以前&#xff0c;我曾说过&#xff0c; 您总是想保留一些调试器断点作为例外 。 此帮助可防止代码在不引起注意的情况下腐烂掉-有时掩盖了另一个问题。 如果您认真对待这一点&#xff0c;则最好将此概念扩展到自动化测试中。 但是想出一个全面的解决方案并不简单。 您可以仅从…

git显示服务器所有分支,git 查看所有远程分支以及同步

在多台电脑使用git管理开发分支的时候&#xff0c;会出现这样的情况。电脑A创建了分支1&#xff0c;并且push上了远程仓库。电脑B本地clone仓库默认只会clone下master分支&#xff0c;而其他电脑A推送的分支是不会默认同步下来的。那么如何同步呢&#xff1f;查看电脑B本地仓库…

Vue中浏览器的的前进和后退

项目开发的时候&#xff0c;有时候可能需要我们来对页面后退和前进&#xff0c;这个东西跟浏览器自带的前进后退功能很像,下面来大致讲一下在vue中浏览器的前进和后退 一、后退功能 vue中的后退有好多种方法可以使用&#xff0c;使用这些方法前要确认有之前的页面&#xff0c;否…

pandas:DataFrname(三)

pandas:从文件读取 读取文件&#xff1b;从文件名。url,文件对象中加载数据 read_csv 默认分隔符为逗号 read_table 默认分隔符为\t读取文件函数主要参数 sep 指定分隔符&#xff0c;可用正则表达式 headerNone 指定文件无列名 names 指定列名 index_col 指定某列作为索引 …

json-schema 可视化编辑器发布了

json-schema 的用途越来越广泛&#xff0c;除了定义数据结构外&#xff0c;我们还可以使用 json-schema 验证数据格式和生成随机数据&#xff0c;但是编写复杂数据结构的 json-schema 是非常痛苦的事情。假设一个 100 字段的数据结构&#xff0c;如果用 json-schema 定义&#…

tfw文件如何导入cad_如何将CAD的线稿导入PS并和底色分离

【新朋友】 点击标题下方的 CG伴学 迅速关注【老朋友】 点击右上角的按钮 分享 或者 收藏这是 【CG伴学 】制作的第249篇答疑教程观看往期视频教程请点击或者前往公众号自定义菜单【学习中心】我们专门制作了教程汇总目录&#xff0c;你可以根据标题关键词搜索获取我们在后台收…