博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS布局
阅读量:5068 次
发布时间:2019-06-12

本文共 3101 字,大约阅读时间需要 10 分钟。

一些基本概念

  • viewport: 展现网页的媒体,比如窗口或者某个区域,它的大小是有限制的,为了不被平台术语所束缚,我们给他起名viewport,中文意思就是视口。
  • canvas: 而我们在渲染网页的时候通常并不知道我们需要多大的空间,而且这些空间通常尺寸会超过viewport的大小,于是实际上我们需要设想一个无限大的画布来绘制我们的元素,我们把它称为canvas。
  • box: element(元素)和node(节点)是大家很熟悉的概念,当我们做布局计算的时候,通常会把节点变成box,一个节点可能产生多个box,伪元素也会产生box。
  • render tree: 对应于dom树,我们把box的包含关系构成的属性结构成为渲染树render tree

BFC

首先我们来考虑一个基本的情况:

run

        

之所以简单是因为这些div每一个只产生一个盒子,默认的display下,div产生块级盒,为了让块级盒按照我们的意愿排布,我们需要引入一个概念:block formatting context,简称BFC。

BFC其实是个相当简单的概念,然而因为实在中文中没啥合适的词来形容(你不觉得"块级格式化上下文"比BFC更让人觉得不知所云么?),这个概念已经被传得极其神秘:

在 CSS 面试中问 BFC 等概念,就如在 JS 面试中问闭包等概念一样,经常会刷掉一些真正优秀的人。 ——玉伯

甚至很多人连它是动词还是名词都搞不清,不信你可以搜索一下,亲,BFC是名词啊……怎么它就能触发呢?

简单地说,BFC就是像例子里面一样顺次竖着排块级盒的一种上下文。竖着排盒子而已,竖着排盒子有什么理解不了的啊我X?

好吧平复一下情绪,我们继续说,canvas会设立一个BFC,这也是最外层的formatting context了,问题的复杂性在于有些块级盒内部也可以产生BFC(至少它必须也能包含块级盒),于是说BFC是可以嵌套滴:

run

        

不是所有块级盒内部都可以产生BFC,比如说要是这盒里面连块级盒都没有,都是行内盒那就产生IFC:

run

        
囧囧

不过,只要它的子节点里面有一个块级盒,它就产生BFC,那些行内元素,会自动套一个匿名的块级行盒。

run

        
啦啦啦
囧囧

又比如说overflow:visible的块盒就不产生BFC,不但不产生BFC,啥FC都不产生,它的子元素直接搞进自己外层的BFC鸟:

run

        

aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa

overflow:visible这个限制只对所谓的块盒(既包含块级盒、自己又是块级盒)存在,有些盒内部也能包含块级元素,但是它本身又不是块级元素(比如display为table-cell、inline-block、或者盒本身是flex item等),因为外面不是BFC,所以它们不论如何一定会给包含的块级盒创建一个新的BFC出来。

同一个BFC里面的盒还会有margin collapse现象,详情见此文 

IFC

IFC里面可能有文字、行内元素混合排布:

run

        
囧囧囧
囧囧

文本的排布是个很复杂的事情,在dom树中,我们存储的是字符和字符串,而在render tree中,我们要使用一个新的概念:字型(glyph)。字体文件(通常是ttf,ture type格式的)中包含着不同字体下字符到字型的规则。

一个字型有很多属性,下面这张图来自freetype,它是大部分浏览器使用的文字排版基础库:

详情请看。

图中的那根加粗的X轴就是传说中的基线(base line)了,文字默认是按照基线对齐的。

下面这个demo展示了一个IFC中的几条重要的基准线:

  baseline   sub   super   top   text-top   middle   bottom   text-bottom  

 
 great it works!
2囧啊

在水平方向,文字的排布主要受到以下属性影响

  • word-break, word-spacing, word-wrap
  • letter-spacing
  • white-space
  • text-align
  • hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphenate-limit-lines, hyphens
  • justify-content
  • ……

总之很复杂,讲也讲不完,而且大家又不要写浏览器所以大家就大概望文生义一下好了(po主被扔蛋中……)。

对于一个正常的"行盒"来说,文字总是垂直居中排布的。

在纵向,文本排布主要受line-height属性影响,在有行内盒参与的情况下就复杂了,

一个行内盒的vertical-align可以有这样几种取值:

  • baseline
  • sub
  • super
  • top
  • text-top
  • middle
  • bottom
  • text-bottom

它也可以是某一指定高度。根据行内盒的对齐方式,它有可能把这行盒向上或者向下"撑大",造成超过行高的情况。

所以行盒在BFC中占据的实际高度,很可能大于line-height。

文字的baseline很好理解,而行内元素则比较复杂,特别是当行内元素自身又是容器的时候:

run

        
囧囧囧
囧囧

run

        
囧囧囧
123
123
123
囧囧

浮动

浮动是个行级的行为,当遇到浮动元素的时候,会首先"假装"它是个行内元素进行排版,排好后就往浮动的方向挤到挤不过去为止(遇到边界或者其它浮动元素)。

run

        
囧囧囧
囧囧

run

        
囧囧囧
囧囧

某一方向有clear的时候,浮动元素总是挤到边界,在垂直方向上的行为类似"换行"。

run

        
囧囧囧
囧囧

排好一个浮动元素之后,这一行就要重排一次。所以说浮动元素会造成行级的reflow。重排的时候,行盒会躲开浮动元素。之后的块级盒(不论是行盒还是其它盒)也都会躲开浮动元素排布。

转载于:https://www.cnblogs.com/bzzhzblog/p/7400913.html

你可能感兴趣的文章
桌面图标修复||桌面图标不正常
查看>>
JavaScript基础(四)关于对象及JSON
查看>>
JAVA面试常见问题之Redis篇
查看>>
jdk1.8 api 下载
查看>>
getElement的几中属性介绍
查看>>
HTML列表,表格与媒体元素
查看>>
雨林木风 GHOST_XP SP3 快速装机版YN12.08
查看>>
java对象的深浅克隆
查看>>
数据结构3——浅谈zkw线段树
查看>>
Introduction to my galaxy engine 2: Depth of field
查看>>
Python 3.X 练习集100题 05
查看>>
设计器 和后台代码的转换 快捷键
查看>>
Monkey测试结果分析
查看>>
STL——配接器、常用算法使用
查看>>
STL容器之vector
查看>>
无法向会话状态服务器发出会话状态请求
查看>>
数据中心虚拟化技术
查看>>
01入门
查看>>
复习文件操作
查看>>
SQL Server 使用作业设置定时任务之一(转载)
查看>>