文档章节

Css规范整理:3.3、常规流布局:行内格式化上下文

 雕刻零碎
发布于 2018/02/10 00:51
字数 3530
阅读 385
收藏 14
Css

常规流布局

行内格式化上下文

关键概念:

  • 行内级盒:参与行内格式化上下文的盒(outer = inner )
  • 行内盒:display = inline 的不可替换元素。
  • 原子行内级盒:不属于行内盒的行内级盒。
  • 行框(line box):包含来自同一行的盒的矩形区域叫做行框。(不是一个盒,没有padding border margin)

⭐核心模型——行框:

定义:包含来自同一行的盒的矩形区域叫做行框(不是一个盒)。需要盛放(hold)行内格式化上下文中的行内级内容时,创建一个行框。(不是一个盒,因为它只有自适应的宽高以及相应的内容框)

明确一点,行内格式化上下文是构建在块容器盒内部的。 构建了行内格式化上下文的块容器盒就是个行框的垂直栈。行框在其中是没有垂直间隔地堆放(除非在其它地方有特别说明)并且它们不会重叠。

换句话说,行内格式化的包含关系是:构建了行内格式化上下文的块容器盒>>>一行行的行框>>>参与行内格式化上下文的元素>>>元素内部的行框>>>...>>>...(但记住,行框是一个模型,在页面中是不可见的,这里形成了一个行框包含链条)。

行框的宽高

行框的宽度由包含块浮动情况决定,行框的高度由**<u>行高的计算</u>**小节给出的规则决定。

宽度:

一般来说,一个行框的左边界挨着其包含块的左边界,右边界挨着其包含块的右边界。**然而,浮动盒可能会跑到包含块边界与行框边界之间。**因此,尽管同一个行内格式化上下文中的行框一般都有相同的宽度(即包含块的宽度),如果可用的水平空间因为浮动而减少了的话,它们的宽度就可能不同。

    <style>
        div{
            background: yellow
        }
        .fl{
            float: left;
            height: 100px;
            width: 100px;
            border:1px solid red;
        }
    </style>
    <section class="fl"></section>
    <div>
        <span>div内没有任何outer display type = block 的元素 ,则生成行内格式化上下文。用仅用一行的文字表示单行的行框。这里浮动把行框的宽度减少使得文字不能完全贴着包含块的左边。建议在浏览器使用缩放观察行框的变化</span>
    </div>
高度:

行框总是足够高,能够容纳它包含的所有盒。同一个行内格式化上下文中的行框一般高度各不相同(例如,一行可能含有一个高图片,而其它的只含文本)。然而,它可能比它所包含的最高的盒还要高(例如,如果盒是以基线对齐的)。见下文**<u>行高的计算</u>**。(见后文详细解析行高)。

行框的高度由下列规则决定:

  1. 计算行框中每个行内级盒的高度时,对于替换元素,inline-block元素和inline-table元素,这个值就是其外边距框(margin box)的高度;对于行内盒,这个值是其**line-height(见<u>计算height与margin</u><u>行距(Leading)与半行距</u>中的<u>行内盒的高度</u>**)【详见 行高的计算

        <style>
            .main {
                border: 1px solid red;
                line-height: 20px;
            }
            .one {
                margin: 10px;
                padding: 20px;
                display: inline-block;
                border: 1px solid green;
    
            }
            .two {
                margin: 10px;
                padding: 10px;
                border: 1px solid yellow;
                line-height: 100px;
            }
        </style>
        <div class="main">
            <span class="one">text1</span>
            <span class="two">text2</span>
            <span style="border:1px solid green;float:left">float盒对齐当前包含块<br/>(假如有)行框的顶点</span>
        </div>
    

    【因为行框高度是最高的盒的顶端与最低的盒的底端之间的距离,所以块容器盒的内容就被line-height:100px撑起了。】

  2. 行内级盒是根据其vertical-align属性垂直对齐的。如果它们是top或者bottom对齐,它们必须对齐得让行框高度最小化。如果这样的盒足够高,存在多个解,而CSS 2.1没有定义行框基线的位置(即,strut位置,见下文,这里内容的理解将在下文垂直对齐中讲述,仅仅因为这个是在规范中同一提到的内容因而写在这里)

  3. 行框高度是最高的盒的顶端与最低的盒的底端之间的距离(包括下面line-height中解释的strut

若该行框不含文本、保留空白符(preserved white space、外边距,内边距和边框非0的行内元素、 以及其它流内内容(例如,图片,行内块或行内表格),并且不以保留换行符结束的情况中,在确定其内部元素的位置时必须被当做0高度行框(有宽度)。出于其他目的时,必须当它不存在。【这我也不知道用在哪,有机会再补例子】

布局方式:

水平:在行内格式化上下文中,盒是从包含块的顶部开始一个挨一个水平放置的。这些盒之间的水平margin,border和padding都有效。【上文在行框的概念中已有论述】

垂直:盒可能会以不同的方式垂直对齐:以它们的底部或者顶部对齐,或者以它们里面的文本的基线对齐。【详见 行高的计算

盒的对齐方式

垂直:当行内级盒B的高度小于它所在的行框的高度时,行框中B的垂直对齐方式由'vertical-align'属性决定。【详见 行高的计算

水平:当一行的行内级盒的总宽度小于它们所在的行框的宽度时,它们在行框里的水平分布由text-align属性决定。如果该属性值为'justify',用户代理可能还会拉伸行内盒(不包括inline-table和inline-block盒)里的空格和单词【详见文本章节介绍文本的对齐与修饰】

    <style>
        .main {
            background: yellow;
            direction: ltr;
            /* text-align: right */
        }

        .main2 {
            background: greenyellow;
            direction: rtl;
            /* text-align: left */
        }
    </style>
    <div class="main">
        <span>text1</span>
        <span>text2</span>
        <span>text3</span>
        <span>text4</span>
        <span>text5</span>
    </div>
    <hr>
    <div class="main2">
        <span>text1</span>
        <span>text2</span>
        <span>text3</span>
        <span>text4</span>
        <span>text5</span>
    </div>

direction影响 text-align 的默认值】

盒的分割:

当几个行内级盒在水平方向上不能共存于一个行框时,它们会被分到两个或多个垂直堆叠的(vertically-stacked) 行框里。因此,段落就是个行框的垂直栈(vertical stack)。

当行内盒超出行框宽度时,它会被分成几个盒,并且这些盒会跨多行框分布。如果一个行内块无法分割(例如,如果该行内盒(只)含单一字符,或者特定语言的单词分隔规则不允许在该行内盒里分隔,或该行内盒受到了一个值为nowrap或者prewhite-space的影响),那么该行内盒会从行框溢出。【见 字母与单词间距:'letter-spacing'和'word-spacing属性

当一个行内盒被分割后,外边距,边框和内边距在发生分割的地方(或者在任何分割处,如果有多处的话)没有视觉效果

【官方例子】

<style>
    blockquote {
        text-decoration: underline;
        color: blue;
    }
    span{
        border: 10px solid red;
    }
    em {
        display: block;
        border: 10px solid green
    }
    cite {
        color: fuchsia;
    }
</style>
<blockquote>
    <p>
        <span>
            Help, help!
            <em> I am under a hat! </em>
            <cite> —GwieF </cite>
        </span>
    </p>
</blockquote>

Sample rendering of the above underline example

同一个行框里的行内盒也可能因为双向(bidirectional)文本处理而被分割成几个盒。

⭐行高的计算:line-height 与 vertical-align 属性

如行内格式化上下文节所述,用户代理把行内级盒排列在一个行框的垂直堆叠里。行框的高度由下列规则决定:

  1. 计算行框中每个行内级盒的高度时,对于替换元素,inline-block元素和inline-table元素,这个值就是其外边距框(margin box)的高度;对于行内盒,这个值是其'line-height'(见计算height与margin行距(Leading)与半行距中行内盒的高度

    【注意,当没有margin,border,padding,height 默认为auto ,受line-height 控制的时候,行内级盒和行内盒的表现是一致的。这也是我们下文中研究line-height 位置的根本】

  2. 行内级盒是根据其**'vertical-align'**属性垂直对齐的。如果它们是'top'或者'bottom'对齐,它们必须对齐得让行框高度最小化。如果这样的盒足够高,存在多个解,而CSS 2.1没有定义行框基线的位置(即,strut的位置,见下文)

    【没有定义不代表不存在,在浏览器实践中发现即可】

  3. 行框高度是最高的盒的顶端与最低的盒的底端之间的距离(包括下面'line-height'中解释的strut

空行内元素生成空的行内盒,但这些盒仍然具有margin,padding,border和line height,从而影响这些计算,就像有内容的元素一样

例子:

    <style>
        div {
            line-height: 30px;
            background: greenyellow
            
        }
        div::first-line{
            background: yellow;
        }
        span {
            background: red;
        }
    </style>
    <div>
        <span style="display:inline-block;">X</span>
        <span style="display:inline;line-height: 1px;">X</span>
        <span style="display:inline-block;line-height: 10px;">X</span>
        <span style="display:inline-block;line-height: 1px;">X</span>
        <!---->
        |
        <span style="display:inline-block;line-height: 1px;vertical-align: top;">X</span>
        <span style="display:inline;line-height: 1px;vertical-align: top;">X</span>
        <span style="display:inline-block;line-height: 1px;vertical-align: text-top;">X</span>
        
        <span style="display:inline-block;line-height: 1px;vertical-align: bottom;">X</span>
        <span style="display:inline-block;line-height: 1px;vertical-align: text-bottom;">X</span>
        <span style="display:inline-block;line-height: 1px;vertical-align: sub;">X</span>
        <span style="display:inline-block;line-height: 1px;vertical-align: super;">X</span>
        <span style="display:inline-block;line-height: 1px;vertical-align: middle;">X</span>x
        |
        <!---->
        <span style="display:inline-block;line-height: 1px;vertical-align: baseline;">X</span>
        <span style="display:inline-block;vertical-align: 10px">X</span>
        <span style="display:inline-block;vertical-align: 50%">X</span>
    </div>

从上文的例子中可以看出很多

行框高度是最高的盒的顶端与最低的盒的底端之间的距离:该例子保证块容器盒中只有一行,即只生成一个行框,以便于总结规律,推广到多行中同样可行

行框、行高、垂直对齐的总结

  • 行内格式化上下文中,一行的行框,存在两个层级

    • 1、由包含块中字体盒的大小,计算初始的行高,生成黄色部分的区域——行框的内容区的大小
    • 2、另外,绿色区域,行框内容区的溢出部分。布局时,该区域尽可能地小。
    • 上述两个区域共同形成行框。
  • 对于行框来说,里面的内容,就是各元素line-height的所形成的区域(宽=自适应字体的宽,高=line-height)

    • 在行框中的对齐就是根据 line-height 的区域的边界。
  • 行内级元素同样会有自己行框,行框高度初始继承于其包含块。

    • display:inline 的 非替换元素,就算line-height 设置为 1px 改变了行框的大小,但由于字体大于行高,所以该元素的显示还是以字体盒的高度显示的。但这并不影响行框确实设定为1px。【下文由于希望更直观看到line-height 的变化,所以均使用了display:inline-block】
  • line-height 总是位于黄色区域的中线。

    • 使用**X(大写)**的目的就是希望使用一个上下对齐(黄色区域) 的字体能够观察出line-height的初始位置。
    • 行内级元素 line-height 初始是在包含块生成的行框(黄色区域)中的中线
    • line-height 在中线位置 上下展开。
    • line-height 和字体盒没有绝对的包含关系。
  • 垂直对齐的详解

'vertical-align'

Value: baseline | sub | super | top | text-top | middle | bottom | text-bottom | 百分比值 | 绝对长度值 | inherit
Initial: baseline
Applies to: 行内级和'table-cell'元素
Inherited: no
Percentages: 参照元素自身的'line-height'
Media: visual]
Computed value: 对于百分比值 | 绝对长度值,就是绝对长度,否则与指定值相同

<u>⭐在下面的定义中,对于行内非替换元素,用于对齐的盒是那个高度为'line-height'(包括该盒的字形和两边的半行距,见上文)的盒。对于其它所有元素,用于对齐的盒都是外边距框(margin box)</u>

baseline

把盒的基线与父级盒的基线对齐。如果该盒没有基线,就把下外边距边界和父级的基线对齐

middle

把该盒的垂直中点与父级盒的基线加上父级的半x-height对齐

sub

把该盒的基线降低到合适的位置作为父级盒的下标(该值不影响该元素文本的字体大小)

super

把该盒的基线提升到合适的位置作为父级盒的上标(该值不影响该元素文本的字体大小)

text-top

把该盒的顶端和父级的内容区(content area)的顶端对齐(见10.6.1

text-bottom

把该盒的底端和父级的内容区的底端对齐(见10.6.1

百分比值

把该盒提升(正值)或者降低(负值)这个距离('line-height'值的百分比)。值'0%'表示与“基线”相同

绝对长度值

把该盒提升(正值)或者降低(负值)这个距离。值'0cm'表示与“基线”相同

下面的值让元素相对于一个行框对齐。因为该元素可能具有相对于它对齐的子级(相应的,(这些子级也)可能具有相对于它们对齐的后代),这些值使用对齐子树的边界(the bounds of the aligned subtree)。行内元素的对齐子树包括这个元素和所有'vertical-align'的计算值不为'top'或者'bottom'的子级行内元素的对齐子树。对齐子树的顶端是子树中盒的顶端最高的(位置),底端(的定义)与之类似

  • top

    把对齐子树的顶端与行框的顶端对齐

  • bottom

    把对齐子树的底端与行框的底端对齐

'inline-table'(盒)的基线是表格第一行的基线

⭐'inline-block'(盒)的基线是它的最后一个常规流中的行框的基线,除非它没有流内行框或者其'overflow'属性的计算值不为'visible',此时基线是下外边距边界

上一章:块格式化上下文 下一章:相对定位

© 著作权归作者所有

粉丝 6
博文 19
码字总数 48259
作品 0
江门
程序员
私信 提问
【前端帮帮忙】第8期 关于BFC,你需要了解的

BFC是耳熟能详的一个东西了,经常听到,其实在项目中也经常用到,比如最常用的清除浮动,自适应两栏布局等等。只是都没有去深究其原理和相关的知识点,今天就一起来好好学习一下吧。 要明白是...

大志_前端
06/02
0
0
CSS中各种布局的背后(*FC)

CSS中各种布局的背后,实质上是各种*FC的组合。CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 FFC 和 GFC。 盒模型(Box Model) 上图为W3C标准盒模型,另外还有一种IE盒模型(IE6以下),唯一的...

啊咩
2018/12/10
0
0
再读规范中浮动与定位细节

前言 如题,浮动与定位是布局中重要且基础知识点,相关规范和书籍都有篇幅解读。但具体细节,笔者初读囫囵吞枣,几经再读受益匪浅。感叹规范,简明扼要,字字珠玑 。借此行文,着笔细节,竭尽...

2017/12/30
0
0
从CSS盒子模型说起

前言 总括: 对于盒子模型,BFC,IFC和外边距合并等概念和问题的总结 原文地址:从CSS盒子模型说起 知乎专栏:前端进击者 博主博客地址:Damonare的个人博客 为学之道,莫先于穷理;穷理之要...

Damonare
2017/07/12
0
0
浅析行内元素视觉格式化

起因 前段时间组内同学在开发运营页的过程中,遇到一个有趣的问题:移动端页面采用 ,图片在垂直方向展示时会出现莫名的间隙(如下图所示)。几位同学纷纷提出不同的解决方案,但为什么会出现...

代码君的自白
2017/11/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【0918】正则介绍_grep

【0918】正则介绍_grep 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 一、正则介绍 正则是一串有规律的字符串,它使用单个字符串来描述或匹配一系列符合某个语法规则的字符串。 二、grep工具 ...

飞翔的竹蜻蜓
26分钟前
4
0
为什么要在网站中应用CDN加速?

1. 网页加载速度更快 在网站中使用CDN技术最直接的一个好处就是它可以加快网页的加载速度。首先,CDN加速的内容分发是基于服务器缓存的,由于CDN中缓存了不少数据,它能够给用户提供更快的页...

云漫网络Ruan
今天
8
0
亚玛芬体育(Amer Sports)和信必优正式启动合作开发Movesense创新

亚玛芬体育和信必优正式启动合作开发Movesense创新,作为亚玛芬体育的完美技术搭档,信必优利用Movesense传感器技术为第三方开发移动应用和服务。 Movesense基于传感器技术和开放的API,测量...

symbiochina88
今天
4
0
创龙TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA核心板规格书

SOM-TL437xF是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA芯片设计的核心板,采用沉金无铅工艺的10层板设计,适用于高速数据采集和处理系统、汽车导航、工业自动化等领...

Tronlong创龙
今天
5
0
好程序员Java学习路线分享MyBatis之线程优化

  好程序员Java学习路线分享MyBatis之线程优化,我们的项目存在大量用户同时访问的情况,那么就会出现大量线程并发访问数据库,这样会带来线程同步问题,本章我们将讨论MyBatis的线程同步问...

好程序员官方
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部