10.4【前端开发】页面布局:如何理解 “CSS 视觉格式化模型”?
页面布局:如何理解 “CSS 视觉格式化模型”?
几种盒子
行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
旧说法有块元素、行内元素,这种表述是不确切的。应该说是块级元素,或行内级元素。有一些网上教程沿用了旧说法,但不准确。
相关概念
- 块block,一个抽象的概念,一个块在文档流上占据一个独立的区域,块与块之间在垂直方向上按照顺序依次堆叠。
- 盒子box,有时候一个盒子对应几个元素,有时候一个元素几个盒子。一个抽象的概念,由CSS引擎根据文档中的内容所创建,主要用于文档元素的定位、布局和格式化等。盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。
- 块级元素:block-level element,元素的 display 为 block、list-item、table时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
- 块级盒子:block-level box,由块级元素生成。一个块级元素至少会生成一个块级盒子,但也有可能生成多个(例如列表项元素)。
- 块盒子:block box,如果一个块级盒子同时也是一个块容器盒子,则称其为块盒子。
- 匿名块盒子:除具名块盒子之外,还有一类块盒子是匿名的,称为匿名块盒子(Anonymous block box),匿名盒子无法被CSS选择符选中。
- 块容器盒子:block container box或block containing box,块容器盒子侧重于当前盒子作为“容器”的这一角色,它不参与当前块的布局和定位,它所描述的仅仅是当前盒子与其后代之间的关系。
盒子分为“块盒子”和“块级盒子”两种,但元素只有“块级元素”,而没有“块元素”。下面的“行内级元素”也是一样。
- 行内级元素:inline-level element,display 为 inline、inline-block、inline-table 的元素称为行内级元素。与块级元素一样,元素是否是行内级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
- 行内级盒子:inline-level box,由行内级元素生成。行内级盒子包括行内盒子和原子行内级盒子两种,区别在于该盒子是否参与行内格式化上下文的创建。
- 行内盒子:inline box,参与行内格式化上下文创建的行内级盒子称为行内盒子。与块盒子类似,行内盒子也分为具名行内盒子和匿名行内盒子(anonymous inline box)两种。
- 原子行内级盒子:atomic inline-level box,不参与行内格式化上下文创建的行内级盒子。原子行内级盒子一开始叫做原子行内盒子(atomic inline box),后被修正了,改为了原子行内组盒子。原子行内级盒子的内容不会拆分成多行显示。
盒子的概念
盒子有不同的类型,不同类型的盒子的格式化方法也有所不同。盒子的类型取决于 CSS display 属性。
块级元素
当元素的 display 为 block、list-item 或 table 时,该元素将成为块级元素。一个块级元素会被格式化成一个块,默认按照垂直方向依次排列。例如文章中的段落,多个段落依次向下排列。
每个块级盒子都会参与块格式化上下文(block formatting context)的创建,而每个块级元素都会至少生成一个块级盒子,即主块级盒子(principal block-level box)。有一些元素,比如列表项会生成额外的盒子来放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。
一个块级盒子可能也是一个块容器盒子。块容器盒子(block container box)要么只包含其它块级盒子,要么只包含行内盒子并同时创建一个行内格式化上下文(inline formatting context)。
块级盒子与块容器盒子是不同的,前者描述了元素与其父元素,和兄弟元素之间的行为,而后者描述了元素跟其后代子元素之间的行为。
同时是块容器盒子的块级盒子称为块盒子(block box)。
块级元素示例:匿名盒子是怎么产生的?
display 为 block:
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
运行效果:
此时会产生两个匿名块盒子:
一个是 <p> 元素前面的那些文本(Some inline text),
另一个是 <p> 元素后面的文本(followed by more inline text.)
对这两个匿名盒子来说,无法像 <p> 元素那样控制它们的样式,因此它们会从 <div> 那里继承那些可继承的属性,如 color。其他不可继承的属性则会设置为 initial ,可以继承的都是inherit。
中间的p标签元素生成的是一个块级盒子。
示例2
<p style="display: inline;">Some <em>inline</em> text <span style="display: block;">followed by a paragraph</span> followed by more inline text.</p>
运行效果:
行内级元素
如果一个元素的 display 属性为 inline、inline-block 或 inline-table,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。
一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。
在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:
<style>
span {
display:inline-block;
}
</style>
<div style="width:20em;">
The text in the span <span>can be split in several
lines as it</span> is an inline box.
</div>
效果:
最佳实践
总结一下,对于上面的css视觉格式化模型,我们要了解什么是行内级元素,什么是块级元素,什么是匿名盒子及如何产生的。了解在什么情况下,元素类型会相互转换。
- 块级元素:display 为 block、list-item 或 table 时
- 行内级元素: display 属性为 inline、inline-block 或 inline-table
元素如何定位?
- 普通流:按照次序依次定位每个盒子
- 浮动:将盒子从普通流中单独拎出来,将其放到外层盒子的某一边
- 绝对定位:按照绝对位置来定位盒子,其位置根据盒子的包含元素所建立的绝对坐标系来计算,因此绝对定位元素有可能会覆盖其他元素
flex布局。
普通流定位示例
在块格式化上下文中,盒子在垂直方向依次排列;
而在行内格式化上下文中,盒子则水平排列。
当CSS的 position 属性为 static 或 relative,并且 float 为 none 时,其布局方式为普通流。
普通流又有两种情况:
静态定位和相对定位。
【静态定位】
position 为 static 时为静态定位,此时每个盒子根据普通流所计算出的确切位置来定位
示例:
<h2>普通流静态定位</h2>
<style>
.sp1 {
position: static;
width: 20px;
height: 40px;
}
</style>
<div>
<div>
<span class="sp1">11</span>
<span class="sp1">12-----12</span>
<span class="sp1">13</span>
</div>
<div>
<span class="sp1">21</span>
<span class="sp1">22-----22</span>
<span class="sp1">23</span>
</div>
</div>
效果:
【相对定位】
当 position 为 relative 时为相对定位,此时每个盒子还会根据 top、bottom、left 和 right 属性的值在其原本所在的位置上产生指定大小的偏移。
示例:
<h2>普通流相对定位</h2>
<style>
.sp2 {
position: relative;
width: 20px;
height: 40px;
}
.sp2:nth-last-of-type(2) {
left: 20px;
border: solid 1px goldenrod;
}
</style>
<div>
<span class="sp2">11</span>
<span class="sp2">12-----12</span>
<span class="sp2">13</span>
</div>
效果:
浮动定位
left、right
在浮动定位中,浮动盒子会浮动到当前行的开始或尾部位置。这会导致普通流中的文本及其他内容会“流”到浮动盒子的边缘处,除非元素通过 clear 清除了前面的浮动。
一个盒子的 float 值不为 none,并且其 position 为 static 或 relative 时,该盒子为浮动定位。
如果将 float 设置为 left,浮动盒子会定位到当前行盒子的开始位置(左侧),
如果设置为 right,浮动盒子会定位到当前行盒子的尾部位置(右侧)。
不管是左浮动还是右浮动,行盒子都会伸缩以适应浮动盒子的大小。
clear何时使用?
clear 属性指定当前这个元素,在清除浮动后,是否必须移动到在它前面的浮动元素的下面。
示例:
<h2>clear使用示例</h2>
<style>
.wrapper {
border: 1px solid black;
padding: 10px;
}
.left {
border: 1px solid black;
clear: left;
}
.black {
float: left;
margin: 0;
background-color: black;
color: #fff;
width: 20%;
}
.red {
float: left;
margin: 0;
background-color: pink;
width: 20%;
}
wrapper p {
width: 50%;
}
</style>
<div class="wrapper">
<p class="black">Lorem ipsum dolor elit. </p>
<p class="red">Lorem ipsum dolor.</p>
<p class="left">clears left.</p>
</div>
效果:
绝对定位
如果元素的 position 为 absolute 或 fixed,该元素为绝对定位。在绝对定位中,盒子会完全从当前文档流中移出。此处仅指定位和位置计算而言,元素在文档树中仍然与其他元素有父子或兄弟等关系。
绝对定位的元素,位置会使用 top、bottom、left 和 right 相对其包含块进行计算。对固定位置的元素来说,是相对视口进行绝对定位,因此滚动时元素的位置并不会改变。
absolute
通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。
fixed
元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。
两者的分别在于,absolute是相对某个非static的祖先绝对定位,而fixed是相对对整个页面绝对定位。
示例:
<h1>绝对定位示例</h1>
<style>
.menu{
position: fixed;
right: 20px;
bottom: 100px;
background-color: honeydew;
}
</style>
<dl class="menu">
<dt>菜单</dt>
<dd>分享</dd>
<dd>生成海报</dd>
</dl>
效果:
2020年9月25日
【关于作者】
李艺,笔名“石桥码农,腾讯云最具价值专家(TVP),腾讯课堂启明星俱乐部成员,日行一课联合创始人兼 CTO,前 VIPKID 资深技术专家。国内早期闪客之一,具有 15 年以上互联网软件研发经验。
参与研发的音视频直播产品曾在腾讯 QQ 上线,为数千万人使用。从 0 到 1 创建课件标准,被团队誉为课件之父,官方评定为 Adobe 中国 15 位社区管理员之一。著有《小程序从0到1:微信全栈工程师一本通》等计算机图书,是极客时间视频畅销课《微信小程序全栈开发实战》的作者,知乎 Live 讲师,在行互联网技术专家。欢迎到“在行”找我一对一约聊。
- JS魔法堂:不完全国际化&本地化手册 之 拓展篇
- 使用jQuery的animate方法制作滑动菜单
- jenkins 入门教程(下)
- CSS3制作心形头像
- CSS魔法堂:重拾Border之——不仅仅是圆角
- scala 学习笔记(01) 函数定义、分支、循环、异常处理、递归
- java之log4j的配置
- scala 学习笔记(02) 元组Tuple、数组Array、Map、文件读写、网页抓取示例
- scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类
- 使用jQuery封装实用函数
- scala 学习笔记(05) OOP(中)灵活的trait
- Web Fundamentsals学习1-Multiple-Screen-Site
- Vagrant使用
- java 中的异步回调
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例
- Linux安装Jenkins步骤及各种问题解决(页面访问初始化密码)
- 解决Ubuntu19 安装Theano问题
- centos7 esxi6.7模板实际应用详解
- Centos8搭建本地Web服务器的实现步骤
- 总结Linux 6种日志查看方法
- Ubuntu18.04一次性升级Python所有库的方法步骤
- linux下php安装xml扩展的详细步骤
- 查看linux文件的命令详解
- 解决Linux+Apache服务器URL区分大小写问题
- Centos8(最小化安装)全新安装Python3.8+pip的方法教程
- 使用 Linux seq 命令生成数字序列(推荐)
- CentOS 7上为PHP5安装suPHP的方法(彭哥)
- Linux修改主机名命令详解
- 在CentOS 7.2上安装SuPHP的详细方法
- centos6-7 yum安装php的方法(推荐)