Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深入理解视觉格式化模型( VISUAL FORMATTING MODEL)

深入理解视觉格式化模型( VISUAL FORMATTING MODEL)

作者头像
Jace
发布于 2018-08-01 09:29:42
发布于 2018-08-01 09:29:42
6490
举报
文章被收录于专栏:进步博客进步博客

“理论不懂就实践,实践不会就学理论”,非常赞同bluedavy的这句话。实践过程中经常会遇到某个属性的使用,浏览器渲染效果与预期效果不符,虽然通过死记硬背能避免或巧妙应用这种效果,但总感心虚发慌、毫无自信,因为不知晓背后的原理。这时就不要再用“就是这样的”的借口来搪塞自己,我们需要重新认识它。

实践与现象

绝对定位是一种常用的定位方式,也经常会看到一些使用技巧,轻松搞定一些不太容易实现的效果。现介绍两个绝对定位的使用技巧:

1. 绝对定位元素,水平方向(top和bottom)或和垂直方向(left和right)的定位值不设置时,其位置受其前面的兄弟元素影响,如同其在常规流中的位置。如下例所示:

  • 元素A,C绝对定位,不设置top,bottom值;
  • 元素B处于常规流中;

结果是:元素C的位置受元素B的影响,跟随在元素B的下方。

See the Pen <a href="http://codepen.io/wenjul/pen/jrMjOd/">absolute-position</a> by wenjul (<a href="http://codepen.io/wenjul">@wenjul</a>) on <a href="http://codepen.io">CodePen</a>.<br />

这种看似毫无用处的技巧,却能帮助我们解决一些项目实际问题。我们总希望我们的布局是自适应的,即不依赖与所处环境,当环境改变时,仍能完美工作。下面这个实例要求蓝色购买按钮水平居中,其后跟随一个链接。为了达到自适应布局,我们不能假设父级容器宽度固定,也不能假设蓝色按钮的文案固定,所以链接元素的位置也是根据上下文环境改变的。这种情况下,我们就可以对链接设置绝对定位,并且不用设置left 和right 值,两者的间距通过margin值实现,即可轻松达到预期效果。(当然,通过嵌套的方式也可实现,但不是最优解)

See the Pen <a href="http://codepen.io/wenjul/pen/aZmegP/">center-el-followed-by-link</a> by wenjul (<a href="http://codepen.io/wenjul">@wenjul</a>) on <a href="http://codepen.io">CodePen</a>.<br />

另一个案例是用以实现下拉菜单,下拉菜单通常由触发按钮和下拉列表组成,下拉列表的位置位于触发按钮的下方。同样,由于触发按钮的高度是可能变化的,那么下拉列表与触发按钮顶端的绝对距离是不固定的,使用单位px是无法达到自适应的,通常的技巧是设置top:100%,其实利用我们上面提到的技巧,对top和bottom不设置值也是可以实现的。

See the Pen <a href="http://codepen.io/wenjul/pen/WxopOr/">dropdown menu</a> by wenjul (<a href="http://codepen.io/wenjul">@wenjul</a>) on <a href="http://codepen.io">CodePen</a>.<br />

2. 绝对定位结合margin实现垂直居中

很多设计都可以抽象为“一个元素相对于父级(或包含块)在垂直方向或水平方向上居中对齐”的模式,根据实际情况又可分为该元素的尺寸未知和已知两种情况。这是个经久不衰的话题,实现方式也多种多样,这里我们讨论的是“尺寸已知元素在垂直方向上的居中对齐”问题。你可能看到过下面这种实现方式,绝对定位元素的4个值均为0,margin在垂直方向上也设置为了auto(支持IE8+)。一般为了水平居中会在水平方向上设置auto,为什么这种情况下,在垂直方向上设置auto,会导致垂直居中的效果呢?

See the Pen <a href="http://codepen.io/wenjul/pen/ZOBeYB/">center-middle</a> by wenjul (<a href="http://codepen.io/wenjul">@wenjul</a>) on <a href="http://codepen.io">CodePen</a>.<br />

规范与原理

为了解决这个疑虑,我重新学习了CSS 2.1规范中的9 Visual formatting model10 Visual formatting model details,现将相关章节译录于此。

这两章讲解了视觉格式化模型:用户代理在视觉媒体上如何处理文档树。在视觉格式化模型中,文档树中的每个元素根据框模型(box modal)生成0或多个框。这些框的布局由以下因素决定:

  • 框尺寸和类型
  • 定位方案(常规流、浮动和绝对定位)
  • 文档树中元素之间的关系
  • 外部信息(比如viewport尺寸、图像的固有尺寸等)

9.1.2 Containing blocks(包含块) CSS 2.1中,许多框的位置和尺寸的计算是相对于一个矩形框的边缘,这个矩形框称为包含块。通常情况下,生成框是后代框的包含块(generated boxes act as containing blocks for descendant boxes;),称之为一个框为其后代创建了包含块。短语“一个框的包含块”指的是“这个框存在其中的包含块”,而非它生成的框。 每个框会相对于其包含块赋予位置,但它并不囿于包含块,可能会溢出(overflow)。包含块的尺寸计算细节在第10章有详细介绍。 9.2 Controlling box generation(控制框生成) 本节描述了CSS 2.1中可生成的框类型。一个框的类型部分地影响其在视觉格式化模型中的行为。 9.2.1 Block-level elements and block boxes 处在块格式化环境(BFC,block formatting context)中的框称之为块级框(block-level box)每个块级元素生成一个包含后代框和生成的内容的主体块级框,同时这个框与定位方案密切相关。有些块级元素除了生成主体框外,还会生成一个附加框,如’list-item’元素。附加框相对于主体框定位。 表框(table boxes)和替换元素(replaced elements)外,块级框同时也是块容器框(block container box)。块容器框要么仅包含块级框,要么建立一个行内格式化环境(IFC,inline formatting context),即仅包含行内级框。并非所有的块容器框都是块级框:非替换行内块(inline blocks)和非替换表格单元格都是块容器,但不是块级框。既是块级框也是块容器的框称为块框(block box)。 “块级框”、“块容器框”和“块框”这三个术语有时被简称为块(block)9.2.3 Run-in boxes(插入型框) CSS Level 3的CSS basic box model中定义。 run-in框的行为如下:

  1. 如果run-in框包含一个块框,那么run-in框变为块框。
  2. 如果run-in框的后继兄弟元素为块框(非浮动,非绝对定位),那么run-in框变为该块框的第一个行内框。run-in不能插入本身为run-in的块中,也不能插入块中已有run-in的块中。
  3. 否则,run-in框变为块框。

浏览器支持:IE8+(chrome不支持,难道是太鸡肋?) IE下查看效果

9.3.2 Box offsets: ‘top’, ‘right’, ‘bottom’, ‘left’

  • (绝对、固定)定位元素会生成一个定位框(positioned box),根据top,right,bottom,left布局。
  • 初始值为auto,非0。(文章开头的问题中未设置四值,等同设置为auto
  • 对于绝对定位元素,四值指定的是元素margin边与包含块的边之间的偏移量。对于相对定位元素,四值指定的是相对于自身框边的偏移量。

9.6 Absolute positioning

  • 从常规流中完全抽离,对其后继兄弟元素无影响。
  • 固定定位是绝对定位的特例,它的包含块是viewport。

9.7 Relationships between ‘display’, ‘position’, and ‘float’ 这三个属性影响了框的生成和布局,相互影响如下:

  1. 如果’display’值为’none’,同时不设置’position’和’float’,那么该元素不生成框。
  2. 否则,如果’positon’值为’absolute’或’fixed’,即框为绝对定位,’float’的计算值为’none’,并且’display’根据下表设置。那么该框的位置由’top’,’right’,’bottom’,’left’和框的包含块决定。
  3. 否则,如果’float’的值不为’none’,那么该框会浮动,’display’根据下表设置。
  4. 否则,如果该元素为根元素,’display’根据下表设置。
  5. 否则,剩余的’display’属性值与指定值相同。

指定值 计算值 inline-table table inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block others same as specified 10.6 Calculating heights and margins(高度和margin值计算) 10.6.4 Absolutely positioned, non-replaced elements(绝对定位的非替换元素) 静态位置(static position),粗略地讲是指一个元素在常规流中的位置。精确地讲,一个元素的静态top值,是指包含块顶部边沿与该元素的假想框的顶部margin边沿之间的距离。假想框是指如果该元素的’position’值为’static’,以及’float’值为’non’且’clear’值为’none’时,该元素的第一个框。 对于绝对定位的元素,垂直尺寸的使用值必须满足下面约束: ‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = height of containing block 如果’top’,’bottom’,’height’值均为auto,那么’top’值为元素的静态位置。(这也就回答了文章开头的问题) 如果三个值均不为auto,那么:

  • 如果’margin-top’和’margin-bottom’值均为’auto’,那么假定margin-top和margin-bottom两值相等,然后再解上面方程式。(上述的第二个垂直居中案例就是利用了这一点 
  • 如果’margin-top’和’margin-bottom’值中其一为’auto’,解上面方程式获取该margin值。
  • 如果数值超过限制,忽略’bottom’值,解方程式获取该值。

否则,从以下六种规则中挑选适用情况:

  1.  ‘top’和’height’为’auto’,’bottom’不为’auto’,那么’height’基于其内容根据10.6.7规则计算,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’top’值。
  2.  ‘top’和’bottom’为’auto’,’height’不为’auto’,那么设置’top’值为其静态位置,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。
  3.  ‘bottom’和’height’为’auto’,’top’不为’auto’,那么’height’基于其内容根据10.6.7规则计算,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。
  4.  ‘top’值为’auto’,’bottom’和’height’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’top’值。
  5.  ‘height’值为’auto’,’bottom’和’top’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’height’值。
  6.  ‘bottom’值为’auto’,’height’和’top’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/06/222,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入理解视觉格式化模型
“理论不懂就实践,实践不会就学理论”,非常赞同bluedavy的这句话。实践过程中经常会遇到某个属性的使用,浏览器渲染效果与预期效果不符,虽然通过死记硬背能避免或巧妙应用这种效果,但总感心虚发慌、毫无自信,因为不知晓背后的原理。这时就不要再用“就是这样的”的借口来搪塞自己,我们需要重新认识它。 实践与现象 绝对定位是一种常用的定位方式,也经常会看到一些使用技巧,轻松搞定一些不太容易实现的效果。现介绍两个绝对定位的使用技巧: 1. 绝对定位元素,水平方向(top和bottom)或和垂直方向(left和righ
前朝楚水
2018/04/03
9380
深入理解视觉格式化模型
【CSS 学习笔记】CSS元素和布局
其中 margin 称为外边距,在计算元素整体宽高的时候一般不包括它。CSS3 中新增了一个属性 box-sizing,可以用来指定使用的盒模型计算方式。下面是 CSS3 中支持的盒模型计算方式(CSS2种只支持默认的)
零式的天空
2022/03/22
1.1K0
掌握这些CSS知识点,Coding如飞!
整理了一些在CSS(层叠样式表)中的知识点,或许你曾看过一些什么“万字总结”、“面试必看”,但还是希望更多同学能够沉下心来学习,不仅仅满足于停留在“API工程师”的层面,多从CSS约定的规则去解释现象。
小东同学
2022/07/29
1.1K0
掌握这些CSS知识点,Coding如飞!
常见的几种 CSS 水平垂直居中解决办法
用CSS实现元素的水平居中,比较简单,可以设置text-align center,或者设置 margin-left:auto; margin-right:auto 之类的即可。
书童小二
2018/09/03
1.3K0
常见的几种 CSS 水平垂直居中解决办法
CSS 定位和层叠上下文
position 属性的初始值是 static。如果把它改成其他值,就说元素就被定位了。而如果元素使用了静态定位,那么就说它未被定位。
Cellinlab
2023/05/17
1.4K0
CSS 定位和层叠上下文
深入学习下 CSS 间距相关的知识
https://ishadeed.com/article/spacing-in-css/
前端达人
2022/11/25
13.9K0
深入学习下 CSS 间距相关的知识
要开始使用Bootstrap 4 前,我们先了解几个它的通用模式吧
前情提要:让我们站在巨人的肩膀上,如何在专案中导入Bootstrap 4 并客制它[1]
沙漠尽头的狼
2021/12/08
1.3K0
要开始使用Bootstrap 4 前,我们先了解几个它的通用模式吧
CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法
本文介绍了前端性能优化中的垂直居中方案,包括使用Flexbox、Grid、CSS3进行垂直居中,以及使用定位和Transform进行垂直居中。同时,还介绍了如何通过代码拆分、懒加载和图片自适应来提高页面性能。最后,给出了一组示例和代码。
张果
2018/01/04
3.9K0
CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法
CSS 中你需要知道 auto 的一切!
在CSS中,我们有auto值,它可以用于像margin,position,height,width等属性。在本文中,会先解释auto的工作方式以及如何最大程度地利用auto的技术细节,当然,会配合一些用例和示例。
前端小智@大迁世界
2020/05/12
5.8K0
CSS 中你需要知道 auto 的一切!
CSS理解之margin
1.margin与百分比单位 Paste_Image.png Paste_Image.png 2.margin重叠 margin重叠通常特性: 只发生在block水平元素(例如:p、div、list、
小胖
2018/06/27
1.8K0
CSS深入理解学习笔记之margin
1、margin与容器尺寸   元素尺寸:①可视尺寸 clientWidth(标准);②占据尺寸   margin与可视尺寸:①适用于没有设定width/height的普通block元素;②只适用于水
就只是小茗
2018/03/07
1.5K0
CSS深入理解学习笔记之margin
CSS margin合并问题
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
前端下午茶
2018/10/22
1.3K0
104道 CSS 面试题,助你查漏补缺(上)
https://github.com/CavsZhouyou/Front-End-Interview-Notebook/blob/master/Css/Css.md
刘小夕
2020/11/03
2.3K0
104道 CSS 面试题,助你查漏补缺(上)
关于BFC理解
在进入BFC话题前,先来捋一下常见的定位方案,定位方案是控制元素的布局,主要有三种常见的方案:
Jimmy_is_jimmy
2019/07/31
1K0
前端基础篇之CSS世界
我想你每天写css代码有时候也会觉得很痛苦:这个布局的css怎么这么难实现!我也经常会有这种感觉,一个看似简单的布局总是要琢磨半天才能实现,偶尔还会出现一些怪异的超出理解的现象。这是因为我们对css只是大概知道个形,并没有看透css的本质。在同事的推荐下我阅读了张鑫旭老师的《css世界》,才发现css跟想象中的不太一样。本文为《css世界》个人总结笔记,为缩减篇幅丢弃了张老师冗余的小幽默,丢掉了些含金量较低的章节内容,因为ie已经被淘汰出局,所以有关css兼容性的地方也全部忽略不记,同时对个人觉得不易理解的地方加上了一些自己的理解和验证,所以错误之处还望指正。顺便推荐个好用的在线代码编辑工具,国内镜像站点,方便各位对本文实例进行测试。另外本文会随着作者对css的更深入理解而逐步更新,希望到最后能够文如标题展现出真正的css世界。
Nealyang
2019/10/14
2.2K0
前端基础篇之CSS世界
CSS上下左右居中
关键是利用transform百分比相对自身宽高计算的特性,如果环境不支持transform的话,就需要用一些比较老,但很精妙的技巧了
ayqy贾杰
2019/06/12
3.4K0
CSS上下左右居中
50道CSS基础面试题
23 0 0 50道CSS基础面试题 1 介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的? 标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin 低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin 2 box-sizing属性? 用来控制元素的盒子模型的解析模式,默认为content-box context-box:W3C的标准盒子模型,设置元素的 height/width 属性
慕白
2018/07/06
1.6K0
【Hello CSS】第二章-CSS的逻辑属性与盒子模型
在上一篇 【HelloCSS】的第一章CSS的语法与工作流中介绍了 CSS的语法规则以及基本的渲染流程。本篇则会分享 CSS的逻辑属性以及盒子模型。
陈大鱼头
2020/04/16
6170
【Hello CSS】第二章-CSS的逻辑属性与盒子模型
【学习笔记】CSS深入理解之absolute「建议收藏」
无依赖绝对定位元素可以使用margin值进行定位,实现脱离文档流的相对定位效果,脱离文档流可以解决溢出限制的问题
全栈程序员站长
2022/08/04
4690
纯CSS实现拖拽--resize、scale、包裹性
今天看了一篇关于 CSS 的文章,文章用到的几个点,想和大家聊聊。 附「原文地址」大家可自己查阅。
奋飛
2021/09/06
3.5K0
纯CSS实现拖拽--resize、scale、包裹性
相关推荐
深入理解视觉格式化模型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档