ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CSS Flexible Box Layout

2020-03-13 19:11:01  阅读:286  来源: 互联网

标签:Box 容器 Layout flex end start Flexible main 属性


引子

最近接触 flex 布局的时候,碰到一些问题,于是借着这个机会,对 flex 相关的知识点进行整理。

简介

CSS 2.1 定义了 4 种布局模式,这些算法是根据盒子与它们的兄弟和祖先盒子的关系,来确定盒子自身大小和位置。分别有:

  • block 布局,为文档布局设计
  • inline 布局,为文本布局设计
  • table 布局,为表格形式的 2D 数据布局设置
  • positioned 布局,设计用于非常明确的定位,不用考虑文档中的其他元素

新引入的 flex 布局,跟 block 布局很类似,它缺少很多在 block 布局中,有关文本和文档相关的特性,例如浮动。相应的,它拥有了简单且强大的工具,用于来分配空间,并可以按照 web 应用程序和复杂网页经常需要的方式对齐内容。

目前处于候选推荐阶段,主流浏览器支持的情况很不错,详细见 Can I use flex

相关概念和术语

一个元素设置 display 属性值为 flexinline-flex,就会变成一个 flex 容器(flex container),其直接子元素被称为 flex 项(flex items),它们布局使用 flex 布局模式。

在 CSS 中定义了一些跟物理方向和空间相对应的一些概念,这些概念为未来定义新的布局提供理论支持,在 flex 布局模式中对应物理方向和空间的概念如下图。

32-css-flex

  • main axis:主轴,flex 项的排列是按照主轴进行排列,主轴的方向取决于 flex-direction 属性,不一定是水平方向。
  • main-start/main-end:flex 容器主轴上的开始/结束位置,flex 项的排列是从 main-start 开始,到 main-end 结束。
  • main-size:在主轴方向 flex 容器或者 flex 项的高度或宽度,它可能是元素的 widthheight 属性。类似的,它的 min/max main size 属性取决于它的 min-width/max-width 或者 min-height/max-height 属性。
  • cross axis:侧轴,跟主轴方向垂直的轴。
  • cross-start/cross-end:flex 容器侧轴上的开始/结束位置,flex 项的排列是从 cross-start 开始,到 cross-end 结束。
  • cross-size:在侧轴方向 flex 容器或者 flex 项的高度或宽度,它可能是元素的 widthheight 属性。类似的,它的 min/max cross size 属性取决于它的 min-width/max-width 或者 min-height/max-height 属性。

flex container

成为 flex 容器的方式是,设置 display 属性值为 flex | inline-flex

  • flex:当一个块级元素放在流布局中,这个值会让这个元素生成一个 flex 容器盒子。
  • inline-flex:当一个内联元素放在流布局中,这个值会让这个元素生成一个 flex 容器盒子。

flex 容器会为它的内容建立一个 flex 格式化上下文,它形成的包含块就像块级容器做的那样。flex 容器的外边距(margin)不会跟它内容的边距重合。overflow 属性适用于 flex 容器。flex 容器不是块级容器,并且有些适用于 block 布局的属性在 flex 布局中并不适用,特别是:

  • floatclear 不会产生浮动或者清空 flex 项,并且不会让元素脱离文档流。
  • vertical-align 对 flex 项没有作用。
  • ::first-linefirst-letter 伪元素不适用于 flex 容器,flex 容器不会为它们的祖先提供第一行格式化或第一个字母。

这是测试示例,移动端查看如下。

32-qrcode-flex-test

如果一个元素的 display 属性设置为 inline-flex,在特定的环境下,它的的 display 属性会被计算为 flex

用于 flex 容器的相关属性有:

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

flex-direction

属性名:flex-direction

可取值:row | row-reverse | column | column-reverse

默认值:row

适用于:flex 容器

可继承:否

flex-direction 属性通过设置 flex 容器主轴的方向,来指定 flex 项在 flex 容器中的放置方式。

这是测试示例,移动端查看如下。

32-qrcode-flex-direction

flex-wrap

属性名:flex-wrap

可取值:nowrap | wrap | wrap-reverse

默认值:nowrap

适用于:flex 容器

可继承:否

flex-wrap 属性决定 flex 容器是单行还是多行,侧轴的方向决定了新行的插入方向。

  • nowrap:flex 容器的子元素单行显示。
  • wrap:flex 项在当前行显示不了时,会换行显示。
  • wrap-reverse:flex 项在当前行显示不了时,会换行显示。

当值为非 wrap-reverse 时,cross-start 的方向与 当前 writing modeinline-startblock-start 方向一致,当值为 wrap-reverse 时,cross-startcross-end 方向相反。

这是测试示例,移动端查看如下。

32-qrcode-flex-wrap

flex-flow

flow-flowflex-directionflex-wrap 的缩写。
属性名:flex-flow

可取值:flex-direction || flex-wrap

适用于:flex 容器

可继承:否

justify-content

属性名:justify-content

可取值:flex-start | flex-end | center | space-between | space-around

默认值:flex-start

适用于:flex 容器

可继承:否

justify-content 属性沿着 flex 容器当前行的主轴对齐 flex 项。

  • flex-start:flex 项向行的开始位置放置。行内第一个 flex 项的 main-start 外边距边界与行的 main-start 的外边距边界齐平,每个后续的 flex 项与前一项齐平放置。
  • flex-end:flex 项向行的结束位置放置。行内最后一个 flex 项的 main-end 外边距边界与行的 main-end 的外边距边界齐平,每个前面的 flex 项与后续的项齐平放置。
  • center:flex 项向行的中间位置放置。行内每个 flex 项齐平放置并与行的中心对齐,行的 main-start 边界与第一个 flex 项之间的空间,和行的main-end 边界与最后一个 flex 项之间的空间等量。
  • space-between:flex 项在行内均匀分布。如果剩下的自由空间是负的,或者只有一个 flex 项在行内,这个值的作用与 flex-start 等同。除此之外,行内第一个 flex 项的 main-start 外边距边界与行的 main-start 的外边距边界对齐,行内最后一个 flex 项的 main-end 外边距边界与行的 main-end 的外边距边界对齐,剩下的 flex 项在行上均匀分布,任意两个相邻 flex 项的间距相同。
  • space-around:flex 项在行内均匀分布,两端各有一半的空间。如果剩下的自由空间是负的,或者只有一个 flex 项在行内,这个值会被识别为 center。除此之外,在行内任意两个相邻的 flex 项的间距相同,第一个和最后一个 flex 项与 flex 容器边界的间距是相邻 flex 项之间间距的一半。

32-justify-content

这是测试示例,移动端查看如下。

32-qrcode-justify-content

align-items

属性名:align-items

可取值:flex-start | flex-end | center | baseline | stretch

默认值:stretch

适用于:flex 容器

可继承:否

align-items 设置所有 flex 容器的项的默认对齐方式,包括匿名的 flex 项。

  • flex-start:flex 项的 cross-start 外边距边界与行的 cross-start 边界对齐。
  • flex-end:flex 项的 cross-end 外边距边界与行的 cross-end 边界对齐。
  • center:flex 项的外边距盒子在行的侧轴上中心。
  • baseline:flex 项基于基线对齐,行内所有参与的 flex 项目都基于基线对齐,并且拥有基线与其自身的 cross-start 外边距边界最大距离的 flex 项,与行的 cross-start 边界齐平。如果项目在必要的轴中没有基线,则从 flex 项的边框盒子合成基线。
  • stretch:如果 flex 项的 cross size 属性计算为 auto,并且侧轴的的外边距都不是 auto,那么 flex 项会被拉伸。它使用的值是尽可能的让 项的外边距盒子的 cross size 与行的大小一致的长度,仍然受到 min-height/min-width/max-height/max-width 的约束。

32-align-items

这是测试示例,移动端查看如下。

32-qrcode-align-items

align-content

属性名:align-content

可取值:flex-start | flex-end | center | space-between | space-around | stretch

默认值:stretch

适用于:多行 flex 容器

可继承:否

当在侧轴上有多余的空间时,align-content 属性让 flex 容器内的行对齐。注意,该属性对单行 flex 容器没有作用。

  • flex-start:行向 flex 容器的开始位置放置。flex 容器内第一行的 cross-start 边界与flex 容器的 cross-start 边界齐平,后续的每行与前一行齐平。
  • flex-end:行向 flex 容器的结束位置放置。flex 容器内最后一行的 cross-end 边界与flex 容器的 cross-end 边界齐平,每个前面的行与后续的行齐平放置。
  • center:行向 flex 容器的中间位置放置。flex 容器内每一行都齐平放置并与 flex 容器的中心对齐,flex 容器内第一行与 flex 容器的 cross-start 内容边界的空间,和 flex 容器内最后一行与 flex 容器的 cross-end 内容边界的空间等量。
  • space-between:行在 flex 容器内均匀分布。如果剩下的自由空间是负的,或者只有一行在 flex 容器内,这个值的作用与 flex-start 等同。除此之外,flex 容器内第一行的 cross-start 边界与 flex 容器的 cross-start 内容边界对齐,flex 容器内最后一行的 main-end 边界与 flex 容器的 main-end 的内容边界对齐,剩下的行在 flex 容器内均匀分布,任意相邻行的间距相同。
  • space-round:行在 flex 容器内均匀分布,两端各有一半的空间。如果剩下的自由空间是负的,这个值的作用与 center 等同。除此之外,flex 容器内任意相邻的行的间距相同,第一行和最后一行与 flex 容器边界的间距是相邻行间距的一半。
  • stretch:行会伸展占据剩余的空间。如果剩下的自由空间是负的,这个值的作用与 flex-start 等同。除此之外,剩余的空间会被所有的行平分。

32-align-content

这是测试示例,移动端查看如下。

32-qrcode-align-content

flex item

flex 容器下每个在文档流里的后代都会成为一个 flex 项。每个连续的子文本都包含在匿名块容器 flex 项中。如果只包含空白符,就不会渲染,就好像文本节点拥有属性 display: none 。flex 项为它的内容建立一个独立的格式化上下文。然而,flex 项是 flex 级别盒子,不是 block 级别盒子,它们参与自己的 flex 格式化上下文,不是在 block 格式化上下文。

如果在 flex 容器内,在文档流的后代设置 display 为内联的值,其计算值与块级别值等效。也就是说这种情况下 flex 项的 display 属性值被锁定。详细见 CSS Display

flex 容器内绝对定位,脱离文档流的后代不会参与 flex 布局。这样的 flex 容器的静态位置矩形(static-position rectangle )是它的内容盒子,这个静态位置矩形是用来决定绝对定位盒子偏移位置的容器。

相邻 flex 项的边距(margin)不会合并。flex 项的 marginpadding 为百分比时,跟块级盒子一样,会根据包含快的逻辑宽度计算。margin 的值为 auto 时,会在相应的维度,吸收额外的空间。它们可以用来对齐或者分开 flex 项。

用于 flex 项的相关属性有:

  • flex
  • order
  • align-self

flex

属性名:flex

可取值:none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ]

默认值:0 1 auto

适用于:flex 项

可继承:否

影响 flex 项长度有 flex 因子(增长和收缩)和 flex 基础。当一个盒子是 flex 项时,flex 属性决定了盒子的主要大小。如果一个盒子不是 flex 项,flex 属性将不会有作用。

flex 设置值为 none 时,相当于 0 0 auto

flex-grow

值为数字。当空间剩余时,这个属性决定了 flex 项相对于 flex 容器下其它 flex 项,会增长多少空间。当在 flex 简写中省略时,设置为 1 。

flex-shrink

值为数字。当空间不足时,这个属性决定了 flex 项相对于 flex 容器下其它 flex 项,会收缩多少空间。当在 flex 简写中省略时,设置为 1 。

flex-basis

flex-basis 定义了在分配多余空间前,flex 项的初始 main size。

  • auto:使用该值时,将会取 main size 属性的值,如果 main size 属性的值也是 auto,则使用值 content
  • content:基于 flex 项的内容大小自动生成。
  • <‘width’>:除了上面两个值,flex-basis 使用方式与 widthheight 相同。

在 flex 简写中省略时,设置的值是 0 。

flex 常见值

  1. flex: initial:相当于 flex: 0 1 auto 。flex 项的大小基于 width/height 属性。当有剩余空间时,不会分配剩余空间,但允许空间不足时缩小到最小尺寸。对齐的属性或者 auto 外边距可以用来让 flex 项沿主轴对齐。
  2. flex: auto:相当于 flex: 1 1 auto 。flex 项的大小基于 width/height 属性。当有剩余空间时,会沿着主轴,尽可能的吸收剩余空间。如果所有项目都是 flex: autoflex: initialflex: none ,则在项目大小调整后,任何剩余空间将均匀分配到具有属性 flex: auto 的项。
  3. flex: none:相当于 flex: 0 0 auto 。flex 项的大小根据 width/height 属性。盒子不会变得有弹性,跟取值 initial 有点类似,但不允许 flex 项收缩,即使在溢出的情况下。
  4. flex: <positive-number>:相当于 flex: <positive-number> 1 0 。flex 项接收 flex 容器中指定比例的可用空间。如果 flex 容器下所有 flex 项都使用这种模式,它们的大小将与指定的弹性系数成比例。

这是测试示例,移动端查看如下。

32-qrcode-flex

order

属性名:order

可取值:<integer>

默认值:0

适用于:flex 项

可继承:否

order 属性控制了 flex 项在 flex 容器里面显示的顺序。flex 容器放置内容,从最低编号开始按顺序向上。序号相同的组,会按照它们在源文档中出现的顺序放置。flex 容器内绝对定位的后代,会被当做拥有 order: 0 ,这样做是为了决定它们相对于 flex 项的绘制顺序。

这是测试示例,移动端查看如下。

32-qrcode-order

align-self

属性名:align-self

可取值:auto | flex-start | flex-end | center | baseline | stretch

默认值:auto

适用于:flex 项

可继承:否

align-self 作用跟 align-items 一样,但它适用于 flex 项,可以为单独的 flex 项设置对齐的方式,会覆盖 align-items 的效果。

如果 flex 项的侧轴任一外边距为 auto ,那么 align-self 无效。

align-selfalign-items 多了一个可取值 auto ,使用该值时,对齐方式的控制权交给了父级盒子。

这是测试示例,移动端查看如下。

32-qrcode-align-self

参考资料

标签:Box,容器,Layout,flex,end,start,Flexible,main,属性
来源: https://blog.csdn.net/u011194386/article/details/104847214

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有