前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10.4【前端开发】页面布局:如何理解 “CSS 视觉格式化模型”?

10.4【前端开发】页面布局:如何理解 “CSS 视觉格式化模型”?

作者头像
LIYI
发布2020-10-26 15:47:51
7790
发布2020-10-26 15:47:51
举报
文章被收录于专栏:艺述论专栏艺述论专栏

页面布局:如何理解 “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:

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。

一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。

在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:

代码语言:javascript
复制
<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 时为静态定位,此时每个盒子根据普通流所计算出的确切位置来定位

示例:

代码语言:javascript
复制
    <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 属性的值在其原本所在的位置上产生指定大小的偏移。

示例:

代码语言:javascript
复制
    <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 属性指定当前这个元素,在清除浮动后,是否必须移动到在它前面的浮动元素的下面。

示例:

代码语言:javascript
复制
    <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是相对对整个页面绝对定位。

示例:

代码语言:javascript
复制
    <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 讲师,在行互联网技术专家。欢迎到“在行”找我一对一约聊。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 页面布局:如何理解 “CSS 视觉格式化模型”?
    • 相关概念
      • 盒子的概念
        • 块级元素
          • 块级元素示例:匿名盒子是怎么产生的?
            • 示例2
              • 行内级元素
                • 最佳实践
                  • 元素如何定位?
                    • 普通流定位示例
                      • 浮动定位
                        • clear何时使用?
                          • 绝对定位
                          相关产品与服务
                          容器服务
                          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档