flex的探究

前几天看到一个面试题,关于网页栅栏化的实现,查找了一下资料,发现有几种方法,一种是利用 float,但是这个方法需要注意的点较多,第二种方法就是 css3 的 display:flex。

当我看到这个词,突然想起之前自己在写个人网站的时候也遇到过这样的布局,当时因为只是储备还不够,理解的也不深刻,如今再次遇见,便想好好查找一下资料,借着刚搭成的博客,写一篇对这个的认识和总结。

display:flex

Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

CSS3 弹性盒子(Flexible Box 或 Flexbox),是一种布局方式,当页面需要适应不同的屏幕大小以及设备类型时,它依然能确保元素拥有更恰当的排布行为。对很多应用程序来说,当不使用浮动,且弹性容器的外边距也不需要与其内容的外边距合并时,弹性盒子模型比起方框模型要好一些。

许多设计师会发现弹性盒子模型更易于使用。弹性盒子中的子元素可以在各个方向上进行布局,并且能以弹性尺寸来适应显示空间。由于元素的显示顺序可以与它们在源代码中的顺序无关,定位子元素将变得更容易,并且能够用更简单清晰的代码来完成复杂的布局。这种无关性是仅限制于视觉呈现上的,语音顺序以及基于源代码顺序的导航均不受影响。

任何元素都可以指定为 Flex 布局(包括行内元素)。

<style>
 .container {
    display: -webkit-flex;
    display: flex;  //定义Flex容器
 }
 .initial {
   -webkit-flex: initial;
        flex: initial;
   width: 200px;
    min-width: 100px;
 }
 .none {
    -webkit-flex: none;
        flex: none;
    width: 200px;
 }
 .flex1 {
    -webkit-flex: 1;
        flex: 1; //在剩余空间占1份
 }
 .flex2 {
    -webkit-flex: 2;
        flex: 2; //在剩余空间占2份
 }
</style>

看上面的代码,我们能很容易想到类似这样一个图。

关于 flex,还有几个很重要的属性。

flex-direction

flex-direction 属性决定主轴的方向(即排列方向)。

.box {
 flex-direction: column-reverse;  //主轴为垂直方向,起点在下沿
     column;  //主轴为垂直方向,起点在上沿
     row(默认值);  //主轴为水平方向,起点在左端
     row-reverse;  //主轴为水平方向,起点在右端
}

flex-wrap

就像第一张图中,所有的 div 都排列在一行中,那如果那一行有很多 div 呢。

flex-wrap 就是用来处理这几种情况。

.box {
  flex-wrap: nowrap(默认); //不换行
  flex-wrap: wrap; //换行,第一行在上方
  flex-wrap: wrap-reverse; // 换行,第一行在下方
}

(1)nowrap:

(2)wrap:

(3)wrap-reverse:

需要注意的是,在第一种情况中,如果你给某些 div 设置了 min-width,而 min-width 加起来超过父级 div 的宽时,子 div 就会溢出。

我这里给父级 div 设置 220px 的宽,子 div 的 min-width 为 100px。

flex-flow

flex-flow 属性是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为 row nowrap。

.box {
  flex-flow: <flex-direction> || <flex-wrap>;
}

justify-content

设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式。 当弹性盒里一行上的所有子元素都不能伸缩或已经达到其最大值时,这一属性可协助对多余的空间进行分配。当元素溢出某行时,这一属性同样会在对齐上进行控制。

.box {
 justify-content: flex-start(默认);  //左对齐
      flex-end;  //右对齐
      center;  //居中
      space-between;  //两端对齐,项目之间的间隔都相等
      space-around;  //每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
}

align-items

定义 flex 子项在 flex 容器的当前行的侧轴(纵轴)方向上的对齐方式。

.box {
 align-items: flex-start;  //弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
  flex-end;  //弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
  center;  //弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
  baseline;  //弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
  stretch(默认);  //如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。
}

align-content

当伸缩容器的侧轴还有多余空间时,本属性可以用来调准「伸缩行」在伸缩容器里的对齐方式,这与调准伸缩项目在主轴上对齐方式的 <’ justify-content ‘> 属性类似。请注意本属性在只有一行的伸缩容器上没有效果。

.box {
 align-items: flex-start;  //
各行向弹性盒容器的起始位置堆叠。弹性盒容器中第一行的侧轴起始边界紧靠住该弹性盒容器的侧轴起始边界,之后的每一行都紧靠住前面一行。
  flex-end;  //各行向弹性盒容器的结束位置堆叠。弹性盒容器中最后一行的侧轴起结束界紧靠住该弹性盒容器的侧轴结束边界,之后的每一行都紧靠住前面一行。
  center;  //各行向弹性盒容器的中间位置堆叠。各行两两紧靠住同时在弹性盒容器中居中对齐,保持弹性盒容器的侧轴起始内容边界和第一行之间的距离与该容器的侧轴结束内容边界与第最后一行之间的距离相等。(如果剩下的空间是负数,则各行会向两个方向溢出的相等距离。)
  space-between;  //各行在弹性盒容器中平均分布。如果剩余的空间是负数或弹性盒容器中只有一行,该值等效于'flex-start'。在其它情况下,第一行的侧轴起始边界紧靠住弹性盒容器的侧轴起始内容边界,最后一行的侧轴结束边界紧靠住弹性盒容器的侧轴结束内容边界,剩余的行则按一定方式在弹性盒窗口中排列,以保持两两之间的空间相等。
  space-around;  //各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。如果剩余的空间是负数或弹性盒容器中只有一行,该值等效于'center'。在其它情况下,各行会按一定方式在弹性盒容器中排列,以保持两两之间的空间相等,同时第一行前面及最后一行后面的空间是其他空间的一半。
  stretch(默认);  //各行将会伸展以占用剩余的空间。如果剩余的空间是负数,该值等效于'flex-start'。在其它情况下,剩余空间被所有行平分,以扩大它们的侧轴尺寸。
}

所以现在再看如何实现网页栅栏化就很简单了。

ellipsis

在 flex 中使用 ellipsis 的时候,有几个注意点:

  1. 设置了 display:flex 的节点直接直接 ellipsis 是无效的,因为拿不到 width
  2. flex 的子节点设置 ellipsis 的时候,设置 display:flex 的节点要设置 min-width:0 来 flex 元素能够收缩它的内容。
.parent {
  display: flex;
  min-width: 0; // important
}

.content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

结尾

相关链接

blog comments powered by Disqus
目 录