• CSS篇 第9章 Visual Formatting Model 部分翻译


       为了弄明白BFC、IFC以及定位、流的问题,翻译部分Visual Formatting Model章节要点,如下:

    注:当且属首次翻译,特别粗糙,并无与实战结合,请勿相信,仅供参考

    翻译约定:

    中文名 英文名 示例描述
    浏览器 User agents  
    box   
    元素 element  
    块级元素 block-level element  
    定位机制 positioning scheme  
    内容块 containing block  
    框的渲染/生成 box generation  
    块级框 block-level box 如:display属性为“block”、“list-item”、“table”的元素,table框、可替换元素
    块级容器框 block container box 如:不可替换的inline-block、不可替换的table cell
    块框 block box 即属于块级框、又属于块级容器框
    行内级框 inline-level box 如:display属性值为"inline"、“inline-table”,“inline-block"的元素
    行内框 inline box 如:大部分行内级框属于行内框,但是以下不属于行内框:可替换的行内级元素、inline-block元素、inline-table元素
    原子性行内级框           atomic inline-level block          如:可替换的行内级元素(如:input)、inline-block元素、inline-table元素
    可替换元素 Replaced element 如:<img>, <object>, <video>; <textarea>, <input>; 匿名可替换元素
    不可替换元素 Non-replaced element  
    流外 Out of flow 如:根元素、浮动元素、绝对定位元素
    流内 In flow  

     部分关系图:

     

    块级框、块级容器框、块框

    行内级框、参与IFC的框、行内框

     

    解释:

    1. 可替换元素

      可替换元素是一种其展现不在CSS限制范围的元素,也就是说:它的展现独立于CSS。典型的可替换元素有:

      1. <img>, <object>, <video>,       display属性为:inline

      2. 表单元素:<textarea>, <input>.     display属性为:inline-block

      3. 有些元素在特定情况下才属于可替换元素,如:<audio>, <canvas>,  display属性为:inline

      4. 使用CSS属性content插入的内容称为匿名可替换元素。

      这类元素的典型特点是:没有结束标签,因此开始结束标签之间也没有内容,内容通过属性(如:value)来指定;你也可以理解为:该标签会被外面的资源所代替。

    2. 不可替换元素:

      除上面之外的所有HTML元素称为不可替换元素。

    翻译正文:

    9.     Visual Formatting Model 可视化排版模型(简称:VFM)
    9.1     VFM介绍
      本章和下一章描述了VFM:浏览器将DOM树转换为可视化的过程。
      VMF中,DOM树中的每个元素根据框模型生成0或多个框。这些框的布局是根据以下因素控制:
      1. 框尺寸和类型(框生成方式)
      2. 定位机制(常规流、浮动、绝对定位)
      3. DOM树中元素间的关系
      4. 外部因素(例如:viewport尺寸、图片的内在尺寸等)

      (跳过Continuous media, paged media)
      VFM并没有规定排版的所有方面(如:letter-spacing算法),本规范也不会讲到不同浏览器对排版处理的差异。
    9.1.1  viewport

      (译者注:跳过不译)
    9.1.2  内容块
      CSS2.1中,许多框的position和size是根据其内容块计算的。一般来说,一个DOM元素生成的框会被后代框当做内容块,我们俗称:一个框为后代节点“建立”了内容块。短语:"一个框的内容块"指的是"包围这个框的内容块",并不是这个框生成的内容块。

      每一个框都是根据它的内容块来定位,但并不总是限制于内容块中,因为它有可能会(溢出)overflow;
      关于内容块尺寸计算的详细信息请参考下章。

    9.2   框的渲染/生成
      本小节讨论了CSS2.1中生成的框的类型,类型的不同会影响框在VFM中的处理方式。以下的display属性用于指定框的类型。

    9.2.1  块级元素、块级框
      DOM源码中,按照块排版的元素称为块级元素(Block-level element)(如:paragraph对应的p标签),当元素的display属性为“block”、“list-item”、“table”时,该元素成为块级元素;

      每一个块级元素都会生成一个"主块级框"(Principal block-level box)用于包含后代框和生成的内容,这个框会参与到定位机制和BFC中。部分块级元素(如:“list-item”)会生成除了主块框之外的额外框,这些额外框根据主块级框的位置放置。

      除了后面章节单独介绍的table框、可替换元素,一个块级框也是一个块级容器框。一个块级容器框要么只能包含块级框、或者行内框(建立一个IFC)。并非所有的块级容器框都属于块级框:不可替换的inline-block、不可替换的table cell属于块级容器框,但不属于块级框。

      同时属于块级框和块级容器框的框称为块框。

      块级框、块级容器框、块框有时一概简称为"块"。

    9.2.1.1  匿名块框
      如下的一段HTML代码:

    <DIV>
      Some text
      <P>More text
    </DIV>

      假设div和p元素的display为block,那么div就拥有了行内元素和块级元素,为了简化定义排版模型,我们假设存在一个匿名块围绕着文本some text。

      换言之,如果块级容器框(如:div元素)包含块级框(如:p元素),那么我们强制块级容器框只包含块级框,即:将some text设置为块级框,只不过是匿名的。

      当行内框的代码中包含块级框时,这个行内框(以及祖先行内框)会被分成多段围绕在这个块级框上下,因此行内框被打断成两段(即使其中一段是空文本),中间夹着块级框。考虑到上面简化的排版模型,这些前后的行内框被匿名块框包围,中间的那个块级框成为匿名块框的兄弟节点。当这样的行内框遇到相对定位时,也会影响到其中的块级框。

      这种模型也会应用到如下规则(p元素为inline,span为block)的代码中:

    p    { display: inline }
    span { display: block }
    <P>
      This is anonymous text before the SPAN.
      <SPAN>This is the content of SPAN.</SPAN>
      This is anonymous text after the SPAN.
    </P>

      p元素包含了匿名文本C1、块级元素C2、匿名文本C3,最终生成的框为:body代表一个块框,包含了一个行内框,这个行内框内部包含了:匿名块框C1、span块框、匿名块框C2。

      匿名框会从父框中继承一些可被继承的属性(如:第一个例子中的div父框),不可继承的属性会有初始值。例如:匿名框的font会被继承,但是外边距是0。

      设置在匿名框的父元素上的属性也会应用到元素本身和内容上。例如:在p元素上设置border属性,导致边框会围绕在C1(C1无右边框)和C2(无左边框)上。

      针对行内容器框设置边框,部分浏览器会有其它的处理方式。(译者注:跳过不译)

    9.2.2  行内元素、行内框
      HTML代码中,不会按照块排版的元素称为行内元素。它的内容处于一行中(如:p元素中的em元素,行内图片等)。display属性值为"inline"、“inline-table”,“inline-block"的元素称为行内级框,这些框会参与到IFC(Inline Formatting Context)中。

      当一个元素即属于行内级,且内容又参与到IFC中时,该元素称为行内框。不可替换元素的display属性为inline时称为行内框。不属于行内框的行内级框(例如:可替换行内级元素、inline-block元素、inline-table元素)称为:"原子性行内级框",因为他们会作为一个整体参与到IFC中。

    9.2.2.1 匿名行内框
      块容器元素内部的任何直接子文本都必须按照行内元素来处理(例外:内部含有块框时,会当做匿名块框处理)。

      如下的一段代码:

    <p>Some <em>emphasized</em> text</p>

      p元素生成一个块框,em元素生成一个行内框,文本"Some"和"text"生成行内框。后者称为匿名行内框,因为他们没有相关联的行内级元素将这些文本包围起来。

      匿名行内框会从父块框中继承部分属性,不可继承属性使用初始值。(如:匿名框从p元素继承了color,但background却是透明的(译者注:chrome下background也继承了))

      由于"white-space"属性不会生成匿名块,因此空白内容应该会被重叠起来。

      如果清楚匿名框在BFC、IFC中所属的类型,那么规范统称这些匿名行内框、匿名块框为匿名框。

      更多的匿名框将在后面介绍table排版时介绍。

    9.2.3 Run-in框
      display为run-in将在CSS3中定义。

    9.2.4 display属性
      初始值 inline

      下列各值的解释:
      block
      元素生成块框
      inline-block
      元素生成一个行内级的块容器框,对内是一个块框,对外则是一个原子性的行内框
      list-item
      元素生成多个行内框,如:ul元素生成一个块框,里面的li元素的display属性默认为:list-item。
      none
      元素不会出现在VFM中,不会生成框,也不会对外面的布局有影响。后代元素也不会生成框,为后代节点设置display属性无法覆盖这种方式。

      table,... 元素生成类似于table的格式。

      除了定位元素、浮动元素、根元素外,display属性计算出来的值就是设定的值。关于这三类的情况,请参考这一节”display、position、float的关系“。

      虽然display属性的初始值为inline,但浏览器的默认样式会覆盖这一值。


    9.3  定位机制
      CSS2.1中,一个框会根据三种定位机制来布局:
      1. 常规流   块级框的块排版、行内级框的行内排版、块级框与行内级框的相对定位
      2. 浮动    浮动模型中,框首先按照常规流布局,然后从常规流中去除,接着移动尽左或尽右的地方,它的内容会跟随移动。
      3. 绝对定位  该模型中,框直接从常规流中移除,然后根据这个框的内容块来计算位置

      根元素、浮动元素、绝对定位元素处于流外,不处于流外的其余元素处于流内。元素A的流包含了元素A本身、和A里面的所有最近流外祖先元素为仍A的元素。

      注意:根元素虽然处于流外,但是position属性确属于static

    9.3.1  position属性
      CSS2.1中, position和float属性决定了采用哪种定位机制来计算框的位置。

      可选值: static, relative, absolute, fixed, inherit
      初始值: static

      各值的解释:
      static
      该元素的框按照常规流布局,top, right, bottom, left属性无效
      relative
      框根据它在常规流中的正常位置进行偏移;该值对table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption元素无效。
      absolute
      框的位置根据框所在的内容块进行定位
      fixed
      框根据当前浏览器的视口定位(viewport),它不会随着页面的滚动而移动

      多数浏览器会为根元素的position属性赋值static。

    9.3.2  框偏移:top, right, bottom, left
      如果一个元素的position属性不为static,则称这个元素为定位元素。定位元素生成定位框,拥有以下四个属性:
      top
      right
      bottom
      left
      初始值 auto

      赋值类型:
      length
      不允许负值
      auto
      对于不可替换元素,该值与所属的属性top,right, bottom, left有关。详见绝对定位小节。
      对于可替换元素,其效果取决于该元素本身的尺寸。详见绝对定位小节。

    9.4  常规流
      常规流中,块级框参与BFC,行内级框参与IFC。

    9.4.1  BFC
      块框会参与到所属内容块为BFC的计算中,并非所有块框都会为其子节点建立BFC。满足下面任何一个条件即会建立BFC:
      1. float元素不为none
      2. 绝对定位元素(position不为static)
      3. 不属于块框的块容器框(如:inlien-block,table-cells, table-caption)
      4. overflow属性不为visible的块框(除非...,译者注:跳过不译)

      BFC中,框会按照垂直方向依次排列,相邻的两个块级框的margin外边距会发生重叠。
      BFC中,每个框的左外边缘贴在了内容块的左边,即使该框为float。

    9.4.2  IFC
      IFC中,行内框水平排列,margin不会发生重叠,对应的这个内容块成为行框。

      行框的width是根据其内容块决定的,高度根据line-height计算规则决定。

      (译者注:跳过不译)

    9.7  display, position, float之间的关系:
      影响框生成的三个属性:display, position, float关系如下:
      1. display为none,则position和float无效,不会生成框。
      2. 否则如果position为absolute, fixed,则float计算为none;display按下表格转换:inline变为block
      3. 否则如果float不为none,display按下表格转换
      4. 否则如果元素是根节点,display按下表格转换
      5. 否则按照display设定的值展示

    Specified valueComputed value
    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

      总结:display的值可能会变的情况是:position属性为absolute, fixed; 或者float不为none;或者根节点。

     汇总:

      从其他博客汇总来BFC的相关资料:

      BFC的用处:

      1. 自适应两栏布局          原因:BFC的区域不会与float box重叠

      2. 清除内部浮动           原因:计算BFC的高度时,浮动元素也参与计算

      3. 防止垂直 margin 重叠        原因:Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

      

      BFC的特点:

    1. 内部的Box会在垂直方向,一个接一个地放置。
    2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
    3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    4. BFC的区域不会与float box重叠
    5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    6. 计算BFC的高度时,浮动元素也参与计算

      

      如何新建BFC:

      1. float不为none

      2. position为absolute或fixed

      3. display为inline-block, table-cell, table-caption, flex, inline-flex

      4. overflow不为visible

    参考资料:

    Replaced element

    W3C Visual formatting model

     前端精选文摘:BFC 神奇背后的原理

    MDN Visual formatting model

  • 相关阅读:
    Linux下升级gcc版本(9.1.0版本)
    Linux/CentOS系统同步网络时间的2种方法详解
    为什么使用promise
    总结js深拷贝和浅拷贝
    js闭包理解
    select框实现多选的功能
    动态添加element-ui组件
    总结鼠标移入移出事件
    echarts提示框太长,导致显示不全 ,撑大div框的问题
    vue项目中管理定时器
  • 原文地址:https://www.cnblogs.com/diydyq/p/4230308.html
Copyright © 2020-2023  润新知