为了账号安全,请及时绑定邮箱和手机立即绑定

css布局 - 九宫格布局的方法汇总

标签:
Html5 CSS3 面试

这是我们开发中很常用的九宫格布局,请看效果:

https://img1.sycdn.imooc.com//5c060d860001be8811480769.jpg

主要总结了几种实现方式:

  1. margin负值实现

  2. 祖父和亲爹的里应外合

  3. 换个思路 - li生了儿子帮大忙。

  4. 借助absolute方位值,实现自适应的网格布局

  5. cloumn多栏布局

  6. grid

  7. display: table;

  8. css3选择器nth-child()


写在前面的话:

除非特别说明,以下几种方式的通用html结构如下:

<div class="box">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
    </ul>
  </div>

除特别说明,布局中用到的css reset代码如下:

/* 基础 */
 .box{
     background: #e4f7fd61;
     border: 2px solid #0786ada1;
     border-radius: 8px;
}
 ul{
     padding: 0;
}
 .box li{
     list-style: none;
     text-align: center;
     line-height: 200px;
     background: rgba(146, 203, 230, 0.65);
     border-radius: 8px;
}


方法一、margin负值实现

原理 : margin负边距

关键点 : 

  1. 最外层的包裹元素等于:li宽度*3+li右间距*2

  2. 如果li是右间距,则ul的margin-right为负的li间距值。

  3. 父元素ul使用overflow:hidden;形成bfc,以清除浮动带来的影响(父元素塌陷)。

  4. margin-bottom和margin-top的配合,是同right的理的,消除最后一排li撑开的底边距。

  5. li要浮动。外边距方向和ul设置负值的外边距方向一致。

关键代码

.box{
     width: 940px;
}
 ul{
     overflow: hidden;
     margin-right: -20px;
     margin-bottom: -20px;
     margin-top: 0;
}
 .box li{
     float: left;
     width: 300px;
     height: 200px;
     margin-right: 20px;
     margin-bottom: 20px;
}


方法二、祖父和亲爹的里应外合

原理:外层box盒子overflow和ul元素宽度死值相结合

其实换一种角度和思路,又是一个解决方法,不用margin负值,我们想要li要对其ul两端效果,之所以纠结是因为li又需要margin-right,而右边最后一个li的margin又会撑开和父亲ul的距离,让我们头疼。
那既然是节外生枝,我们直接让祖父砍掉多出来的那一节不就行了?父亲ul设置宽度,坚持让儿子占他的位置,而box祖父就做一个坏人,使用overflow砍掉多余出来的一个margin-right的距离。

关键点

  1. box使用overflow:hidden;无情的砍掉li的右margin

  2. ul唱白脸,设置宽度坚持让三个li并排站,而不让最后一个li因为没地方挤到下一排。

  3. li 做最真诚的自己

关键代码

因为做demo都在一个html里,防止类名覆盖,这里原来叫box的盒子改叫sec了

.sec{
     width: 640px;
     overflow: hidden;
}
 ul{
     width: 660px;
     overflow: hidden;
     margin-bottom: -20px;
     margin-top: 0;
}
 .sec li{
     float: left;
     width: 200px;
     height: 200px;
     margin-right: 20px;
     margin-bottom: 20px;
}

https://img1.sycdn.imooc.com//5c0791610001854906300670.jpg

https://img1.sycdn.imooc.com//5c0791630001853806190620.jpg

方法三、换个思路 - li生了儿子帮大忙。

看下边这个图片理解实现原理:

https://img1.sycdn.imooc.com//5c060d870001659806380703.jpg

间距不一定要加在父元素li身上的,父元素li可以只负责流体布局,内部用padding或第一层子元素来控制和相邻元素的间距

原理:图片中的红色边框,是li元素,红色边框总的深红区域是li元素内部的子元素。

红边框和子元素之间的白色距离是子元素的margin生成。

关键点

  1. 父元素box以前20的内边距,这次改成10,因为外孙li>div会帮忙的。

  2. li不再设置margin-right来撑开多个li之间的距离

  3. li内部的div设置左右margin来撑开li和li以及li和父元素之间的距离。

关键代码

这里html结构就要变化一下,除了之前的结构,li内部要多加一个div结构了,作用就是撑开间距。

<div class="sec02">
    <h3>
      里应外合-li的边距交给孩子们来做,自己只负责一排站三个人的排列工作
    </h3>
    <div class="box">
      <ul>
        <li><div>1</div></li>
        <li><div>2</div></li>
        <li><div>3</div></li>
        <li><div>4</div></li>
        <li><div>5</div></li>
        <li><div>6</div></li>
        <li><div>7</div></li>
        <li><div>8</div></li>
        <li><div>9</div></li>
      </ul>
    </div>
</div>

样式:

.box{
     padding: 20px 10px;
     display: inline-block;
     background: #ff000026;
}
 ul{
     overflow: hidden;
     width: 600px;
     margin-bottom: -10px;
     margin-top: 0;
     background: none;
}
 li{
     list-style: none;
     float: left;
     width: 198px;
    /*可以用百分比*/
     height: 198px;
    /*可以用百分比*/
     margin-bottom: 10px;
     border: 1px solid red;
}
 li > div{
     background: rgba(255, 0, 0, 0.24);
     margin: 0 10px;
     border-radius: 8px;
     text-align: center;
     line-height: 198px;
}

去掉红色border后的效果:

https://img1.sycdn.imooc.com//5c060d90000180f806440672.jpg

li与嫡长子的左边距作用于浅红和深红之间的左边距,

li嫡长子的右边距和下一个li嫡长子的左边距综合 构成了两个li之间的间距。


方法四、借助absolute方位值,实现自适应的网格布局

自适应?先来一波效果图:

https://img1.sycdn.imooc.com//5c060d8800012f8405400900.jpg

额,这是动图,需要点击看大图才会动。否则就得去我博客看了。

原理:absolute+四个方位值撑开局面、float+宽度百分比实现横向排列。高度百分比实现自适应。

关键点

1. page最外层的父元素使用absolute负责占位,给子元素们把空间拉开。或者用宽高也行

https://img1.sycdn.imooc.com//5c060d8f000185ca04780254.jpg

2. 每一个块的父元素list利用浮动和33.33%的宽度百分比实现横向自适应排列

3. 本案例中,list元素内部用了伪元素+absolute的方式做了效果展示,实际项目中,list元素里边就可以填充自己个各式各样的业务代码了。

关键代码

https://img1.sycdn.imooc.com//5c06103d00015b2903450436.jpg

https://img1.sycdn.imooc.com//5c061046000146e003770837.jpg


方法五、cloumn多栏布局

原理:cloumn设置三栏布局,这种还是自适应效果的

关键点

  1. box依旧做了最严格的祖父,又是宽度限制,又是overflow决绝设卡。

  2. ul这次挑了大梁,针对内部的li使用column多栏布局,设置为三栏显示,且每一栏之间

  3. 而有了ul的操心,li则美滋滋的做起了公子哥,只管自己的宽高和下边距就好,右边距他爹都给他处理好了。

关键代码

https://img1.sycdn.imooc.com//5c0610d300013f5f03110440.jpg

方法六、grid

原理:用CSS Grid 创建网格布局,是最简单也是最强大的方法。

关键点

  1. 九个单元的父元素wrapper设置display为grid类型(注意兼容写法)

默认九个元素就会堆叠排序。

https://img1.sycdn.imooc.com//5c060d900001933e03750207.jpg

2. 设置每一行中单个元素的宽度: grid-template-columns,每个宽度值100px根据业务需要设置。

给三个设置了宽度就长这样了。

https://img1.sycdn.imooc.com//5c060d910001d65f03750091.jpg

3. 设置每一列中单个元素的高度: grid-template-rows,每个高度值100px根据业务需要设置。

最后出现我们想要的效果:

https://img1.sycdn.imooc.com//5c060d91000131a203750316.jpg

关键代码

https://img1.sycdn.imooc.com//5c0611830001733604110635.jpghttps://img1.sycdn.imooc.com//5c06118a00016f4304130257.jpg

方法七、display:table;

原理:其实他就是table的css版本

https://img1.sycdn.imooc.com//5c4e6b310001416806190661.jpg

原理

    原理:其实他是table的css版本处理方式。原谅我只能想到加结构、模拟tr+td的方式实现了。

    好处:也是唯一能用来安慰自己的地方就是,不用table标签少了很多reset样式~

关键点

    1. 三行li,每个li里三列div(模拟表格的结构)

    2. 父元素ul使用display: table(此元素会作为块级表格来显示(类似 <table>),表格前后带有换行符。)

    3. li元素使用display: table-row(此元素会作为一个表格行显示(类似 <tr>)。)

    4. li元素内部三个子元素使用display: table-cell(此元素会作为一个表格单元格显示(类似 <td> 和 <th>))


关键代码

html:

<ul class="table">
      <li>
        <div>1</div>
        <div>2</div>
        <div>3</div>
      </li>
      <li>
        <div>4</div>
        <div>5</div>
        <div>6</div>
      </li>
      <li>
        <div>7</div>
        <div>8</div>
        <div>9</div>
      </li>
    </ul>


css:

.table {
      display: table;
    }
    .table li {
      display: table-row;
      background: #beffee;
    }
    .disTable li:nth-child(odd) {
      background: #bec3ff;
    }
    .table li div {
      width: 200px;
      line-height: 200px;
      display: table-cell;
      
      text-align: center;
    }
    .table li:nth-child(odd) div:nth-child(even) {
      background: #beffee;
    }
    .table li:nth-child(even) div:nth-child(even) {
      background: #bec3ff;
    }

方法八、css3选择器nth-child();

原理:利用css的选择器,选择对应个数的li,设置特殊样式。


不足

li必要要设置固定的宽高,且ul也要设置固定宽高,以强制使得li“归位”。

关键点

1. li.nth-child(3n):控制第3以及3的倍数的li的右边距不存在。

关键代码

https://img1.sycdn.imooc.com//5c0611b70001bfe803220660.jpg

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
78
获赞与收藏
516

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消