zoukankan      html  css  js  c++  java
  • 两列自适应布局

    两列自适应布局

    随便拿一个搜索引擎搜索一下“两列自适应布局”,都能得到很多种实现方法,这篇文章的重点是这些方法的底层逻辑是什么,他们是怎么得来的。

    分析:

    需要满足三个要求:

    ①两个盒子在同一行

    ②右边的盒子需要占满剩下的空间

    ③两个盒子不能重叠

    这三个条件又分别有很多种实现方法(不考虑绝对定位):

    组合起来,会有很多种实现方式。

    方法:

    <div class="left"></div>
    <div class="main"></div>

    1、float+block+margin:

    复制代码
    .left {
        float: left;
         100px;
    }
    .main {
        margin-left: 110px;
         100%;
    }
    复制代码

    缺点:如果想修改.left的宽度,还需要修改.main 的margin-left。

    2、float+BFC:

    复制代码
    .left {
        float: left;
        margin-right: 10px;
         100px;
    }
    .main {
        overflow: hidden; //或overflow:auto
    }
    复制代码

    优点:可以设置浮动的margin来控制间距,想要修改宽度时只修改宽度就行了。

    增加条件:

    如果需要让重要的内容先渲染,即HTML结构应该是:

    <div class="main"></div>
    <div class="left"></div>

    如果是这样的话,第一个盒子的宽度必须是100%,因为如果想要同行,他只能是float或是display:inline-block(不考虑绝对定位),这两种状态都需要设置100%来做到自适应。

    • 浮动:

    如果.main设置float的话,根据浮动流的原理,要让.main的右边出现和.left宽度相同或更多的空隙,才能让.left到上面一行来,如果要让.left贴住.main的左边线,就要制造出和.main自身相等的空隙,所以需要给.left设置margin-left:-100%;

    这时候.left就叠到了.main的上面。如果给.main设置margin-left: 100px,.left还是会叠在.main上面,因为这时候.main的宽度变小了,.left的负边距也变小了,所以不管给.main的margin-left值设置成多大,.left始终会覆盖住它。

    所以,如果想用float+margin让他们不重叠的话,只能再增加一个盒子,为其设置margin。即:

    <div class="main">
        <div class="main-content"></div>
    </div>
    <div class="left"></div>
    复制代码
    .left {
        margin-left:-100%;
        height: 400px;
        display: inline-block;  /*或者 float:left;*/
         100px;
    }
    .main {
        float: left;
         100%;
    }
    .main-content {
        margin-left: 110px;
    }
    复制代码

    除此之外还剩下两条路,一个是float+BFC,一个是position:relative。

    先看float+BFC,.main是float,但是他已经完全被后面的浮动流盖住了,所以他无法充当那个"float",显然他也无法做那个BFC,所以这条路是走不通的。

    然后看position:relative。让.main右移空出.left的位置,然后用relative将其拉出来,即:

    复制代码
    .left {
        margin-left:-100%;
        position: relative;
        left: -110px;
        display: inline-block;  /*或者 float:left*/
         100px;
    }
    .main {
        margin-left: 110px;
        float: left;
         100%;
    }
    复制代码
    • display:inline-block;

    如果让.main display:inline-block的话,必须让当前行盒留出大于.left宽度的空隙,并且让.left浮动,他们才可以到一行上去。

    想让当前行盒缩短的话,可以给.main设置左边或是右边的负边距,这会有一个副作用,就是会让.main向左或向右移动,所以,只能给他设置左边的负边距。

    到一行上面之后.main会盖住.left,这是因为在同一个堆叠上下文中,inline-block会在float的上面,所以还需要给.left设置position:relative让他显示出来。

    因为.main已经设置了负的margin-left,所以无法给.left让出空间,position:relative这条路也是没法走了。float+BFC显然也是行不通。

    所以只有一种方法:

    <div class="main">
        <div class="main-content"></div>
    </div>
    <div class="left">/div>
    复制代码
    .left {
        float: left;
        position: relative;
         100px;
    }
    .main {
         display: inline-block;
         margin-left: -100px;
         100%;
    }
    .main-content {
        margin-left: 110px;
    }

    复制代码

    总结:

    从问题出发,结合基础的知识点,可以得出以下5种实现方式:

     不要求重要内容先渲染的话,可以使用:

    1.float+margin

    2.float+BFC

    要求重要内容先渲染的话,可以:

    1.float+relative

    2.float+新盒子

    3.inline-block+新盒子

    除此之外,还有CSS3的flexbox,他的缺点是不兼容低级浏览器并且会出现一些bug。

    每个方法都有各自的优点和缺点,没有绝对的好与坏,要使用哪种方式还是要结合具体的需求来决定。

    转载http://www.cnblogs.com/LiveWithIt/p/5965605.html

  • 相关阅读:
    Vue+ElementUI 安装与应用
    python 之serial、pyusb 使用开发
    ASP.NET Swagger 创建与汉化生成 API说明文档
    DataGridView绑定数据源后动态删除行
    MySql动态拼接SQL并动态赋值
    MySql存储过程
    DEV控件之TreeList使用
    DataGridView单元格格式化
    ajax通过PUT方式调用WEBAPI
    解决跨域session 同步问题
  • 原文地址:https://www.cnblogs.com/wang1593840378/p/6049032.html
Copyright © 2011-2022 走看看