css3中flexbox伸缩盒深入理解

作者:袖梨 2022-06-25

也就是因为这个flexbox伸缩盒布局太强大了,以至于我没在意它也是display的一个属性。

要想解决这个布局问题,我们还是先了解一些基础的问题。先回顾下display有哪些属性吧:

    none:隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间
    inline:指定对象为内联元素。block:指定对象为块元素。
    list-item:指定对象为列表项目。inline-block:指定对象为内联块元素。(CSS2)
    table:指定对象作为块元素级的表格。类同于html标签

(CSS2)
    inline-table:指定对象作为内联元素级的表格。类同于html标签
(CSS2)
    table-caption:指定对象作为表格标题。类同于html标签(CSS2)
    table-row-group:指定对象作为表格行组。类同于html标签(CSS2)
    table-column:指定对象作为表格列。类同于html标签(CSS2)
    table-column-group:指定对象作为表格列组显示。类同于html标签(CSS2)
    table-header-group:指定对象作为表格标题组。类同于html标签(CSS2)
    table-footer-group:指定对象作为表格脚注组。类同于html标签(CSS2)
    run-in:根据上下文决定对象是内联对象还是块级对象。(CSS3)
    box:将对象作为弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
    inline-box:将对象作为内联块级弹性伸缩盒显示。(伸缩盒最老版本)(CSS3)
    flexbox:将对象作为弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
    inline-flexbox:将对象作为内联块级弹性伸缩盒显示。(伸缩盒过渡版本)(CSS3)
    flex:将对象作为弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)
    inline-flex:将对象作为内联块级弹性伸缩盒显示。(伸缩盒最新版本)(CSS3)

可以看到,目前最新的版本是display:flex ;当然要是用以前过度版本的估计还有用,但我们还是跟着最新的规范来。

我们再了解下伸缩盒的定义和一些概念的东西吧:

Flexbox(伸缩布局盒) 是 CSS3 中一个新的布局模式,为了现代网络中更为复杂的网页需求而设计。

虽然现在我们可以使用 Flexbox 轻松创建布局,而不会像以前那样难以理解,但我们仍然需要花一些时间去熟悉到底如何使用 Flexbox。新的术语和概念可能会是我们使用 Flexbox 时的一个障碍,所以让我们先来了解以下它们。

Flexbox 由 伸缩容器 和 伸缩项目 组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。

Flexbox 规范的相关工作已经进展了3年。不同的浏览器也实现了不同的实验版本。在2012年9月,Flexbox 语法的第三个主要修订版本进入到候选推荐阶段。这意味着 W3C 认为当前的语法是稳定的,并鼓励浏览器开发商去实现它。总之,伸缩盒布局,是我见过的最操蛋的规范,从2009发布到去年最终定下来,更弦换辙了三次。

Flexbox 规范时间表:

    2009年7月 工作草案 (display: box;)
    2011年3月 工作草案 (display: flexbox;)
    2011年11月 工作草案 (display: flexbox;)
    2012年3月 工作草案 (display: flexbox;)
    2012年6月 工作草案 (display: flex;)
    2012年9月 候选推荐 (display: flex;)

Flexbox 已经被浏览器快速支持。Chrome 22+, Opera 12.1+, 和 Opera Mobile 12.1+ 已经支持了本文中所描述的 Flexbox。Firefox 18 和 Blackberry 10 也很快就会实现。我推荐大家使用已经支持的浏览器来阅读本文和查看例子。虽然如此,但是很多浏览器厂商都高了一个私有前缀,所以特别麻烦:

div{

      display: -webkit-box;

      display: -moz-box;

      display: -o-box;

      display: -ms-flexbox;

      display: -webkit-flex;

      display: -moz-flex;

      display: -ms-flex;

      display: -o-flex;

      display: flex;

}

 

我们再来看看它有哪些属性:
Properties
属性  CSS Version
版本  Inherit From Parent
继承性  Description
简介
flex  CSS3  无  复合属性。设置或检索伸缩盒对象的子元素如何分配空间。
flex-grow  CSS3  无  设置或检索弹性盒的扩展比率。
flex-shrink  CSS3  无  设置或检索弹性盒的收缩比率
flex-basis  CSS3  无  设置或检索弹性盒伸缩基准值。
flex-flow  CSS3  无  复合属性。设置或检索伸缩盒对象的子元素排列方式。
flex-direction  CSS3  无  设置或检索伸缩盒对象的子元素在父容器中的位置。
flex-wrap  CSS3  无  设置或检索伸缩盒对象的子元素超出父容器时是否换行。
align-content  CSS3  无  设置或检索弹性盒堆叠伸缩行的对齐方式。
align-items  CSS3  无  设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式。
align-self  CSS3  无  设置或检索弹性盒子元素自身在侧轴(纵轴)方向上的对齐方式。
justify-content  CSS3  无  设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式。
order  CSS3  无  设置或检索伸缩盒对象的子元素出?的?序。
1:flex

取值:

none:none关键字的计算值为: 0 0 auto

[ flex-grow ]:定义弹性盒子元素的扩展比率。

[ flex-shrink ]:定义弹性盒子元素的收缩比率。

[ flex-basis ]:定义弹性盒子元素的默认基准值。

这里flex-grow,flex-shrink,flex-basis可以单独使用例如:flex-grow:1,也可以几个在一起缩写使用,例如:flex:1 1 100px;表示不扩展也不伸缩,设置宽度为100px。

看一个DEMO:

这里面一开始定义了每个Box 400px,所以第一个每个小块都是133px.第二个box(box2)由于每个块都设置了扩展和伸缩比率还有基准值100px。这里我们可以计算得:100+100+100=300px,但是因为它的ID设置了宽度为400px,所以会空出100px,但是它还有设置了扩展比率,所以计算得:100*1+100*2+100*3=600px;,最后我们可以算出每个小块将要增加的宽度:

第一个:1*100/600*100约等于17px;

第二个小块:2*100/600*100约等于33px;

第三个小块:3*100/600*100等于50px

也就是说box2里第一块区域的宽度为117px,第二小块的宽度为133px,第三个小块的宽度为150px;

同样的算法你可以去试试box3的各个宽度。
2.flex-flow

flex-flow是个复合属性,接受这两类值:[ flex-direction ] [ flex-wrap ]。

要不我们先熟悉下flex-direction和flex-wrap吧

flex-direction用来定义弹性盒子元素的排列方向。

语法:flex-direction:row | row-reverse | column | column-reverse默认值是row,无继承性。

row:横向从左到右排列(左对齐),默认的排列方式。row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面。column:纵向排列。row-reverse:反转纵向排列,从后往前排,最后一项排在最上面。

看一个DEMO

再来看看:flex-wrap:nowrap | wrap | wrap-reverse 表示定义弹性盒子元素溢出父容器时是否换行。默认值为nowrap。可取值:nowrap:当子元素溢出父容器时不换行。wrap:当子元素溢出父容器时自动换行。wrap-reverse:反转 wrap 排列。

看一个DEMO:

现在flex-flow的属性搞清楚了,我们可以结合两个来写一个DEMO:
3.再看看align-content属性吧:

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

看一个DEMO:
4.align-items

语法:align-items:flex-start | flex-end | center | baseline | stretch
每个值的意思:
flex-start: 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
flex-end: 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
center: 弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
baseline: 如弹性盒子元素的行内轴与侧轴为同一条,则该值与’flex-start’等效。其它情况下,该值将参与基线对齐。
stretch: 如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制。

DEMO:
5.align-self
align-self:auto | flex-start | flex-end | center | baseline | stretch默认值:auto
适用于:弹性盒模型子元素继承性:无
取值:

auto:
    如果’align-self’的值为’auto’,则其计算值为元素的父元素的’align-items’值,如果其没有父元素,则计算值为’stretch’。
flex-start:
    弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
flex-end:
    弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
center:
    弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
baseline:
    如弹性盒子元素的行内轴与侧轴为同一条,则该值与’flex-start’等效。其它情况下,该值将参与基线对齐。
stretch:
    如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制
    DEMO木有了
    6.justify-content

    用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式。

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

    语法:

    justify-content:flex-start | flex-end | center | space-between | space-around

    默认值:flex-start

    适用于:弹性盒模型容器

    继承性:无
    取值:

    flex-start:
        弹性盒子元素将向行起始位置对齐。该行的第一个子元素的主起始位置的边界将与该行的主起始位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
    flex-end:
        弹性盒子元素将向行结束位置对齐。该行的第一个子元素的主结束位置的边界将与该行的主结束位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
    center:
        弹性盒子元素将向行中间位置对齐。该行的子元素将相互对齐并在行中居中对齐,同时第一个元素与行的主起始位置的边距等同与最后一个元素与行的主结束位置的边距(如果剩余空间是负数,则保持两端相等长度的溢出)。
    space-between:
        弹性盒子元素会平均地分布在行里。如果最左边的剩余空间是负数,或该行只有一个子元素,则该值等效于’flex-start’。在其它情况下,第一个元素的边界与行的主起始位置的边界对齐,同时最后一个元素的边界与行的主结束位置的边距对齐,而剩余的伸缩盒项目则平均分布,并确保两两之间的空白空间相等。
    space-around:
        弹性盒子元素会平均地分布在行里,两端保留子元素与子元素之间间距大小的一半。如果最左边的剩余空间是负数,或该行只有一个伸缩盒项目,则该值等效于’center’。在其它情况下,伸缩盒项目则平均分布,并确保两两之间的空白空间相等,同时第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半。
        DEMO;

        7.order

        用于设置或检索弹性盒模型对象的子元素出?的?序。

        用法:order:

        :用整数值来定义排列顺序,数值小的排在前面。可以为负值。

        DEMO:

上文介绍了flexbox的基本语法和一些属性的使用,这里我们通过实战来更了解这个伸缩盒布局(弹性盒)
我们知道CSS3 弹性盒,是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。对于很多应用来讲,弹性盒在两个方面相对于盒模型进行了提升,它既不使用浮动,也不会导致弹性盒容器的外边距与其内容的外边距之间发生塌陷。
现在我们再来回顾下弹性盒的概念:
弹性盒布局的定义中,它可以自动调整子元素的高和宽,来很好的填充任何显示设备中的可用显示空间,收缩内容防止内容溢出。

不同于盒布局的基于垂直方向以及行内布局的基于水平方向,弹性盒布局的算法是方向无关的。 虽然盒布局在页面中工作良好,但是其定义不足以支持那种需要根据用户代理从竖直切换成水平等变化而进行方向切换、大小调整、拉伸、收缩的引用组件。不同于将要出现的网格布局针对目标为大比例布局,弹性盒布局更适用于应用组件和小比例布局。这两种都是CSS工作组为了能与不同用户代理、不同书写模式和其他弹性需要进行协作而做出的努力。

我们可以用display:flex和display:inline-flex来创建弹性盒。flex 值表示弹性容器为块级。inline-flex 值表示弹性容器为原子行级元素 。里面的元素就称为弹性子元素
弹性子元素的注意事项
包含在弹性容器内的文本自动成为匿名的弹性子元素。然而,只包含空白的弹性子元素不会被渲染,就好像它被设定为 display:none 一样。

弹性容器的绝对定位的子元素会被定位,因此其静态位置会根据它们的弹性容器的主起始内容盒的角落上开始。

目前由于一个已知的问题,在弹性子元素上指定 visibility:collapse
会导致其好像被指定了 display:none 一样,但该操作的初衷是使元素具有好像被指定了 visibility:hidden 一样的效果。在该问题被解决之前建议使用visibility:hidden ,其效果在弹性子元素上等同于 visibility:collapse 。

相邻的弹性子元素不会发生外边距合并。使用 auto 的外边距会在垂直和水平方向上带来额外的空间,这种性质可用于对齐或分隔临近的弹性子元素。W3C弹性盒子布局模型的 使用’auto’的外边距进行对齐 部分有更多信息。
弹性盒子的对齐会进行真正的居中,不像CSS的其他居中方法。这意味着即使弹性容器溢出,子元素仍然保持居中。有些时候这可能有问题,然而即使溢出了页面的 上沿,或左边沿(在从左到右的语言如英语;这个问题在从右到左的语言中发生在右边沿,如阿拉伯文),因为你不能滚动到那里,即使那里有内容!在将来的版本 中,对齐属性会被扩展为有一个“安全”选项。目前,如果关心这个问题,你可以使用外边距来达到居中的目的,这种方式比较“安全”,在溢出的情况下会停止居 中。在你想要居中的弹性子元素上应用自动外边距代替align-属性。在弹性容器的第一个和最后一个子元素的外侧应用自动外边距来代替justify-属性。自动外边距会伸缩并假定剩余空间,当有剩余空间时居中弹性子元素,没有剩余空间时切换会正常对齐模式。然而,如果你想要在多线弹性盒子中用基于外边距的居中替换justify-content属性,你可能就没那么幸运了,因为你需要在每一线的第一个和最后一个元素上应用外边距。除非你能提前预测哪个元素是哪一线上的最后一个元素,否则你没法稳定地在主轴上用基于外边距的居中代替 justify-content 属性。

说起虽然元素的显示顺序与源代码中的顺序无关,这种无关仅对显示效果有效,不包括语音顺序和基于源代码的导航。即使是 order 也不影响语言和导航序列。因此开发者必须小心排列源代码中的元素以免破坏文档的可访问性。
下面我们来看两个例子:

例子展示了如何对元素应用弹性布局以及在弹性布局中子元素的行为

例子2

这个例子适用于桌面浏览器网页必须优化以适应于智能手机屏幕的场景。不仅仅需要元素减小尺寸,它们排列的顺序方式也必须改变。弹性布局很容易实现这种需求。

(CSS2)
    table-cell:指定对象作为表格单元格。类同于html标签
(CSS2)
    table-row:指定对象作为表格行。类同于html标签

相关文章

精彩推荐