阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      CSS 多栏布局

      栅格系统,是 bootstrap 常用的布局模式,下列就举个简单四栏例子

      html:

      <div class="col"></div>
      <div class="col"></div>
      <div class="col"></div>
      <div class="col"></div>
      

      css:

      .col{
          width:25%;
          height:500px;
          float: left;
          background: #ccc;
      }
      .col:nth-child(1){
          background: red;
      }
      .col:nth-child(2){
          background: green;
      }
      .col:nth-child(3){
          background: black;
      }
      .col:nth-child(4){
          background: yellow;
      }
      

      常见还有 column-count、column-gap、column-rule、columns

      1. 弹性布局 (flex) html:
      <ul>
          <li><a href="#">菜单1</a></li>
          <li><a href="#">菜单2</a></li>
          <li><a href="#">菜单3</a></li>
          <li><a href="#">菜单4</a></li>
      </ul>
      

        css:

      ul{
          display: flex;
          height:100px;
          width:100%;
      }
      ul li{
          flex: auto;
          list-style:none;
          text-align:center;
          border:1px solid red;
      }
      

      CSS 等宽布局

      //假如是n个child
      <div class="parent-fix">
          <div class="parent">
              <div class="child"><p>1</p></div>
              <div class="child"><p>2</p></div>
              <div class="child"><p>3</p></div>
              <div class="child"><p>4</p></div>
          </div>
      </div>
      

      table

      .parent-fix{
          margin-left: -20px;
      }
      .parent{
          display: table;
          width: 100%;
          table-layout: fixed;
      }
      .child{
          display: table-cell;
          padding-left: 20px;
      }
      

      flex

      
      .parent{
          display: flex;
      }
      .child{
          flex: 1;
      }
      .child+.child {
          margin-left: 20px;
      }
      

      等高布局

      <div class="parent"  style="background: black;">
          <div class="left" style="background: red;">
              <p>left</p>
          </div>
          <div class="right" style="background: green;">
              <p>right</p>
              <p>right</p>
          </div>
      </div>
      

      table

      .parent{
          display: table;
          width: 100%;
          table-layout: fixed;
      }
      .left,.right{
          display: table-cell;
      }
      .left{
          width: 100px;
          border-right: 20px solid transparent;
          background-clip: padding-box;
      }
      

      flex

      .parent{
          display: flex;
      }
      .right{
          flex: 1;
      }
      .left{
          width: 100px;
          margin-right: 20px;
      }
      

      float

      //部分UI框架采用的就是这种方式,
      .parent{
          overflow: hidden;
      }
      .left{
          float: left;
          margin-right: 20px;
      }
      .right{
          overflow: hidden;
      }
      .left,.right{
          padding-bottom: 9999px;
          margin-bottom: -9999px;
      }
      

      等分等高

      5,等分

      float + margin

      .parent {
          margin-left: -20px;
      }
      .column {
          float: left;
          width: 25%;
          padding-left: 20px;
          box-sizing: border-box;
      }
      
      

      table + margin

      .parent-fix{
          margin-left: -20px;
      }
      .parent{
          display: table;
          width:100%;
          table-layout: fixed;
      }
      .column{
          display: table-cell;
          padding-left: 20px;
      }
      

      flex

      .parent{
          display:  flex;
      }
      .column{
          flex:  1;
      }
      .column+.column{
          margin-left: 20px;
      }
      
      

      6,等高

      float + overflow

      .parent {
          overflow: hidden;
      }
      .left,.right {
          padding-bottom: 9999px;
          margin-bottom: -9999px;
      }
      .left {
          float: left;
          width: 100px;
      }
      .right {
          overflow: hidden;
      }
      

      table

      .parent {
          display: table;
          width: 100%;
      }
      .left {
          display:table-cell;
          width: 100px;
          margin-right: 20px;
      }
      .right {
          display:table-cell;
      }
      

      flex

      .parent {
          display:flex;
          width: 100%;
      }
      .left {
          width: 100px;
      }
      .right {
          flex:1;
      }
      

      7,并排等分,单排对齐靠左布局

      .main {
          display: flex;
          flex-flow: row-wrap;
          justify-content: space-between;
      }
      .item {
          display: inline-block;
      }
      .empty {
          height: 0;
          visibility: hidden;
      }
      

      6.1 等宽布局

      6.1.1四列等宽

      (1)使用float实现▲

      效果图:

      image.png

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      /*使整体内容看起来居中,抵消padding-left的影响*/
      #parent {margin-left: -20px;}
      .column{
          padding-left: 20px;  /*盒子的边距*/
          width: 25%;
          float: left;
          box-sizing: border-box;
          border: 1px solid #000;
          background-clip: content-box; /*背景色从内容开始绘制,方便观察*/
          height: 500px;
      }
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:根据父元素空间宽度平分,子元素设置浮动,用padding去模拟间隔,再给父元素一个位移抵消第一个间隔

      优缺点:

      优点:代码简单,容易理解;兼容性较好(ie8+) 缺点:需要手动清除浮动,否则会产生高度塌陷;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示

      (2)使用table实现▲

      效果图:

      image.png

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {
          height: 540px;  /*抵消上下边20*2间距的高度影响*/
          display: table;
          margin: -20px 0;  /*抵消上下边20*2间距的位置影响*/
          /*两边离页面间距无法消除,改用子元素设置padding来当成间隔就不会有这样的问题*/
          border-spacing: 20px;  /*设置间距*/
      }
      .column{display: table-cell;}
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:CSS Table以表格的形式显示

      优缺点:

      优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素

      (3)使用flex实现

      效果图:

      image.png

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {
          margin-left: -15px;  /*使内容看起来居中*/
          height: 500px;
          display: flex;
      }
      .column{
          flex: 1; /*一起平分#parent*/
          margin-left: 15px; /*设置间距*/
      }
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐

      优缺点

      优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

      6.1.2多列等宽

      效果图:

      image.png

      (1)使用float实现▲

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {height: 500px;}
      .column{
          float: left;  /*添加浮动*/
          width: 16.66666666666667%;  /*100÷列数,得出百分比*/
          height: 500px;
      }
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:根据父元素空间宽度平分,子元素设置浮动,用padding去模拟间隔,再给父元素一个位移抵消第一个间隔

      优缺点:

      优点:代码简单,容易理解;兼容性较好(ie8+) 缺点:需要手动清除浮动,否则会产生高度塌陷;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示

      (2)使用table实现▲

      html代码

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {
          width: 100%;
          height: 500px;
          display: table;
      }
      /*无需关注列数,单元格自动平分*/
      .column{display: table-cell;}
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:CSS Table以表格的形式显示

      优缺点:

      优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素

      (3)使用flex实现

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {
          height: 500px;
          display: flex;
      }
      /*无需关注列数,一起平分#parent*/
      .column{flex: 1;}
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐

      优缺点

      优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

      (4)使用Grid实现

      html代码:

      <body>
      <div id="parent">
          <div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
          <div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
      </div>
      </body>
      

      css代码:

      #parent {
          height: 500px;
          display: grid;
          grid-template-columns: repeat(6,1fr);  /*6就是列数*/
      }
      .column{}
      .column:nth-child(odd){background-color: #f00;}
      .column:nth-child(even){background-color: #0f0;}
      

      原理:css grid布局,请查看文末的阅读推荐

      优缺点

      优点:灵活划分网格区域;新型布局利器,适用于页面三维布局 缺点:兼容性不好,移动端(Android5.0+)

      6.2 九宫格布局

      效果图:

      image.png

      (1)使用table实现▲

      html代码:

      <body>
      <div id="parent">
          <div class="row">
              <div class="item">1</div>
              <div class="item">2</div>
              <div class="item">3</div>
          </div>
          <div class="row">
              <div class="item">4</div>
              <div class="item">5</div>
              <div class="item">6</div>
          </div>
          <div class="row">
              <div class="item">7</div>
              <div class="item">8</div>
              <div class="item">9</div>
          </div>
      </div>
      </body>
      

      css代码:

      #parent {
          width: 1200px;
          height: 500px;
          margin: 0 auto;
          display: table;
      }
      .row {display: table-row;}
      .item {
          border: 1px solid #000;
          display: table-cell;
      }
      

      原理:CSS Table以表格的形式显示

      优缺点:

      优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素

      (2-1)使用flex实现

      html代码:

      <body>
      <div id="parent">
          <div class="row">
              <div class="item">1</div>
              <div class="item">2</div>
              <div class="item">3</div>
          </div>
          <div class="row">
              <div class="item">4</div>
              <div class="item">5</div>
              <div class="item">6</div>
          </div>
          <div class="row">
              <div class="item">7</div>
              <div class="item">8</div>
              <div class="item">9</div>
          </div>
      </div>
      </body>
      

      css代码:

      #parent {
          width: 1200px;
          height: 500px;
          margin: 0 auto;
          display: flex;
          flex-direction: column;
      }
      .row {
          display: flex;
          flex: 1;
      }
      .item {
          flex: 1;
          border: 1px solid #000;
      }
      

      原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐

      优缺点

      优点:简单灵活;功能强大 缺点:每三个一行,对于动态创建不确定数量的元素要控制好嵌套结构,PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

      (2-2)flex优化版(不需要遵守三个嵌套一行)

      image.png

      html代码:

      <body>
      <ul>
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
      </ul>
      </body>
      

      css代码:

      * {
          margin: 0;
          padding: 0;
      }
      ul {
          width: 100%;
          background-color: #ccc;
          list-style: none;
          display: flex;
          flex-wrap: wrap;
      }
      ul > li {
          width: 33.333333333333%;
          height: 100px;
          -webkit-box-sizing: border-box;
          -moz-box-sizing: border-box;
          box-sizing: border-box;
          border: 1px solid #000;
      }
      

      原理:父元素flex并设置换行,子元素不设置伸缩,转而定宽设置宽三分之一,高度自定义,计算好宽度即能实现九宫格布局(也可以多列等宽布局)

      优缺点

      优点:简单;功能强大;不需要额外的嵌套关系,灵活运用于动态创建数量不等的元素布局中; 缺点:高度需要自定无法等宽,PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

      (2-3)flex再优化版(高度等宽九宫格)

      image.png

      html代码:

      <body>
      <ul>
          <li>
              <span>1</span>
          </li>
          <li>
              <span>1</span>
          </li>
          <li>
              <span>1</span>
          </li>
          <li>
              <span>1</span>
          </li>
      </ul>
      </body>
      

      css代码:

      *{
          margin: 0;
          padding: 0;
      }
      ul{
          width: 100%;
          margin: 0 auto;
          background-color: #ccc;
          list-style: none;
          display: flex;
          flex-wrap: wrap;
      }
      ul>li{
          width: 33.33333%;
          padding-top: 33.33333%;
          -webkit-box-sizing: border-box;
          -moz-box-sizing: border-box;
          box-sizing: border-box;
          border: 1px solid #000;
          position: relative;
          height: 0;
      }
      ul>li>span{
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background-color: #999;
      }
      

      原理:无法实现高度等宽的原因是因为宽度根据百分比而定,无法通过px去确定高度,又由于padding,width,margin这些百分比都是相对于父元素宽度的,那么只要padding-top或者padding-bottom和width的百分比一样,就能实现一个元素宽高相等,同时利用子绝父相,让子元素占满这个盒子就实现正方形的效果了,此处的span换成img同样可行,这个特性同时也适用于之前介绍的布局(比如float…)。单纯一个正方形效果,除去flex,兼容ie8+

      优缺点

      优点:简单;功能强大;高度等宽;不需要额外的嵌套关系,灵活运用于动态创建数量不等的元素布局中 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer

      (3)使用Grid实现

      CSS Grid非常强大,可以实现各种各样的三维布局,可查阅本文结尾的阅读推荐

      html代码:

      <body>
      <div id="parent">
          <div class="item">1</div>
          <div class="item">2</div>
          <div class="item">3</div>
          <div class="item">4</div>
          <div class="item">5</div>
          <div class="item">6</div>
          <div class="item">7</div>
          <div class="item">8</div>
          <div class="item">9</div>
      </div>
      </body>
      

      css代码:

      #parent {
          width: 1200px;
          height: 500px;
          margin: 0 auto;
          display: grid;
          grid-template-columns: repeat(3, 1fr); /*等同于1fr 1fr 1fr,此为重复的合并写法*/
          grid-template-rows: repeat(3, 1fr);  /*等同于1fr 1fr 1fr,此为重复的合并写法*/
      }
      .item {border: 1px solid #000;}
      

      6.3 栅格系统▲

      优缺点:

      优点:代码简洁,容易理解;提高页面内容的流动性,能适应多种设备; 缺点:浮动脱离文档流,需要清除浮动;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示

      (1)用Less生成

      /*生成栅格系统*/
      @media screen and (max-width: 768px){
        .generate-columns(12);     /*此处设置生成列数*/
        .generate-columns(@n, @i: 1) when (@i <= @n) {
          .column-xs-@{i} {
            width: (@i * 100% / @n);
          }
          .generate-columns(@n, (@i+1));
        }
      }
      @media screen and (min-width: 768px){
        .generate-columns(12);    /*此处设置生成列数*/
        .generate-columns(@n, @i: 1) when (@i <= @n) {
          .column-sm-@{i} {
            width: (@i * 100% / @n);
          }
          .generate-columns(@n, (@i+1));
        }
      }
      div[class^="column-xs-"]{
          float: left;
      }
      div[class^="column-sm-"]{
          float: left;
      }
      

      编译后的CSS代码:

      @media screen and (max-width: 768px) {
        .column-xs-1 {  width: 8.33333333%;  }
        .column-xs-2 {  width: 16.66666667%;  }
        .column-xs-3 {  width: 25%;  }
        .column-xs-4 {  width: 33.33333333%;  }
        .column-xs-5 {  width: 41.66666667%;  }
        .column-xs-6 {  width: 50%;  }
        .column-xs-7 {  width: 58.33333333%;  }
        .column-xs-8 {  width: 66.66666667%;  }
        .column-xs-9 {  width: 75%;  }
        .column-xs-10 {  width: 83.33333333%;  }
        .column-xs-11 {  width: 91.66666667%;  }
        .column-xs-12 {  width: 100%;  }
      }
      @media screen and (min-width: 768px) {
        .column-sm-1 {  width: 8.33333333%;  }
        .column-sm-2 {  width: 16.66666667%;  }
        .column-sm-3 {  width: 25%;  }
        .column-sm-4 {  width: 33.33333333%;  }
        .column-sm-5 {  width: 41.66666667%;  }
        .column-sm-6 {  width: 50%;  }
        .column-sm-7 {  width: 58.33333333%;  }
        .column-sm-8 {  width: 66.66666667%;  }
        .column-sm-9 {  width: 75%;  }
        .column-sm-10 {  width: 83.33333333%;  }
        .column-sm-11 {  width: 91.66666667%;  }  
        .column-sm-12 {  width: 100%;  }
      }
      div[class^="column-xs-"]{
          float: left;
      }
      div[class^="column-sm-"]{
          float: left;
      }
      

      ★本章小结:

      • 对于多列等宽布局,目前常用的还是浮动,宽度按百分比去平分。要是百分比的话就不太好设置margin,只能用padding去模拟间隔。又或者是固定宽度,计算好间隔,刚好填满或接近填满,这样倒是可以直接设置margin;
      • 除了浮动,其实还可以用到inline-block,但是要注意html换行或空格都会占位,有可能导致空间不够换行显示,这样就要给父元素设置一个font-size:0,然后再给设置inline-block的盒子设置所需要大小的font-size;
      • 然后就是css table布局了,想划分多少列都可以,灵活简单,就是一些不感知属性要注意;
      • 移动端兼容性允许的情况下能用flex就用flex,务必带上兼容,写法可参考文末阅读推荐,也可以使用Autoprefixer;
      目录
      目录