日常工作中,前端常常会与布局打交道,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 常见的子项属性有:
order;
flex-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; } }}