• 多栏自适应布局+水平垂直居中+清除浮动——集锦


    前言

    首先声明在这篇博客里我将不会细说每一个知识点(比如什么是BFC,什么是flex等等),我主要是总结一下自己对标题中所列三个知识点的一些方法。

    一、多栏自适应布局

    首先,在这里我将从最简单的两栏固定布局慢慢讲到多栏自适应布局。

    1.固定布局

    说到固定布局想必大家已经觉得无爱了,但我还是要简单地讲一下,下面通过一个简单的实例进行讲解:

    html代码:

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

    css代码:

    .wrap{
      width:500px;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .left{
      width:200px;
      height:400px;
      background:#ccc;
    }
    .right{
       width:300px;
       height:400px;
       background:#ddd;
    }

    我们希望的布局效果是500px宽的容器内分别有一个200px宽和300px宽的子元素容器,可此时运行结果为:

    5AUJTVB~)}IAM~3913()5F4_thumb[1]

    这是因为div元素是块级元素,默认是会占据整行的,于是我们就采用浮动的方法来解决这个问题。

    此时我们只需要再添加如下样式:

    .left,.right{
      float:left;
    }

    那么就能得到我们想要的结果了:

    NF`QG4~)Y)[)VY%TD}(YRJ2_thumb[2]

    由于这里只有两栏布局,而且都是固定布局,并且刚好占满父容器,所以第二个子元素右浮动也是一样的效果。但如果是多栏布局(比如四栏布局)并且刚好占满父容器的话,那么最后一个可以是左浮动或者右浮动。

    对于两栏固定布局,其实并不一定两个子元素都需要左浮动,可以第一个子元素左浮动,第二个设置margin-left值撑开就行了:

    .left{
      float:left;
    }
    .right{
      margin-left:200px;
    }

    这样也能实现上面的效果。但如果是多栏固定布局,个人觉得还是浮动比较方便。

    在固定布局中,除了浮动之外,还有一种比较常用的方法就是定位。

    把上面的样式代码改一改:

    .wrap{
      position:relative;
    }
    .left{
      position:absolute;
      top:0;
      left:0;
    }
    .right{
       position:absolute;
       top:0;
       left:200px;
    }

    这样写同样能达到之前的那种效果,但定位布局比较烦的就是得精确计算每一块的位置。

    所以,个人觉得目前固定布局一般会结合浮动+定位+必要时的内外边距来进行布局会更加实用。当然了,浮动+定位+内外边距也同样适用于自适应布局,彼此之间都不是等号关系的。

    2.两栏自适应布局

    同样是上面的实例,我把它改成自适应布局:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .left{
      width:40%;
      height:100%;
      float:left;
      background:#ccc;
    }
    .right{
       width:60%;
       height:100%;
       float:left;
       background:#ddd;
    }

    此时运行看一下结果:

    $Q3Q)~TMTM]_{%H8NL7()@T_thumb[1]

    因为现在已经改成流式布局了,所以容器的宽度会随着浏览器的宽度而按比例缩放。当然,需要配合浮动或者定位。

    但是CSS3提供了一种更好的弹性伸缩布局flexbox,看看怎么实现:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
      display:flex;
    }
    .left{
      flex:2;
      background:#ccc;
    }
    .right{
       flex:3;
       background:#ddd;
    }

    是不是更简单。所以说,不管多少栏布局(实际开发中也不会很多栏的),通过流式布局或者flexbox弹性伸缩布局基本能解决。但目前来说,弹性布局兼容性还不是很好,所以用得比较多的还是移动端布局,但总体上更多的还是使用流式布局,必要时可以配合媒体查询。

    既有固定布局也有自适应布局

    还是上面的实例,现在两栏布局第一个子元素固定宽度,而第二个子元素自适应剩余的宽度,该怎么做?

    第一种方法就是给第二个子元素加左外边距,挤出来:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .left{
      width:200px;
      height:300px;
      float:left;
      background:#ccc;
    }
    .right{
       height:100%;
       margin-left:200px;
       background:#ddd;
    }

    结果就是这样的:

    72LU~RHH1XJ6O8FB8K$PK`L_thumb[1]

    第二种方法就是绝对定位+外边距:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
      position:relative;
    }
    .left{
      width:200px;
      height:300px;
      background:#ccc;
      position: absolute;
      top:0;
      left:0;
    }
    .right{
       height:100%;
       background:#ddd;
       margin-left:200px;
    }

    但其实第一种方法和第二种方法原理是一样的,换汤不换药罢了。

    第三种方法,利用BFC特性:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .left{
      width:200px;
      height:300px;
      background:#ccc;
      float:left;
    }
    .right{
       height:100%;
       background:#ddd;
       overflow: hidden;
    }

    这里给第二个子元素设置了overflow:hidden之后呢,它就生成了一个BFC块,BFC其中的一个布局规则就是不会和float box 发生重叠,于是就和第一个浮动了的子元素隔开了,我说得比较苍白,大家可以去多了解BFC的一些布局特性,包括如何生成一个新的BFC块。那为了方便,我这里就把BFC的一些相关知识点直接放上来给大家了解一下:

    BFC布局规则:
    • 内部的Box会在垂直方向,一个接一个地放置。
    • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
    • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    • BFC的区域不会与float box重叠。
    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    • 计算BFC的高度时,浮动元素也参与计算
    哪些元素会生成BFC:
    • 根元素
    • float属性不为none
    • position为absolute或fixed
    • display为inline-block, table-cell, table-caption, flex, inline-flex
    • overflow不为visible

    OK,还有一种方法就是flex布局:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
      display:flex;
    }
    .left{
      width:200px;
      height:300px;
      background:#ccc;
    }
    .right{
       height:100%;
       background:#ddd;
       flex:1;
    }

    是不是也挺方便的?现在我提升一下难度,现在是三栏布局,左右栏固定宽度,中间自适应,该怎么做?

    这时候flex布局就是最佳的选择了:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
      display:flex;
    }
    .left{
      width:200px;
      height:300px;
      float:left;
      background:#ccc;
    }
    .right{
        width:200px;
       height:300px;
       float:right;
       background:#ddd;
    }
    .center{
        height:100%;
        background:#666;
        flex:1;
    }

    这种本来就很苦恼的布局,对于flex布局来说都能轻松解决意外烦恼。

    且慢,如果我想让中间的子元素优先渲染呢?

    <div class="wrap">
       <div class="center">中间自适应栏</div>
       <div class="left">左边固定栏</div>
       <div class="right">右边固定栏</div>
    </div>

    这时的情况是这样的:

    [{6O_ZOOV4ELX(~63{C]0UE_thumb[1]

    这时候吧,还是得利用flex来解决这个问题:

    .wrap{
      width:80%;
      height:400px;
      border:1px solid red;
      margin:0 auto;
      display:flex;
    }
    .left{
      width:200px;
      height:300px;
      float:left;
      background:#ccc;
      order:1;
    }
    .right{
        width:200px;
       height:300px;
       float:right;
       background:#ddd;
       order:3;
    }
    .center{
        height:100%;
        background:#666;
        flex:1;
        order:2;
    }

    这时候出来的效果就是我们想要的:

    HRKDFY]ADRI9`BUQ){KZZTL_thumb[1]

    好的,关于多栏自适应布局我就讲到这里,其他方面的知识扩展与应用,就留给大家去研究了。

    二、水平垂直居中

    水平居中最常用的就是text-align:center; 和 margin:0 auto; 其中text-align:center;是对内部子元素(inline/inline-block)起作用,而margin:0 auto;是对元素自身(block)起作用,具体根据自己的需要适当地运用。

    垂直居中常用的有line-height 和 vertical-align:middle,但是它们都有使用的限制条件或者前提吧。比如line-height得和height一样高,vertical-align:middle 只对inline-block起作用,但其实还有很多坑,个人不怎么喜欢使用vertical-align。

    下面我们就直接进入水平垂直居中的讨论吧:

    其实吧,水平垂直居中也是有两种情况:知道宽高 和 不知道宽高。

    1.已知宽高的水平垂直居中

    在这种情况下,其实就很好解决了,实例说明一下:

    html代码:

    <div class="wrap">
       <div class="child">水平垂直居中</div>
    </div>

    默认样式:

    .wrap{
      width:400px;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .child{
      width:200px;
      height:200px;
      background:#ccc;
    }

    现在的情况是这样的:

    360截图20150907094514427

    因为我们是已知宽高的,所以可以给子元素加外边距挤到中间位置,或者通过绝对定位到中间位置,当然还有一些方法,我就放在未知宽高的情况下再介绍,因为已知宽高包含于未知宽高,所以为了避免重复,我就分开了,这里就只讲仅适合已知宽高的情况。

    我们给子元素加上外边距:

    .child{
      margin-top:100px;
      margin-left:100px;
    }

    这时内部子元素就水平垂直居中了。

    EXK{G1@JN8Y_7@R0M5VPCOT

    现在使用绝对定位来实现:

    .wrap{
      position:relative;
    }
    .child{
      position:absolute;
      top:50%;
      left:50%;
      margin-top:-100px;
      margin-left:-100px;
    }

    貌似绝对定位比较麻烦,但其实绝对定位对整体布局更好一些,也是比较常用。

    2.未知宽高的水平垂直居中

    1.绝对定位+css3 transform:translate(-50%,-50%)

    .wrap{
      position:relative;
    }
    .child{
      position: absolute;
      top:50%;
      left:50%;
      -webkit-transform:translate(-50%,-50%);
    }

    2.css3 的flex布局

    .wrap{
      display:flex;
      justify-content:center;
    }
    .child{
      align-self:center;
    }

    3.table布局

    <div class="wrap">
       <div class="child">
              <div>sadgsdgasgd</div>
       </div>
    </div>
    .wrap{
      display:table;
      text-align:center;
    }
    .child{
      background:#ccc;
      display:table-cell;
      vertical-align:middle;
    }
    .child div{
        width:300px;
        height:150px;
        background:red;
        margin:0 auto;
    }

    table布局貌似得多套一层,试了好多遍,两层都出不来效果。但是这种html结构太冗余了。所以前两种比较新潮一些。

    OK,水平垂直居中就讲到这里,以上都是自己琢磨的一些方法,有什么纰漏或者不恰当的地方,欢迎留言指正。

    三、清除浮动

    这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。

    下面我就讲三种常用清除浮动的方法,够用了。

    1.在浮动元素后面加一个空的div,并为它清除浮动

    html代码:

    <div class="wrap">
       <div class="float">浮动</div>
       <div class="clear"></div>
       <div class="nofloat">不想被浮动影响</div>
    </div>

    css代码:

    .wrap{
      width:500px;
      height:400px;
      border:1px solid red;
      margin:0 auto;
    }
    .float{
      width:200px;
      height:200px;
      background:#ccc;
      float:left;
    }
    .nofloat{
        width:300px;
        height:150px;
        background:red;
    }

    现在虽然加了一个空的div,但是并没有给它清除浮动,所以目前的效果就是第三个子元素.nofloat还是收到浮动的影响。

    360截图20150907132503001

    OK,现在给.clear加上清除浮动:

    .clear{
        clear:both;
    }

    刷新一下效果就出来了:

    360截图20150907132808775

    PS:这种情况比较适合元素之间是垂直排列布局的,为了不受彼此浮动的影响。

    2.利用BFC特性清除浮动

    html代码:

    <div class="wrap">
       <div class="float">浮动</div>
       <div class="nofloat">不想被浮动影响</div>
    </div>

    css代码:

    .wrap{
      width:500px;
      border:1px solid red;
      margin:0 auto;
      overflow:hidden;
    }
    .float{
      width:200px;
      height:200px;
      background:#ccc;
      float:left;
    }
    .nofloat{
        width:300px;
        height:150px;
        background:red;
        overflow:hidden;
    }

    效果是这样的:

    360截图20150907134136407

    这里父容器是没有设置固定高度的,本来第一个子元素浮动之后,父元素的高度会塌陷到跟第二个子元素一样高,但由于这里分别给第二个子元素和父元素都设置了overflow:hidden ,所以它们都生成了一个新的BFC区域,根据上文提供的BFC布局规则可以得知:BFC区域不会与float box 重叠;计算BFC高度时浮动元素的高度也参与计算。所以就得到清除浮动的效果。说得比较绕,但其实清除浮动得根据自己开发中的实际情况合理使用。

    3.使用:after伪元素,给浮动元素的父元素清除浮动

    html代码:

    <div class="wrap">
       <div class="float">浮动</div>
    </div>

    css代码:

    .wrap{
      width:500px;
      border:1px solid red;
      margin:0 auto;
    }
    .float{
      width:200px;
      height:200px;
      background:#ccc;
      float:left;
    }

    此时子元素浮动了,脱离了文档流,所以父元素高度酒塌陷了:

    360截图20150907134730403

    可以看到父元素的边框挤在一起了。

    OK,现在给父元素添加一个clearfix类:

    <div class="wrap clearfix">
       <div class="float">浮动</div>
    </div>
    .clearfix{
        *zoom:1;
    }
    .clearfix:after{
        content:'clear';
        display:block;
        height:0;
        clear:both;
        overflow:hidden;
        visibility:hidden;
    }

    现在刷新后的效果就是:

    360截图20150907135058497

    这种方法和BFC清除浮动个人用的比较多,实际开发中,其实这两种就够用了。

    好的,清除浮动我也就简单地提到这里!

    总结

    以上我总结了自己对标题中列出的三个知识点——(多栏自适应布局,水平垂直居中,清除浮动)的一些个人积累。如果有什么错误的话,欢迎留言指正。

    若需转载,请注明出处,谢谢合作!

  • 相关阅读:
    [代码保留]ORA01033: ORACLE initialization or shutdown in progress
    我的重构步骤:重构两份过程一致、中间数据类型不一致的超长函数
    C# 由UTF8 BOM头引发的两个问题(C#去BOM头)
    XPath 基本语法
    Check Browser Compatibility for CSS3 and HTML5 features
    【Mrak】C# 文本文件 ANSI编码格式 转 UTF8
    SQL 过滤重复数据
    重构具有相似“过程”的代码的经验总结(以方法为例)
    POS 收款机资料整理
    WinForm中的暗杀杀手——相对路径
  • 原文地址:https://www.cnblogs.com/jr1993/p/4788718.html
Copyright © 2020-2023  润新知