美文网首页
CSS 布局套路

CSS 布局套路

作者: _ClariS_ | 来源:发表于2019-12-31 22:22 被阅读0次

    一、布局流程


    布局流程图

    二、布局原则


    1. 尽量不要写死widthheight
    2. 尽量使用高级语法,如calcnth-childflex
    3. 如果是 IE,就全部写死

    三、float 布局与 flex 布局


    float 布局

    1. 子元素上写float: left(right)
    2. 父元素(容器)上加.clearfix
     .clearfix::after{
         content: '';
         display: block; /*或者 table*/
         clear: both;
     }
     .clearfix{
         zoom: 1; /* IE 兼容*/
     }
    

    清除浮动示例
    导航栏示例

    flex 布局

    详见阮一峰老师的这篇文章 Flex 布局教程:语法篇

    四、布局示例


    这里以做一个PC端和移动端的布局为例

    PC端:

    1. 用 float 实现平均布局

    做平均布局时经常会碰到宽度不够的情况,就像下面这样

    上图中,元素宽度的总和超出了容器的宽度,因此最后一个元素就跑到下一行去了

    针对该问题,有以下几种解决方法供大家参考

    方法一:使用nth-child

    使用nth-child将上图中奇数个元素的margin-left和偶数个元素的margin-right分别设置为0即可

    <div class="pictures clearfix">
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
    </div>
    
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
    }
    .picture {
      width: 194px;
      height: 194px;
      background: #ddd;
      margin: 4px;
      float: left;
    }
    .picture:nth-child(4n+1) { /*1和5*/
      margin-left: 0;
    }
    .picture:nth-child(4n) { /*4和8*/
      margin-right: 0;
    }
    

    查看效果:http://js.jirengu.com/vazaqivoja/2/edit?html,css,output

    如果要兼容IE等不支持nth-child语法的浏览器,可以使用“负margin”法。

    方法二:负margin

    该方法即在父子之间加一层wrapper,在wrapper上设置负数的margin

    <div class="pictures">
       <div class="picture-wrapper clearfix">
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
       </div>
    </div>
    
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
    }
    .picture {
      width: 194px;
      height: 194px;
      background: #ddd;
      margin: 4px;
      float: left;
    }
    .pictures > .picture-wrapper{
      margin:0 -4px;
    }
    

    查看效果:http://js.jirengu.com/mogenujaci/2/edit?html,css,output

    2. 用 flex 实现平均布局

    方法一:使用flex的space-between属性
    <div class="pictures">
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
    </div>
    
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
      display:flex;
      flex-wrap:wrap;
      justify-content:space-between;
    }
    .picture {
      width: 194px;
      height: 194px;
      background: #ddd;
      margin:4px 0;
    }
    

    查看效果:http://js.jirengu.com/yohebomuqo/2/edit?html,css,output

    但是,如果仅仅只是使用space-between也是会有缺陷的(上面说的几种方法不会出现该问题),如下图,我们删掉了一个picture,会发现第二排并不是像我们期望的那样依次排列,最后留下一个空位。

    为了解决这个问题,可以使用 flex + 负margin

    方法二:flex + 负margin
    <div class="pictures">
       <div class="picture-wrapper">
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
         <div class="picture"></div>
       </div>
    </div>
    
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
    }
    .picture {
      width: 194px;
      height: 194px;
      background: #ddd;
      margin: 4px;
    }
    .pictures > .picture-wrapper{
      display:flex;
      flex-wrap:wrap;
      margin: 0 -4px;
    }
    

    查看效果:http://js.jirengu.com/sedabamohe/2/edit?html,css,output

    此方法和上面float布局中的“负margin”差不多,只是picture-wrapper上可以少写一个.clearfix

    小优化:使用calc属性
    .pictures {
      width: 800px; /*使用calc属性后,去掉此宽度,伸缩页面试试看*/
      background: green;
      margin: 0 auto;
    }
    .picture {
      width: calc(25% - 8px);/* 808x25% - 8px */
      height: 194px;
      background: #ddd;
      margin: 4px;
    }
    

    查看效果:http://js.jirengu.com/gimaverune/5/edit?html,css,output

    这里使用calc属性的好处是,如果元素是不定宽/高的话,页面伸缩时可以保持比例不变。

    3. 中间存在空隙的左右布局

    <div class="art clearfix">
       <div class="sider">广告1</div>
       <div class="main">广告2</div>
    </div>
    
    .art{
      background: #ddd;
      width: 800px;
      margin: 0 auto;
    }
    .art > .sider{
      float: left;
      width: 33.333333%;
      border: 1px solid;
      height: 100px;
    }
    .art > .main{
      float: left;
      width: 66.666666%;
      border: 1px solid;
      height: 100px;
    }
    

    此时如果我们想让底部两个广告之间产生空隙该如何做呢?

    使用float来做

    方法一:内部加div
    <div class="art clearfix">
       <div class="sider">
         <div class="sider-child">广告1</div>
       </div>
       <div class="main">
         <div class="main-child">广告1</div>
       </div>
    </div>
    
    .art{
      background: #ddd;
      width: 800px;
      margin: 0 auto;
    }
    .art > .sider{
      float: left;
      width: 33.333333%;
    }
    .art > .main{
      float: left;
      width: 66.666666%;
      border: 1px solid;
      height: 100px;
    }
    .sider-child{
      margin-right: 20px;
      border: 1px solid;
      height: 100px;
    }
    

    查看效果:http://js.jirengu.com/cayiziribu/2/edit?html,css,output

    方法二:使用calc属性
    <div class="art clearfix">
       <div class="sider">广告1</div>
       <div class="main">广告2</div>
    </div>
    
    .art{
      background: #ddd;
      width: 800px;
      margin: 0 auto;
      display: flex;
    }
    .art > .sider{
      float: left;
      width: calc(33.333333% - 20px);
      margin-right: 20px;
      height: 100px;
      border: 1px solid;
    }
    .art > .main{
      float: left;
      width: 66.666666%;
      border: 1px solid;
      height: 100px;
    }
    

    查看效果:http://js.jirengu.com/tacanacohu/2/edit?html,css,output

    使用flex来做

    方法一:margin-right:auto

    此时需要去掉html中.art上的.clearfix类,然后把上面方法二中的.art加上display: flex;并去掉float: left;,最后把.art > .sider中的margin-right: 20px;改为margin-right: auto;即可
    查看效果:http://js.jirengu.com/canemojiju/3/edit?html,css,output

    方法二:space-between

    在方法一的基础上去掉margin-right: auto;,然后在.art中加上justify-content: space-between;即可
    查看效果:http://js.jirengu.com/dusuputata/2/edit?html,css,output

    移动端:

    1. 首先加一个meta:vp
    2. 使用媒体查询做响应式的导航栏
      首先去掉min-width: 600px;
    .parent .menu{
      display: none;
    }
    @media (max-width: 420px){
      .parent .menu{
        display: block;
      }
      .parent .nav{
        display: none;
      } 
    }
    
    1. 自适应的banner
      PC上定宽,移动端自适应
    .banner {
      width: 800px;
      height: 300px;
      background: #888;
      margin: 0 auto;
      margin-top: 10px;
    }
    @media (max-width: 420px){
      .banner{ width: auto; }
    }
    
    1. 自适应的pictures
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
    }
    @media (max-width: 420px){
      .pictures{ width: auto; }
    }
    
    1. 从PC一行四张图变为移动端一行两张图
    .picture {
      width: calc(25% - 8px);
      height: 194px;
      background: #ddd;
      margin: 4px;
    }
    @media (max-width: 420px){
      .picture { 
        width: calc(50% - 8px); 
      }
    }
    
    1. 底部广告变为上下结构
    .art{
      background: #ddd;
      width: 800px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
    }
    @media (max-width: 420px){
      .art { 
        width: auto; 
        flex-direction: column;
      }
    }
    .art > .sider{
      width: calc(33.333333% - 20px);
      height: 100px;
      border: 1px solid;
    }
    @media (max-width: 420px){
      .art > .sider { 
        width: auto; 
        height: auto;
      }
    }
    .art > .main{
      width: 66.666666%;
      border: 1px solid;
      height: 100px;
    }
    @media (max-width: 420px){
      .art > .main { 
        width: auto; 
        height: auto;
      }
    }
    

    解决bug:

    1. 解决移动端页面左右滑动的一个bug(负margin造成的)
      解决:加overflow: hidden;
    .pictures {
      width: 800px;
      background: green;
      margin: 0 auto;
      overflow: hidden; /* 解决bug */
    }
    
    1. 这里banner存在一个问题,就是当缩小到移动端时,宽度变为auto,高度却没变,这会导致图片发生形变
      解决:不使用img标签,使用CSS的background: url来设置背景图
    .banner {
      width: 800px;
      height: 300px;
      background: #888;
      margin: 0 auto;
      margin-top: 10px;
      background: transparent url(https://ftp.bmp.ovh/imgs/2019/12/fea07c39f3654cff.jpg) no-repeat center;
      background-size: cover; /* 尽可能保持图片比例 */
    }
    

    另外,如果非要缩小后保持图片的固定比例,请搜索固定比例div

    最终完成的布局(PC端 + 移动端):http://js.jirengu.com/panukozaxu/3/edit?html,css,output
    加入响应式导航栏:http://js.jirengu.com/giquheqogu/2/edit?html,css,output

    相关文章

      网友评论

          本文标题:CSS 布局套路

          本文链接:https://www.haomeiwen.com/subject/kmomoctx.html