zoukankan      html  css  js  c++  java
  • CSS布局经典问题:两栏布局-左侧固定,右侧自适应

    这个问题在开发时碰过非常多次,是经典布局问题。很多公司的面试题也会问这类问题,今天就详细的来谈一下这类问题。


    还有一篇类似的文章,关于三栏布局 详情请戳


    题意非常明确,左侧的块宽度是固定的,右侧的宽度会随着浏览器的宽度变化的,见下图。

    1.BFC

    为了解决这个问题,首先,我们来理解一下何为BFC。

    BFC(Block Formatting Context)直译为“块级格式化范围”。

    BFC提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。它不会影响到其它环境中的布局。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干。

    触发BFC的条件
    1. float的值不为none。
    2. overflow的值不为visible。
    3. display的值为table-cell, table-caption, inline-block中的任何一个。
    4. position的值不为relative和static。

    为了加深我们理解BFC为何物,下面看一个例子,上代码。

        .wrapper{ border: 5px solid #000; }
        .red { background-color:red; }
        .yellow { background-color:yellow; }
        .orange { background-color:orange; }
        .green { background-color:green; }
        .box{ 100px; height:100px; float:left; }
    
        <div class="wrapper">
            <div class="container">
                <div class="red box"></div>
                <div class="yellow box"></div>
            </div>
            <div class="container">
                <div class="orange box"></div>
                <div class="green box"></div>
            </div>
        </div>
    

    见效果:

    很明显,.wrapper中所有的box都是浮动,父级标签没有被内容撑开,虽然.red、.yellow和.orange和.green是在两个不同的div中,但是仍不会换行。这是由于设置了浮动元素的块会形成一个BFC布局,前面提到过了:

    1. 对于一个BFC来说它不会影响到其他环境的布局,反之亦然。
    2. 在BFC中,每一个元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此。
    3. 当容器有足够的剩余空间容纳BFC的宽度时,所有浏览器都会将BFC放置在浮动元素所在行的剩余空间内。
    4. 在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。
    5. 在计算生成了BFC 的元素的高度时,其浮动子元素应该参与计算。
      故呈现了这样的效果。

    若想要让每一个.container中的元素都单独占据一行,可以让.container变成BFC布局(overflow:hidden)。

    看到这里。相信你对BFC也有一定的理解了。如若不理解,可以看看这篇文章,有可取之处。
    关于Block Formatting Context--BFC和IE的hasLayout

    关于IE的layout可以看看这篇文章
    IE的layout属性详解


    2.左侧固定,右侧自定义布局实现

    回到题目,下面来看看如何实现左侧固定,右侧自适应布局

        <div class="container">
            <div class="left"></div>
            <div class="right"></div>
        </div>
    

    2.1利用BFC之方法一

    由于在BFC中,每一个元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此。创建了BFC的元素不能与浮动元素重叠。且当容器有足够的剩余空间容纳BFC的宽度时,所有浏览器都会将BFC放置在浮动元素所在行的剩余空间内。利用这些特性,就可以达到效果。

        .left{
            float: left;
             200px;
            height: 200px;
            background: green;
        }
        .right{
            overflow: hidden;
            height: 300px;
            background: red;
        }
    

    2.2利用margin-left

    首先还是设置left浮动让他变为BFC,由2.1方法可知,在BFC中,每一个元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此。所以left和right会重叠。然后利用margin-left让right腾出位置。

            .left{
                float: left;
                 200px;
                height: 200px;
                background: green;
            }
            .right{
                margin-left: 200px;
                height: 300px;
                background: red;
            }
    

    2.3使用绝对定位

    同样,这个方法和2.2方法类似,也是left的形成BFC方式不同,就不过多描述了。

        .container{
            position: relative;
        }
        .left{
            position: absolute;
            left: 0;
            top: 0;
             200px;
            height: 200px;
            background: green;
        }
        .right{
            margin-left: 200px;
            height: 200px;
            background: red;
        }
    

    2.4利用flex布局

    flex布局走天下阿。。但是兼容性问题还是摆在那里,有所取舍吧。

        .container{
            display: flex;
            display: -webkit-box;
            display: -moz-box;
            display: -ms-flexbox;
            100%;
            height: 200px;
        }
        .left{
             200px;
            background: green;
        }
        .right{
            // 如果此处用100%会导致左侧元素不足固定宽度,因为left+right的宽度大于父级宽度,会进行一个等比缩放
            //100%;
            flex:1;
            background: red;
        }
    

    2.5利用grid布局

     .container{
            display: grid;
            grid-template-rows: 200px;
            grid-template-columns: 200px auto;
            100%;
        }
        .left{
            background: green;
        }
        .right{
            background: red;
        }
    

    2.6利用table-cell

     .container{
            display: table;
            100%;
        }
        .left{
            display: table-cell;
            height: 200px;
             200px;
            background: green;
        }
        .right{
            display: table-cell;
            height: 200px;
            background: red;
        }
    

    知识扩展

    前面提到了BFC,与之类似的还有IFC,GFC,FFC。。很晕吧,贴上两个链接,希望你看了能有所收获。
    CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
    css3之BFC、IFC、GFC和FFC


    以上内容,如有错误请指出,不甚感激。

  • 相关阅读:
    OC学习小总结
    导航控制器
    稍微完善了一些的简单计算器的设计
    android端腾讯性能监控框架Matrix源码分析之第一篇
    android MVP模式介绍与实战
    android声音检测仪---分贝仪 (附源码)
    我的几个开源项目
    结合支付宝和微信首页巩固android事件分发机制 (附项目源码)
    SLAM论文阅读笔记
    Python之可迭代对象、迭代器、生成器
  • 原文地址:https://www.cnblogs.com/adelina-blog/p/6781945.html
Copyright © 2011-2022 走看看