弹性css-web后端最流行的网页布局技术:flexbox弹性布局学习与解读

我们针对 CSS Flexbox 布局的综合手册。 这本完整的手册解释了有关 Flexbox 的所有内容,突出显示了父元素(Flex 容器)和子元素(Flex 项)的所有不同可能属性。 它还包括历史记录、演示、架构和浏览器支持图表。

弹性布局的诞生背景

(FlexboxLayoutFlexibleBox) 模块(截至 2017 年 10 月的 W3C 候选推荐)致力于提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间,尽管它们的大小未知和/或动态(因此术语“弯曲”) ”)。

弹性布局背后的主要思想是容器是否可以更改其项目的长度/高度(和顺序)以最好地填充可用空间(主要是为了适应各种显示设备和屏幕尺寸)。 弹性容器可扩展项目以填充可用空间,或缩小项目以避免溢出。

最重要的是,与常规布局(基于垂直地块和基于水平内联)相比,Flexbox 布局与方向无关。 实际上,这适用于页面,但它们缺乏支持小型或复杂应用程序的灵活性(没有双关语)(特别是在方向修改、调整大小、拉伸、收缩等方面)。

注意:Flexbox 布局最适合应用程序组件和小规模布局,而 Grid 布局则适合较大规模的布局。

基础知识和术语

因为flexbox是一个完整的模块而不是单个属性,所以它涉及到很多东西,包括它的整个属性集。 其中一些是在容器(父元素,称为“flexcontainer”)上设置的,而另一些是在子元素(称为“flexitems”)上设置的。

如果说“常规”布局是基于块流向和内联流向,那么弹性布局则是基于“弹性流向”。 请看一下规范中的这张图片,解释了弹性布局背后的主要思想。

解释 Flexbox 术语的图表。 穿过flexbox主轴的spec称为主spec,另一个方向是纵向spec。 该规范有主起点、主终点、交叉起点和交叉终点。

项目将根据主轴(从main-start到main-end)或垂直轴(从cross-start到cross-end)排列。

flex box属性parent(flex容器)的属性显示

这定义了一个弹性容器; 内联或块取决于给定的值。 它为其所有直接子级启用了弹性上下文。

.container {
  display: flex; /* or inline-flex */
}

请注意弹性css,CSS 列对 Flex 容器没有影响。

弹性方向

这构建了主轴,从而定义了 Flex 项目在 Flex 容器中放置的方向。 Flexbox 是(不仅仅是一个可选的包装器)双向布局概念。 将弹性项目视为主要布置在水平行或垂直列中。

.container {
  flex-direction: row | row-reverse | column | column-reverse;
}

弹性包裹

默认情况下,弹性项目会尝试放在一行上。 您可以修改此属性并允许使用此属性根据需要包装项目。

.container {
  flex-wrap: nowrap | wrap | wrap-reverse;
}

弹性流动

这是 flex-direction 和 flex-wrap 属性的缩写,它们共同定义了 Flex 容器的主轴和交叉轴。 默认为 rownowrap。

.container {
  flex-flow: column wrap;
}

证明内容

这定义了沿主轴的对齐方法。 当一行上的所有弹性项目都不灵活或虽然灵活但已达到其最大尺寸时,它有助于分配额外的可用空间。 它对物品移动时的对齐方式进行一定程度的控制。

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}

请注意,浏览器对此值的支持略有不同。 例如,Edge的个别版本不支持space- Between,但Chrome则没有start/end/left/right。 MDN 有详尽的图表。 最安全的值是flex-start、flex-end和center。

还有两个附加关键字可以与这些值配对:safe 和 unsafe。 使用 safe 可确保无论您如何进行此类定位,都无法提升元素使其呈现在屏幕外(例如,离开底部),从而导致内容也无法滚动(称为“数据丢失”) 。

对齐项目

这定义了弹性项目如何沿当前行的横轴布局的默认行为。 将其视为垂直轴的 justify-content 版本(垂直于主轴)。

.container {
  align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}

和 修饰符关键字可以与所有其他关键字一起使用(尽管请注意安全浏览器支持),并帮助您避免对齐元素使内容看起来无法访问。 不安全

对齐内容

当垂直轴上有额外空间时弹性css,这将对齐 Flex 容器的线条,类似于各个项目在 justify-content 主轴内的对齐方式。

注意:该属性仅对多行柔性容器有效,其中flex-wrap设置为wrap或wrap-reverse)。 单行 Flex 容器(即,flex-wrap 设置为其默认值 no-wrap )将不会反映align-content。

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}

和 修饰符关键字可以与所有其他关键字一起使用(尽管请注意安全浏览器支持),并帮助您避免对齐元素使内容看起来无法访问。 不安全

间隙、行间隙、列间隙

间隙属性显式控制弹性项目之间的空间。 它仅适用于不在外边缘的项目之间的宽度。

.container {
  display: flex;
  ...
  gap: 10px;
  gap: 10px 20px; /* row-gap column gap */
  row-gap: 10px;
  column-gap: 20px;
}

这种行为可以被认为是一个最小的装订线,就好像装订线在某种程度上更大(由于诸如 justify-content:space- Between; 之类的东西),因此只有当空间最终显得更小时,差异才会生效。

除了适合flexbox之外,gap还适合网格和多列布局。

子项目的属性(弹性项目)

命令

默认情况下,弹性项目按源顺序排序。 此外,order 属性控制它们在 Flex 容器中出现的顺序。

.item {
  order: 5; /* default is 0 */
}

使用相同的物料订单恢复到源订单。

弹性增长

这定义了弹性项目在必要时删除的能力。 它接受无单位值用作比率列。 它指定项目应占用的 Flex 容器内的可用空间量。

如果所有项目的 flex-grow 设置为 1,容器中的剩余空间将平均分配给所有子项目。 如果其中一个子代的值为 2,则该子代将占用其他子代之一两倍的空间(或至少尝试这样做)。

.item {
  flex-grow: 4; /* default 0 */
}

正数无效。

弹性收缩

这定义了弹性项目在必要时收缩的能力。

.item {
  flex-shrink: 3; /* default 1 */
}

正数无效。

弹性粉底

这定义了分配剩余空间之前元素的默认大小。 它可以是厚度(如 20%、5rem 等)或关键字。 auto 关键字的意思是“查看我的长度或高度属性”(这是由 main-size 关键字暂时完成的,直到它被弃用)。 content 关键字的意思是“根据项目的内容调整大小”——这个关键字还没有得到很好的支持,所以很难测试,而且很难知道它的同级 max-content、min-content 和 fit——什么意思内容做。

.item {
  flex-basis:  | auto; /* default auto */
}

如果设置为 0,则不考虑内容周围的额外空间。 如果设置为 auto,则根据其 flex-grow 值分配额外空间。 请参阅此图。

灵活的

这是 flex-grow、flex-shrink 和 flex-basis 组合的缩写。 第二个和第三个参数(flex-shrink 和 flex-basis)是可选的。 默认值为01auto,但如果设置为单个值,例如flex:5;,则会将flex-basis修改为0%,所以与设置flex-grow:5;flex-shrink是一样的:1;弹性基础:0%;。

.item {
  flex: none | [  ? ||  ]
}

建议您使用此简写属性,而不是设置单独的属性。 速记可以智能地设置其他值。

自我调整

align-items 这允许覆盖各个 Flex 项目的默认对齐方法(或其指定的对齐方法)。

有关可用值,请参阅align-items 描述。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

请注意,浮动、清除和垂直对齐对弹性项目没有影响。

前缀弹性盒

Flexbox 需要一些供应商前缀来支持尽可能多的浏览器。 除了供应商前缀的属性之外,它还包括实际上具有完全不同的属性和值名称。 这是由于 Flexbox 规范随着时间的推移而发生变化,创建了“旧”、“补间”和“新”版本。

实际上,处理这个问题的最佳方法是编写新的(也是最终的)语法并通过 Autoprefixer 运行 CSS,它可以很好地处理回退。

或者,这里有一个 Sass @mixin 来帮助处理一些前缀,它也可以让你知道要做什么:

@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}
@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;
}
@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;
}
.wrapper {
  @include flexbox();
}
.item {
  @include flex(1 200px);
  @include order(2);
}css

案件

让我们从一个非常简单的案例开始,解决一个我们几乎每天都会遇到的问题:完美优雅中心。 如果您使用 Flexbox,那就再简单不过了。

.parent {
  display: flex;
  height: 300px; /* Or whatever */
}
.child {
  width: 100px;  /* Or whatever */
  height: 100px; /* Or whatever */
  margin: auto;  /* Magic! */
}

这依赖于 auto flex 容器中设置的分辨率吸收额外空间的事实。 因此,将行间距设置为自动将使项目在两个轴上完美居中。

现在让我们使用更多属性。 考虑一个包含 6 个项目的列表,所有项目都有固定的规格,但可以手动调整大小。 我们希望它们在水平轴上均匀分布,这样当我们调整浏览器大小时,所有内容都能很好地缩放,但没有媒体查询。

.flex-container {
  /* We first create a flex layout context */
  display: flex;
  /* Then we define the flow direction 
     and if we allow the items to wrap 
   * Remember this is the same as:
   * flex-direction: row;
   * flex-wrap: wrap;
   */
  flex-flow: row wrap;
  /* Then we define how is distributed the remaining space */
  justify-content: space-around;
}

完全的。 其他一切都只是样式问题。

让我们尝试一些别的东西。 想象一下,我们的网站底部有一个右对齐的导航元素,但我们希望它在小屏幕上居中,在较大的设备上以单列居中。 简单的。

/* Large */
.navigation {
  display: flex;
  flex-flow: row wrap;
  /* This aligns items to the end line on main-axis */
  justify-content: flex-end;
}
/* Medium screens */
@media all and (max-width: 800px) {
  .navigation {
    /* When on medium sized screens, we center it by evenly distributing empty space around items */
    justify-content: space-around;
  }
}
/* Small screens */
@media all and (max-width: 500px) {
  .navigation {
    /* On small screens, we are no longer using row direction but column */
    flex-direction: column;
  }
}

让我们通过发挥弹性项目的灵活性来尝试更好的东西! 联通首创的带有全角脚注和页码的 3 栏布局怎么样? 并且与源顺序无关。

.wrapper {
  display: flex;
  flex-flow: row wrap;
}
/* We tell all items to be 100% width, via flex-basis */
.wrapper > * {
  flex: 1 100%;
}
/* We rely on source order for mobile-first approach
 * in this case:
 * 1. header
 * 2. article
 * 3. aside 1
 * 4. aside 2
 * 5. footer
 */
/* Medium screens */
@media all and (min-width: 600px) {
  /* We tell both sidebars to share a row */
  .aside { flex: 1 auto; }
}
/* Large screens */
@media all and (min-width: 800px) {
  /* We invert order of first sidebar and main
   * And tell the main element to take twice as much width as the other two sidebars 
   */
  .main { flex: 2 0px; }
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
}

浏览器支持

此浏览器支持数据来自 Caniuse,其中包含更详细的信息。 数字表示浏览器支持该版本及更高版本的功能。

错误

Flexbox 实际上并非没有缺陷。 我见过的最好的合集是 PhilipWalton 和 GregWhitworth 的 Flexbugs。 这是一个跟踪所有这些的开源地方,所以我认为最好只是链接到它。