Web前端开发教程之flex布局属性(一)

kano个人技术博客 web前端开发 985 次浏览 没有评论

在css2的时代,想让元素横向排列总是一件令kano个人博客很头痛的事情,如果用float,就要为父元素加上clearfix这种类似csshack的东西,否则父元素就无法撑开,总感觉很勉为其难;亦或是用行内块,但是行内块元素之间不能有任何空隙,否则总会留出一个空格来令人头痛。

前端flex布局

上面提到的问题虽然也并不是无法解决,将父元素的font-size设为0,子元素的font-size再单独设置就可以了。凭借这两种方式虽然可以实现布局,要么需要额外的修正,要么就要用曲线救国的方式,总之就令人感觉很不自然。

 

然后css3诞生了,我们拥有了弹性flex布局方式(flex布局的中文名布局叫伸缩盒,不过这个名字并不是很常用,通常的叫法还是英文的flex),flex的出现可以说是重新定义了布局,横向布局、纵向布局、各种的对齐方式、兼容性、宽度高度的灵活伸缩——这在以前是根本无法实现的——即使你完全不了解flex布局的优势所在,你也可以很快了解到他的方便,如上面说的很令人头痛的水平布局,只要在给元素容器设置display: flex即可实现!下面将更为详细讲解flex布局的各个属性,kano个人博客带你快速的入门。

 

如果要使用flex布局,首先要设置元素的display,有关于flex的display值如下:{

display: box|inline-box|flexbox|inline-flexbox|flex|inline-flex

看着有些令人害怕,但别担心,实际上是因为w3c的修改,使得伸缩盒现在有了3个版本:{

        box|inline-box  旧版伸缩盒

        flexbox|inline-flexbox  过渡版本伸缩盒(浏览器的支持非常差)

        flex|inline-flex  新版伸缩盒

}

实际上我们现在只使用新版伸缩盒,而flex和inline-flex的外部表现类似于block和inline-block。

}

 

如果要使用flex布局,首先要将容器元素display设为flex或inline-flex,在为父元素设置了 display: flex; 但未给子元素设置任何 flex 属性的情况下,子元素会根据width或内容自适应宽度(比较像是浮动元素或 inline-block);而子元素的高度在未设置的情况下会扩展到和父元素相同(如果父元素也未设置高度的话,每个子元素的高度会扩展到和最高的子元素一样高)。

<div class="wrap">
  <div>哈哈哈</div>
  <div>哈哈哈</div>
  <div>哈哈哈</div>
</div>
.wrap {
  width: 400px;
  height: 200px;
  display: flex;
  border: 1px solid #ccc;
}

.wrap div {
  padding: 15px;
  color: white;
}

.wrap div:nth-child(1) {
  background: red;
}

.wrap div:nth-child(2) {
  background: green;
}

.wrap div:nth-child(3) {
  background: blue;
}

flex布局

文字的描述稍显复杂,不过看效果图是不是就清楚多了?

↑↑后续的讲解都会在这个例子上修改,后面只贴修改部分的代码,就不贴完整代码了↑↑

flex布局的css属性共有10个——的确很多,但学习后就会发现其实很好理解,下面详细介绍这些属性:

1. flex-grow

值:<数字>

默认:0

说明:设置弹性盒子的扩展比率,不允许负值

 

这个属性是用来控制如何分配父元素的剩余空间的,举例说明比较容易说清楚:

.wrap div:nth-child(1) {
  background: red;
  width: 100px;
}

.wrap div:nth-child(2) {
  background: green;
  width: 100px;
  flex-grow: 1;
}

.wrap div:nth-child(3) {
  background: blue;
  width: 100px;
  flex-grow: 2;
}

flex布局

上面的例子中,3个div都设了宽度为100px,父元素宽度为400px:div2占剩余空间1份,div3占剩余空间2份:{

总剩余空间为父元素宽度减去所有子元素的宽度:400px – 100px * 3 = 100px

总剩余空间会分为所有子元素的flex-grow之和份,在本例中为 1 + 2 = 3 份

 

div1 = 100px

div2 = 100px + 100px * (1 / 3) = 133.33px ≈ 133px

div3 = 100px + 100px * (2 / 3) = 166.66px ≈ 167px

}

看似复杂实际上是不是很简单,等等,如果我们不规定width的话会怎么样?

.wrap div:nth-child(1) {
  background: red;
  /*width: 100px;*/
}

.wrap div:nth-child(2) {
  background: green;
  /*width: 100px;*/
  flex-grow: 1;
}

.wrap div:nth-child(3) {
  background: blue;
  /*width: 100px;*/
  flex-grow: 2;
}

flex布局

当我们把宽度注释掉,似乎出现了一个很奇怪的结果,不过我们可以慢慢分析,div1的并未加flex-grow,其宽度是“哈哈哈”3个字加上15px的padding的自然结果,所以3个div的自然宽度实际上是78px,我们重新做下计算:{

总剩余空间:400px – 78px * 3 = 166px

 

div1 = 78px

div2 = 78px + 166px * (1 / 3) = 133.33px ≈ 133px

div3 = 78px + 166px * (2 / 3) = 188.66px ≈ 189px

}

计算并没有什么区别,只是如果宽度不做规定的话,计算剩余宽度要考虑元素的自然宽度。

在实际的应用中,因为随着内容的多少元素的自然宽度总在变化,使用多个flex-grow且不规定元素的宽度的话会使布局变的难以预测,所以多数情况下是会规定一下元素的宽度的。

2. flex-shrink

值:<数字>

默认:1

说明:设置弹性盒的收缩比率,不允许负值

 

和flex-grow相反,这个属性是在所有子元素的宽度之和大于父元素的时候来决定元素收缩多少的,你可能注意到了属性的默认值为1,这样默认情况子元素宽度就不会超出父元素的宽度了。

.wrap div:nth-child(1) {
  background: red;
  width: 200px;
}

.wrap div:nth-child(2) {
  background: green;
  width: 200px;
  flex-shrink: 1;
}

.wrap div:nth-child(3) {
  background: blue;
  width: 200px;
  flex-shrink: 2;
}

flex布局

每个div的宽度都设置为了200px,而父元素的宽度为400px,这样子元素的宽度就大于父元素了,计算如下:{

总超出空间:200px * 3 – 400px = 200px

超出空间分成的份数:1 + 1 + 2 = 4份(注意div1没有给flex-shrink,默认为1)

 

div1 = 200px – 200px * (1 / 4) = 150px

div2 = 200px – 200px * (1 / 4) = 150px

div3 = 200px – 200px * (2 / 4) = 100px

}

3. flex-basis

值:<数字>|<百分比>|auto

默认:auto

说明:设置弹性盒伸缩基准值

 

在 flex-direction(后面会讲)为row时相当于width,flex-direction为column时相当于height。如果同时设置了flex-basis和width/height,则以flex-basis为准。

这个属性我几乎没有怎么用过,一般我还是用width/height。

※ 推测可能是因为flex-grow和flex-shrink的存在,w3c的老家伙们可能是觉得width/height不能像平常的块元素一样定义多少就是多少,所以引入了一个叫“基准值”的新名词(这一段仅为kano个人技术博客观点)。

(篇幅原因,请移步Web前端开发教程之flex布局属性(二),下一篇中,我们会介绍flex-direction,align-content两个属性)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Go