CSS之flex与grid布局

1,005

日常工作中,前端常常会与布局打交道,position ,float,虽然有其特色,但是也容易出现问题;这里主要通俗的介绍两类功能强大的布局flex与grid 及一些简单的应用实例;

1、flex布局

这里参考www.jianshu.com/p/4290522e1…

使用flex布局的元素称为容器,需要设置display:flex;容器包含的元素就是容器的子项。容器和子项分别拥有各自的样式属性;容器的属性是为了布局子项的,子项的属性是为了布局其包含的内容和元素的;

1.1 常用的容器属性有:

flex-direction;
flex-wrap;
flex-flow;
justify-content;
align-items;
align-content;

1.1.1 flex-direction属性

     该属性主要是控制子项的排布方向,属性值有:row |row-reverse|column|column-reverse

row:子项横向排列,从左到右;

row-reverse:子项横向排列,从右到左;

column:子项纵向排列,从上到下;

column-reverse:子项纵向排列,从下到上;

1.1.2 flex-wrap属性

         该属性主要是控制子项排列的换行方式;属性值有:nowrap|wrap|wrap-reverse

         nowrap:不换行;

         wrap:换行;

         wrap-reverse:换行,但是第一行会在下方;

1.1.3 flex-flow属性

        该属性其实就是 flex-direction与flex-wrap两个属性的简写合集,使用如:

        flex-flow: row nowrap;

1.1.4 justify-content属性

        该属性是常用属性,控制子项的在flex-direction属性排列方向下的对齐方式;属性值有:

       flex-start | flex-end | center | space-between | space-around

       flex-start:从主轴起始端对齐;

       flex-end:从主轴末端对齐;

       center: 沿着主轴居中对其

       space-between:两端对齐,子项之间间隔相同;

       space-around:子项两端间隔相同;

1.1.5 align-items属性 

         该属性定义了在交叉轴上的对其方式(相对与flex-direction主轴的交叉轴);属性值               有:flex-start | flex-end | center | baseline | stretch |

          flex-start:交叉轴的起始端对齐;

          flex-end:交叉轴的末端对齐;

          center:交叉轴的居中对齐;

          baseline:子项的第一行文字基线对齐;

          stretch:子项无高度或auto,使用该属性将占满容器的高度;

1.1.6 align-content属性

          该属性定义了多根轴线的对齐方式,可以理解为多行子项的对齐方式,一行子项使用该            属性无效果;

          属性值有: flex-start | flex-end | center | space-between | space-around | stretch

           flex-start:与交叉轴的起点对齐;

           flex-end:与交叉轴的终点对齐;

           center:与交叉轴的中点对齐;

           space-between:与交叉轴两端对齐,轴线之间的间隔平均分布;

           space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的                                        间隔大一倍;

           stretch(默认值):轴线占满整个交叉轴;

1.2 常见的子项属性有:

orderflex-grow;
flex-shrink;
flex-basis;
flex;
align-self;

1.2.1 order属性

        该属性定义了子项的排列顺序,数字越小,排的越靠前,不常用,默认值为0;

1.2.2 flex-grow属性

        该属性默认值为0,其主要定义了一行或一列中子项的宽或高的占比,如果一行中的子项          该属性值相同,则占比一样;如果值越大占比越大;占比值2是占比值1的二倍;如果其            它子项没有设定该属性,只有一个子项设定,则该子项将占满剩余空间;

1.2.3 flex-shrink属性

        该属性定义了子项的缩放比例;默认值为1,空间不足时会缩小子项;如果设定子项的              flex-shrink属性值为0时,则空间不足时,其它子项缩放,该子项不缩放;(使用该属性          可以解决换行对齐问题)

1.2.4 flex-basis 属性

        该属性不常用,其定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏            览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小;

1.2.5 flex 属性

        该属性是flex-grow, flex-shrink 和 flex-basis三个属性的组合简写,

        默认值为flex: 0 1 auto;

1.2.6 align-self 属性

         该属性,允许子项脱离容器的align-items属性,进而有自己的对齐方式,默认值为auto;

         属性值有:auto |flex-start | flex-end  |center | baseline | stretch

         属性值与align-items的功能相同;

1.3 相关实例与知识点

1.3.1 flex相关实例

        这里展示一些移动端的一些实例,PC端类似;

        1、常用的就是居中布局; 代码如下:

.container{
    display:flex;
    flex-direction:row;
    justify-content:center;
    align-items:center;
}

       2、文字对齐,可换行

<div class="w-style">  
    <span class="right-margin">任务地点</span>  
    <span class="time-style">*******地点</span>
</div>

.w-style {    
    display: flex;    
    flex-direction: row;    
    font-size: 12px;    
    font-family: PingFangSC, PingFangSC-Regular;    
    font-weight: 400;    
    text-align: left; 
   color: rgba(20, 40, 65, 0.5); 
     .time-style {      
     color: #142841;    
    } 
   .right-margin {      
    margin-right: 15px;      
    width: 48px;      
    flex-shrink: 0;    
    }  
}

        3、可以使用flex布局,如下设计侧边样式:

          

代码如下:

<div class="mint-content">      <div class="content-box" v-for="index in 5" :key="index">        <div class="box-left">          <div class="dot"></div>          <div class="line"></div>        </div>        <div class="box-right">          <p>            <span>2020.08.18 19:17</span>            <span>陈四</span>          </p>          <div class="task-detail">            <div class="task-tip">任务详情</div>            <div class="task-content"></div>          </div>        </div>      </div>    </div>  </div>

.content-box {  margin: 0 15px;  display: flex;  flex-direction: row;  .box-left {    display: flex;    margin-right: 10px;    flex-direction: column;    transform: translateY(10px);    .dot {      width: 10px;      height: 10px;      border-radius: 5px;      background-color: rgba(20, 40, 65, 0.3);    }    .line {      margin-left: 4px;      width: 1px;      flex: 1;      background: rgba(20, 40, 65, 0.3);    }  }  .box-right {    flex: 1;    p {      margin-top: 5px;      span:first-child {        color: rgba(20, 40, 65, 0.6);      }      span:last-child {        margin-left: 10px;        color: brown;      }    }    .task-detail {      margin: 15px;      .task-tip {        color: rgba(20, 40, 65, 0.6);      }      .task-content {        margin-top: 10px;        background: rgba(20, 40, 65, 0.1);        width: 100%;        height: 160px;      }    }  }}

      4、圣杯布局;

1.3.2:同时子项中,仍然可以采用display:flex,对自己的内部元素进行布局;

           形成嵌套的独立模块;

小结:我们也可以看出来flex布局,常常处理一些一维的布局,采用flex嵌套可以处理一些二维             的布局,比如上图圣杯布局,但是对于二位布局有更好的放式,那就是grid布局;

2、Grid布局:

      grid实现了网格布局,可以同时控制行和列;详细可以参阅这篇讲的不错的文章              juejin.cn/post/685457… ;grid布局同样拥有容器属性和子项属性;下面简单总结一下:

2.1 容器属性

grid-template-columns;
grid-template-rows;grid-auto-columns;
grid-auto-rows;

grid-row-gap;
grid-column-gap;
grid-gap;

grid-template-areas;
grid-auto-flow;

justify-items;
align-items;

justify-content;
align-content;
place-content;

2.1.1 grid-template-columns 和 grid-template-rows属性:

        grid-template-columns :控制列的(显式)宽度;

        grid-template-rows :控制行的(显式)高度;

.contaainer {
  grid-template-columns: 200px 200px 200px; /*每一列宽度相同,简单写法 repeat(3,200px)*/
  grid-template-rows: 100px 200px;
  grid-gap:20px; /*这里下面介绍*/
}

   可以看出,上图一共为2行3列,每一类的宽度为200px,第一行的高度为100,第二行的高度为     200px;

2.1.2 grid-auto-columns 和 grid-auto-rows属性:

         grid-auto-columns :控制(隐式)列宽;

         grid-auto-rows :控制(隐式)行高;

        显式与隐式是相对的,假如:grid-template-columns 和 grid-template-rows属性:            设定了相应的行和列的尺寸则其为显示,如果超出了对应的行和列则需要采用grid-auto-         columns 和 grid-auto-rows属性来设置其对应的列宽和行高,则其为隐式的;

       grid-template-columns 和 grid-template-rows属性以及 grid-auto-columns 和 grid-         auto-rows属性,在一些情况下可以混合使用,比如:

      1、3列多行,则行高为200px 列宽为200px;

grid-template-columns:repeaat(3,200px);
grid-auto-flow: row;/* 控制布局方向*/
grid-auto-rows:200px;

       2、3行多列 ,

grid-template-rows:repeaat(3,200px);
grid-auto-flow:column;/* 控制布局方向*/
grid-auto-columns:200px;

2.1.3 grid-row-gap 和 grid-column-gap 和 grid-gap属性:

         这三个属性常用来控制子项的间隔,顾名思义:

         grid-row-gap:控制行与行之间的间隔;

         grid-column-gap:控制列与列之间的间隔;

         grid-gap: 是前两者的简写形式,新版弃用了以上几个属性,采用gap属性;

2.1.4  justify-items 属性、align-items 属性以及 place-items 属性    

          这三个属性,分别控制子项中内容的对齐方式 :

           justify-items控制水平位置:左、中、右、拉伸占满子项;

           align-items控制垂直方向的位置:上、中、下、拉伸占满子项

           place-items是以上两个属性的简写,顺序是align-items、justify-items。如果只设置             一个值,则两个属性设为同一个值;

.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
  place-items: align-items属性值 justify-items属性值;
}

2.1.5 justify-content 属性、align-content 属性以及 place-content 属性

        这三个属性与flex的容器属性相似,只是这里操控的是多行与多列;

         justify-content :整个内容区域在容器里面的水平位置(左中右);

         align-content:整个内容区域的垂直位置(上中下);

         place-content:是以上两个属性的简写形式,顺序为:align-content、 justify-content;

.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

        space-around - 每个子项两侧的间隔相等。所以,子项之间的间隔比子项与容器边框的          间隔大一倍 

       space-between - 子项与子项的间隔相等,子项与容器边框之间没有间隔             

       space-evenly - 子项与子项的间隔相等,子项与容器边框之间也是同样长度的间隔 

       stretch - 子项大小没有指定时,拉伸占据整个容器

2.1.6 grid-template-areas属性

         该属性与子项的grid-area属性一同使用,用来划分一定的布局区域,在子项中使用grid-area对子项进行命名,在容器中使用grid-template-areas属性,划分区域;   

.container {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 120px  120px  120px;
  grid-template-areas:
    ". header  header"
    "sidebar content content";
  background-color: #fff;
  color: #444;
}

.sidebar {
  grid-area: sidebar;
}

.content {
  grid-area: content;
}

.header {
  grid-area: header;
}

以上代码,命名的子项一共有三个,在容器中,使用grid-template-areas属性,划分为6个区域,"."代表一个空区域,名字相同的区域融为一大块区域,如下图:

2.2 子项属性

grid-column-start;
grid-column-end;
grid-row-start;
grid-row-end;

grid-area;

justify-self;
align-self;
place-self;

2.2.1 grid-column-start 属性、grid-column-end 属性、grid-row-start 属性以及

        grid-row-end 属性

        grid根据行和列的设定划分出一定的网格区域,区域中包含了子项,以上四个属性,其实          就是利用网格线来定位子项的区域位置;

        grid-column-start 属性:左边框所在的垂直网格线 

        grid-column-end 属性:右边框所在的垂直网格线 

        grid-row-start 属性:上边框所在的水平网格线 

        grid-row-end 属性:下边框所在的水平网格线

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
  grid-auto-rows: minmax(100px, auto);
}
.one {
  grid-column-start: 1;
  grid-column-end: 2;
  background: #19CAAD;
}
.two { 
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 2;
  /*   如果有重叠,就使用 z-index */
  z-index: 1;
  background: #8CC7B5;
}
.three {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 4;
  background: #D1BA74;
}
.four {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 5;
  background: #BEE7E9;
}
.five {
  grid-column-start: 2;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 5;
  background: #E6CEAC;
}
.six {
  grid-column: 3;
  grid-row: 4;
  background: #ECAD9E;
}

2.2.2 grid-area属性

         可以理解为在子项中使用,为子项命名;常与grid-template-areas属性一块使用;

2.2.3 justify-self 属性、align-self 属性以及 place-self 属性

         justify-self 属性设置子项内容的水平位置(左中右),跟 justify-items 属性的用法完            全一致,但只作用于单个子项 

        align-self 属性设置子项内容的垂直位置(上中下),跟align-items属性的用法完全                一致,也只作用于单个子项

       place-self 是设置 align-self 和 justify-self 的简写形式

justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;

2.3 使用案例

<div class="sport-box">        <div          class="sport-item"          v-for="(item, index) in EventList"          :key="item.EventId"          :style="{background: getBgColor(index)}"        >        </div>      </div>

.sport-box {  padding: 15px 13px;  display: grid;  grid-template-columns: repeat(4, 1fr);  grid-auto-flow: row;  grid-auto-rows: 100px;  gap: 10px;  .sport-item {    border-radius: 6px;    box-shadow: 0px 2px 4px 0px rgba(0, 145, 250, 0.35);    text-align: center;    img {      margin: 11px auto 0px;    }  }}