• “fixed+relative≈≈absolute”——对BFC的再次思考


    好久没写博客了,刚好今天跨年夜没约到什么妹子,在家宅着不如写点东西好了。

    需求

    昨天晚上,给公司年会做一个移动端的投票页面,遇到一个UI优化的问题:

    · 正文内容少于一屏时,投票提交按钮固定显示在页面底部(如图一)
    · 正文内容多于一屏时,投票提交按钮,跟随内容,流式显示在内容下面(如图二)
    附图:

     

    以前做一些管理后台的时候,底部的版权信息声明就是这样的UI需求,实现思路大概就是:
    底部按钮,需要一直显示在底部,可以给body设个最小100%高度,然后用绝对定位把按钮显示在body底边靠上一点的位置,这样内容少的时候,100%的高度起作用,按钮会显示在底部,内容多的时候,内容会把body的高度撑出一屏出现滚动条,而按钮是基于body绝对定位,所以可以跟着滚动条走,一直在内容的底部显示。

    关键代码就是这样:

    html结构:
    html>body>.wrap+.bottom-bar
    
    html {
        height: 100%;
    }    
    body {
        min-height: 100%;
        position:relative;
    }
    .bottom-bar {
        position: absolute;
        bottom: 0px;
    }

    本以为轻车熟路,5-10分钟搞定的事情,因为一个bfc的问题,我硬生生调了大半夜,现在记录一下。

    问题、意外

    按照刚才的写法,内容刚好一屏的时候,提交按钮会挡住文档底部的部分内容,所以这里还需要给body设置一个下边距,值要等于bottom-bar的height。
    这个时候问题出来了:
    body下的子元素的magin-top和margin-bottom值会影响到body的渲染,进而影响到基于body做相对定位的bottom-bar。

    调试一番之后,总结了两点特征,就是块级元素&默认情况下&垂直方向的渲染规则:
    · 子元素的margin,会影响父元素的UI渲染,父元素不会被子元素的margin想当然地撑开,就是说渲染上,子元素的margin作用在了父元素上
    · 父元素的margin会被子元素的覆盖掉,如果父元素magin值比较小的话,表现就是父元素的margin被子元素的吃掉了

    此时,不由得想起来CSS2里面非常弯弯绕的一个概念,BFC。

    注:如果BFC小测试 这道题能瞬间答对的话,下面的BFC描述可以直接跳过了。

    BFC

    之前对BFC模式下margin会折叠的理解仅限于兄弟节点之间,没有意识到父子之间也有这类情况。实话说,多数中文的BFC技术文章里讲的,都是在阐述自己的理解或者抄来抄去,有些讲的模棱两可的,恐怕作者自己都没有搞清楚。

    先贴一下mdn和w3的文档供大家参考下:
    https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context
    https://www.w3.org/TR/CSS21/visuren.html#block-formatting
    https://www.w3.org/TR/CSS21/visuren.html#block-level

    备注:
    · 仔细看看w3的介绍,我相信block containers/block boxes/Block-level elements/block-level box这几个词一定会让你看得想要放弃治疗的,哈哈!
    · 另,以上英文文档看得比较费劲的,可以再参考另一位同仁对BFC解释的文章:BFC 神奇背后的原理 

    再次复习了一下BFC的概念之后,我尝试着总结一下我对这个东西的理解:
    1. Block formatting context,是一个上下文环境(可以理解为js里的作用域),这个环境中的元素,遵守块级元素的渲染规则。比如:
      · 从上到下排布,各占一行
      · 垂直方向的margin值,会在相邻节点(兄弟或父子)之间被折叠
      · 自身高度不会被子节点的margin撑大
      · 自身高度不会被浮动子节点撑开
    2. 一个默认的html文档流中,只有一个上下文环境
    3. 如果需要打破1中所述规则,需要创建一个新的上下文(establish new block formatting contexts for their contents),方法是:
      · 适用于父子/兄弟
        float:left/right、position:absolute、display:非block
      · 仅适用于父子
        overflow:非visible

    终极方案

    新年快要到了,不多说了,结合以上需求和对BFC的再次理解,直接贴代码:

    html结构:
    html>body>.wrap+.bottom-bar
    
    * {
        padding: 0;
        margin: 0;
    }
    html {
        height: 100%;
        overflow: auto;
    }
    body {
        position: relative;
        overflow: auto;
        min-height: 100%;
    }
    .wrap {
        overflow: auto;/*为了防止子元素对body产生影响,这里需要专门开辟一个新上下文*/
        margin-bottom: 40px;/*这里也可以加到body去,body{box-sizing: border-box;padding-bottom:40px;}*/
    }
    .bottom-bar {
        position: absolute;
        bottom: 0px;
        height: 40px;
        width: 100%;
    }
  • 相关阅读:
    C#开发串口总结,并提炼串口辅助类到公用类库中
    sharepoint Lists Web service 用法
    .NET简谈策略模式
    细说 Form (表单)
    步步为营 SharePoint 开发学习笔记系列 一、简介
    Memcached进行缓存层设计
    各大主流.Net的IOC框架性能测试比较
    十年磨一剑,BloodyAngel!
    hosts
    新浪微薄的挂件
  • 原文地址:https://www.cnblogs.com/youryida/p/6240547.html
Copyright © 2020-2023  润新知