Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于flex布局我们应该熟悉的 #27

Open
lulujianglab opened this issue Aug 24, 2018 · 0 comments
Open

关于flex布局我们应该熟悉的 #27

lulujianglab opened this issue Aug 24, 2018 · 0 comments
Labels

Comments

@lulujianglab
Copy link
Owner

lulujianglab commented Aug 24, 2018

前言

CSS3最喜欢的新属性之一便是flex布局属性,用六个字概括便是简单、方便、快速

Flex 是 Flexible Box 的缩写,意为"弹性布局"

简单来说,就是通过给元素盒子设置一些属性,让元素盒子具有伸缩性

有别于之前的display+position+float布局,flex布局可以简便、完整、响应式地实现各种页面布局

设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效

概念

首先我们来看下下面这张图,这张图我相信了解过flex布局的人都应该见过

image

采用flex布局的弹性盒子,称为flex容器(flex container),简称“容器”

盒子里边的子元素称flex项目(flex item),简称“项目”

上图中我们还能看到容器默认存在两根轴:

水平的主轴(main axis)

垂直的交叉轴(cross axis)

主轴和交叉轴的位置是可以变换的,依赖于flex-direction,默认方向是row

属性

flex属性主要基于两块,一块是使用flex布局的盒子容器,另一块是其子元素

基于盒子容器

  • flex-direction : 主轴方向(子项目的排列方向)
  • flex-wrap : 换行 默认nowrap
  • flex-flow : flex-direction属性和flex-wrap属性的简写 默认row nowrap
  • justify-content : 项目在主轴上的对齐方向
  • align-items : 项目在交叉轴上如何对齐
  • align-content : 多根轴线的对齐方式

基于子元素项目

  • order : 项目的排列顺序
  • flex-grow : 项目的放大比例
  • flex-shrink : 项目的缩小比例
  • flex-basis : 项目占据的主轴空间
  • flex : flex-grow, flex-shrink 和 flex-basis的简写
  • align-self : 单个项目的对齐方式

接下来的内容主要是针对在项目中使用频率比较高的属性

flex-direction 主轴方向(子项目的排列方向)

默认值是row水平方向,起点在左

与之相反的就是column垂直方向,起点在上

还有两个属性值为row-reversecolumn-reverse,与row和column的区别就在于在于起点相反

有点类似于行内元素不换行与块级元素的换行

justify-content 项目在主轴上的对齐方向

justify-content 是一个非常重要的属性,它的5个属性值都是我们在项目中经常用到的,分别是:

  • flex-start(默认值):左对齐

  • flex-end:右对齐

  • center: 居中

  • space-between:两端对齐,项目之间的间隔都相等

  • space-around:每个项目两侧的间隔相等

align-items 项目在交叉轴上如何对齐

同justify-content一样,也是非常重要的属性,同样也有5个属性值,分别是:

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

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

  • center:交叉轴的中点对齐

  • baseline: 项目的第一行文字的基线对齐

  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度

demo

针对于上面的两种属性,写了个简单的demo,我们可以看下效果,也方便添加后面属性的对比

html
<div class="box">
    <div class="item"></div>
    <div class="item" id="item2"></div>
    <div class="item" id="item3"></div>
    <div class="item"></div>
</div>
css
.box {
    width: 700px;
    height: 400px;
    background-color: #EEB4B4;
    display: flex;
    justify-content: space-around;   
}
.item {
    width: 150px;
    height: 150px;
    font-size: 100px;
    border: 1px solid green;
    display: flex;
    justify-content: center;
    align-items: center;
}
效果

image

flex-grow 项目的放大比例

取值大致有三种情况:

默认值0,即使还存在剩余空间也不放大

所有子项目item取值都为1(或其他相同值),将等分剩余空间(如果有的话)

子项目item取值不相同,比如一个为2,其余都是1,那么属性值为2的item占据的剩余空间是属性值为1的2倍

demo

我们先来设置flex-grow属性值为1,效果如下:

.item{
  ...
  flex-grow: 1;
}

image

将id为item2和item3的flex-grow属性值设置为2

#item2,#item3 {
   flex-grow: 2;
}

image

flex-shrink 项目的缩小比例

这个属性的效果与flex-grow是相反的,取值也有三种情况:

默认为1,即如果空间不足,该项目将缩小

所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小

子项目item取值不相同,比如一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小

demo

先增加子项目item的数量

.box {
    ...
    <div class="item">五</div>
    <div class="item">六</div>
     <div class="item">七</div>
}

然后看flex-shrink的默认值,也就是属性值为1的情况,效果如下:

image

将id为item2和item3的flex-shrink属性值设置为0

#item2,#item3 {
   flex-shrink: 0;
}

image

所以,从flex-growflex-shrink的默认值我们可以知道

flex弹性盒子在存在剩余空间的情况下是默认不具有伸缩性的,在不存在剩余空间的情况下是默认收缩的

flex-basis 定义项目占据的主轴空间(在有剩余空间的情况下)

默认值为auto,项目本身的大小,也就是说从子项目结束后那个位置开始分配项目空间

属性值为width或height属性一样的值(比如350px),代表项目将占据的空间,也就是说从子项目开始的位置分配项目空间

demo

再次将子项目item的数量设为四个,基于最上面的样式设置,给第二个item设置width:200pxflex-basis就用默认值

#item2 {
   width: 200px;
   height: 150px;
}

image

然后将子项目.item{...}添加样式flex-basis:170px;,设置具体的数值

image

可以看到是从子项目开始的位置,重新分配项目占据空间

flex flex-grow, flex-shrink 和 flex-basis的简写

同样按上面的样式设计,有四种取值情况:

默认值是0 1 auto,代表项目在有剩余空间的情况下,不具有伸缩性;在没有剩余空间的情况下,默认压缩,且从子项目结束后那个位置开始分配项目空间

image

属性值是auto (1 1 auto) ,从子项目结束的位置分配剩余空间

image

属性值是none (0 0 auto),不分配剩余空间

image

属性值是数值(比如1),这三个值分别是

image

从子项目开始的位置分配剩余空间,同flex-basis:auto的情况相反

image

通常在项目中,我们往往是在同级子项目item宽度或高度固定的情况下,让其他子项目占据剩余空间时使用flex:1

比如,在上述情况下我们只取两个子项目item,其中一个item宽度和高度固定,另一个item设置flex:1,如下;

html
<div class="box">
    <div class="item">一</div>
    <div class="item" id="item2">二</div>
</div>
css
.box {
    width: 700px;
    height: 400px;
    background-color: #EEB4B4;
    display: flex;
    justify-content: center;   
}
.item {
    width: 150px;
    height: 150px;
    font-size: 100px;
    border: 1px solid green;
    display: flex;
    justify-content: center;
    align-items: center;
}
.item2 {
    flex: 1;
}

image
可以看到设置了flex:1的子项目占据了所有的剩余空间,并始终从头布局(父元素的justify-content: center; 可以相当于未生效)

封装

在项目开发中,我们尽量做到自己封装好flex这些常用的布局方法,比如封装到一个全局样式中,然后在之后的页面css中引入全局样式,具体可以查阅我之前用flex实现的H5页面'头尾固定,中间滚动'的项目,在该项目的global.css中就是我对flex布局常用属性的兼容性的全局封装

.flex {
    display: flex;
    /* 兼容性 */
    display:-webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
}

.direction-column {
    -webkit-box-orient:vertical;
    -webkit-box-direction:normal;
    -moz-box-orient:vertical;
    -moz-box-direction:normal;
    flex-direction: column;
    -webkit-flex-direction:column;
}

以上情况的处理往往是我们写单个网页时。在项目中常常用插件来自动实现兼容性的处理

但是为了方便,在项目中多次用flex布局时,我们也可以对齐进行封装,比如vue,可以参考博客如果说 Flexbox 之前的布局都是错的...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant