最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《重学前端》笔记--CSS排版

    正文概述 掘金(玺同学)   2020-12-06   555

    本文为winter发布在极客时间的《重学前端》的学习笔记及一些补充。

    大家支持正版喔:time.geekbang.org/column/arti…

    导语

    现在CSS提供了很多种排版方式,我们有很多选项可以选择自己适合的那一种,然而,正常流却是我们绕不开的一种排版。

    如果我们从严苛的CSS标准角度去理解正常流,规定排版的算法,就需要引入上述那些复杂的概念。但是,如果我们单纯地从感性认知的层面去理解正常流,它其实是简单的。

    盒模型(Box Model)

    在讲解CSS排版前,需要了解下CSS盒模型。

    CSS盒模型本质上是一个盒子,封装周围的 HTML 元素,包括外边距(marign),边框(border),内边距(padding),内容(content)。

    《重学前端》笔记--CSS排版

    CSS盒模型有两种,W3C的标准盒模型和IE 盒模型(怪异盒模型):

    • W3C 标准盒模型:属性widthheight只包含content,不包括borderpadding
    • IE 盒模型:属性widthheight包含borderpadding,指的是content + padding + border

    css3新增的box-sizing属性用于切换盒模型:

    • content-box 默认值,表示标准盒模型
    • border-box,表示IE盒模型

    正常流

    正常流的行为

    我们可以用一句话来描述正常流的排版行为,那就是:依次排列,排不下了换行

    在正常流的基础上,剩下的功能就是基础的延伸:

    • float

    float相关规则,使得一些盒占据了正常流需要的空间,我们可以把float理解为“文字环绕”。

    《重学前端》笔记--CSS排版

    • vertical-align

    vertical-align相关规则规定了如何在垂直方向对齐盒,设置了盒与文字是如何混合排版的。

    《重学前端》笔记--CSS排版

    • margin

    我们可以把margin理解为“一个元素规定了自身周围至少需要的空间”。

    正常流的原理

    在CSS标准中,规定了如何排布每一个文字或者盒的算法,这个算法依赖一个排版的“当前状态”,CSS把这个当前状态称为“格式化上下文(formatting context,即FC)”。

    我们可以认为排版过程是这样的:

    而我们需要排版的盒,分为块级盒和行内盒。所以排版规则了块级格式化上下文(Block Formatting Contexts,即BFC)行内级格式化上下文(Inline Formatting Contexts,即IFC),可以简单描述如下:

    • 块级格式化上下文顺次排列元素:

    《重学前端》笔记--CSS排版

    • 行内级格式化上下文顺次排列元素:

    《重学前端》笔记--CSS排版

    当我们要把正常流中的一个盒或者文字排版,需要处理以下场景:

    1. 当遇到块级盒:排入块级格式化上下文。
    2. 当遇到行内级盒或者文字:首先尝试排入行内级格式化上下文,如果排不下,那么创建一个行盒,先将行盒排版(行盒是块级,由一行中所有的内联元素所组成,所以到第一种情况),行盒会创建一个行内级格式化上下文。
    3. 遇到float:把盒的顶部跟当前行内级上下文上边缘对齐,然后根据float的方向把盒的对应边缘对到块级格式化上下文的边缘,之后重排当前行盒。

    当然,这仅仅是一个简单的逻辑,实际场景中CSS排版渲染会很复杂。

    块级格式化上下文(BFC)

    创建方式

    常见的BFC创建方式如下(更多的创建方式见这里):

    • 根元素(<html>),这里就可以理解正常流的逻辑
    • float的值不为none
    • overflow的值为autoscrollhidden
    • display的值为table-cell, table-caption, inline-block中的任何一个。
    • position的值不为relativestatic

    布局规则

    • BFC内部的块盒与行盒,会在垂直方向,一个接一个地放置(正常流)
    • 属于同一个BFC的两个相邻盒的垂直方向上的margin会发生重叠,产生折叠边距
    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    • BFC的区域不会与float元素区域重叠(可由上一条推导出)
    • 每个元素的左外边距与包含块的左边界接触(从左到右),即使浮动元素也是如此。(说明BFC中子元素不会超出他的包含块)
    • 计算BFC的高度时,浮动元素也参与计算

    BFC的作用

    上面的布局规则描述可能有些地方有点抽象,下面简单描述下BFC规则的作用:

    • 避免外边距折叠
    <div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
    
    .box1 {
      height: 20px;
      margin: 10px 0;
      background-color: green;
    }
    
    .box2 {
      height: 20px;
      margin: 20px 0;
      background-color: green;
    }
    

    根据第二条规则,这两个box会产生重叠,垂直方向上间距为20px(垂直距离取两个外边距的最大值)。 《重学前端》笔记--CSS排版

    那么,根据第三条规则,我们可以将其中一个box放在另一个BFC中,来解决这个问题(当然,解决重叠问题还有其他方案,这里只记录BFC的解决方案)。

    <div>
        <div class="wrapper">
            <div class="box1"></div>
        </div>
        <div class="box2"></div>
    </div>
    
    .wrapper {
        overflow: hidden;
    }
    

    《重学前端》笔记--CSS排版

    • 清除浮动

    清除浮动,其实就是解决浮动元素的包含块高度塌陷的问题。

    根据第五条规则,float元素会沿其容器的左侧或右侧放置。那么,在正常流中,float元素从网页的正常流动(文档流)中移除,会沿外部容器的左侧或右侧,从而导致其包含块高度塌陷。

    <div class="container">
        <div class="box">浮动元素</div>
    </div>
    
    .container {
       border: 1px solid #000
    }
    .box {
      background-color: rgba(0,255,0,0.6);
      float: left;
    }
    

    《重学前端》笔记--CSS排版

    所以,我们需要将浮动元素的包含块设置为BFC(也可以使用clear来解决)。

    .container {
       border: 1px solid #000;
       overflow: hidden;
    }
    

    《重学前端》笔记--CSS排版

    • 自适应两栏布局

    float元素会盖住下面的盒子,但是下面盒子里的文字反而还会环绕float元素。

    <div class="left"></div>
    <p>你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
       你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
       你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
    </p>
    
    .left {
      float: left;
      width: 100px;
      height: 100px;
      background-color: blue;
    }
    p {
      background-color: green;
      width: 200px;
    }
    

    《重学前端》笔记--CSS排版

    那么,我们根据第四条规则,可以将文字所在的盒设置为BFC,将两者隔开。这也是自适应布局的方案。

    p {
      ...
      overflow: hidden;
    }
    

    《重学前端》笔记--CSS排版

    而且,还可以通过设置float元素的margin-right或者padding-right实现间距效果(可以参考这篇文章)。

    .left {
      ...
      margin-right: 10px;
    }
    

    《重学前端》笔记--CSS排版

    行内级格式化上下文(IFC)

    在一个行内格式化上下文中,盒是一个接一个水平放置的,从包含块的顶部开始。

    • 这些盒水平方向的marginborder以及padding属性会起作用
    • 这些盒在垂直方向上的对齐方式可以不一样:可以顶部或底部对齐,或根据其中文字的基线对齐
    • 行盒的宽度容纳不下子元素时,子元素会换到下一行显示,并且会产生新的行盒
    • IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列

    行盒(line box)

    包含同一行的盒的矩形区域我们称之为行盒(line box)

    • 行盒的高度由line-height决定(有多个行内元素,则取line-height的最大值)。

    行盒的高度能够容纳它包含的所有盒。当盒的高度小于行盒的高度时,盒的垂直对齐方式由vertical-align属性决定。

    这里,我们可以理解为什么存在行内元素的上下间距不生效的问题。

    • 行盒的宽度由它的包含盒和float情况来决定。

    通常,行盒的左边接触到其包含盒的左边,右边接触到其包含盒的右边。但是float元素优先排列,可能让行盒的宽度缩短。

    <span class="s1">111111</span>
    <span class="s2">222222</span>
    <span class="s3">333333</span>
    <span class="s4">444444</span>
    <p>
    <span class="s1" style="float: left">111111</span>
    <span class="s2">222222</span>
    <span class="s3">333333</span>
    <span class="s4">444444</span>
    

    《重学前端》笔记--CSS排版

    由上面的例子我们可以看出,正常情况下盒之间有间距,但是存在float的情况下,盒会紧贴float元素,从而减少行盒的宽度。

    并且,当一行的行内级盒的总宽度小于它们所在的行盒的宽度时,它们在行盒里的水平分布由text-align决定。

    IFC的作用

    • 水平居中

    当一个块元素要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。

    • 垂直居中

    创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

    总结

    每一个盒的排版布局,依赖一个排版的“当前状态”,CSS称为“格式化上下文(formatting context,即FC)”。

    盒分为块级盒和行内盒,所以排版规则了块级格式化上下文(Block Formatting Contexts,即BFC)行内级格式化上下文(Inline Formatting Contexts,即IFC)


    起源地下载网 » 《重学前端》笔记--CSS排版

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元