完整的Flexbox指南

完整的CSS flexbox教程。 本完整指南介绍了有关flexbox的所有内容,重点介绍了父元素(flex容器)和子元素(flex元素)的所有可能属性。 它还包括历史记录,演示,模板和浏览器支持图表。

背景知识
Flexbox布局(Flexible Box)模块( W3C候选建议书 ,2017年10月)旨在提供一种更高效的方式来放置,对齐和分配容器中元素之间的空间,即使它们的大小未知和/或动态(Flex表示“柔性”) 。

Flex布局的主要思想是使容器能够更改其元素的宽度/高度(和顺序),以便最佳地填充可用空间(主要用于在具有任何屏幕尺寸的所有类型的设备上显示)。 flex容器会扩展元素以填充可用的可用空间,或压缩它们以防止溢出。

最重要的是,flexbox布局与方向无关,与常规布局不同(垂直块和水平内联)。 尽管它们对于页面效果很好,但是它们缺乏支持大型或复杂应用程序的灵活性(没有双关语:-)(特别是在更改方向,调整大小,拉伸,压缩等方面)。

注意 :Flexbox布局最适合应用程序组件和小规模布局,而Grid布局则设计用于更大比例的布局。

基础知识和术语
由于flexbox是一个完整的模块,而不是单个属性,因此它包含具有一组属性的许多元素。 其中一些被设计为安装在容器中(父元素称为“ flex容器”),而其他一些则被设计为安装在子元素中(所谓的“ flex元素”)。

如果“常规”布局基于块方向和内联方向,则柔性布局将基于“柔性流向”。 请从规范中查看该图,该图说明了灵活布局的基本概念。



元素将位于主轴方向(从主轴主轴的主轴 )或横向轴(从十字起点到主轴的十字轴 )。

  • 主轴 -伸缩容器的主轴是伸缩元件沿其定位的主轴。 注意,该轴不一定是水平的。 它取决于flex-direction属性(请参见下文)。
  • 主启动| main-end -flex项目放置在容器中,从main-start开始,以main-end结束。
  • 主要尺寸 -flex元素的宽度或高度,取决于主要尺寸。 它由flex元素的主要尺寸决定,即 属性“宽度”或“高度”,具体取决于主要尺寸。
  • 横轴 -垂直于主轴的轴,称为横轴。 其方向取决于主轴的方向。
  • 交叉启动| 交叉端 -柔性线填充有元素并将其放置在容器中,从容器的交叉起始柔性到交叉端开始。
  • 交叉尺寸 -flex元素的宽度或高度。 根据flex-direction的css属性,这是元素的宽度或高度。 这始终是弹性项目的横向尺寸。


父级的属性(弹性容器)




展示


定义一个伸缩容器; 内联或阻止取决于设置值。 为所有第一级后代启用flex上下文。

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

注意事项:

请注意,CSS列不会影响flex容器。

弹性方向



设置主轴,从而确定放置在伸缩容器中的伸缩项目的方向。 Flexbox(除了可选包装之外)是一种单向布局概念。 将flex元素视为水平行或垂直列中的主要布局。

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

  • (默认):在ltr中从左到右; 在rtl中从右到左
  • 从右向左ltr 反向行 ; 在rtl中从左到右
  • :与相同,但从上到下
  • 列反转 :相同, 行反转,但从下至上

柔性包装



默认情况下,弹性项目将尝试放在一行上。 您可以更改此属性,并使用此属性允许项目跳到新行。

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

  • nowrap (默认设置):所有弹性商品都在同一行上
  • wrap :flex项目将从上到下包装几行。
  • wrap-reverse :flex项目将从下至上包装几行。

在此处查看flex-wrap行为的视觉演示。

flex-flow(适用于:flex容器的父元素)


这是flex-directionflex-wrap属性的简写,它们一起定义了flex容器的主轴和横轴。 默认值为row nowrap

 flex-flow: <'flex-direction'> || <'flex-wrap'> 

证明内容




此属性确定沿主轴的对齐方式。 它可以帮助分配额外的剩余可用空间,即使一行中的所有flex元素都是不灵活或不灵活的,但已达到其最大大小。 当元素溢出线时,它还提供对元素对齐的一些控制。

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

  • flex-start (默认):将项目移动到flex-direction方向的开始。
  • flex-end :将项目移近flex方向的末端。
  • start :元素移动到写入模式方向的开始。
  • end :元素在写入模式方向的末尾移动。
  • left :元素向容器的左边缘移动,如果这对flex-direction没有意义,则其行为类似于start
  • :元素被移向容器的右边缘,如果这对伸缩方向没有意义,则其行为类似于start
  • center :元素沿线居中
  • 间隔 :元素沿线均匀分布; 第一个元素在行的开头,最后一个元素在行的末尾
  • space-around :元素沿线均匀分布,周围具有相同的空间。 请注意,从视觉上看,空间是不相等的,因为所有元素的两侧都具有相同的空间。 第一个元素与容器的边缘相对应具有一个空间单位,但是下一个元素之间具有两个空间单位,因为下一个元素具有自己的间距(适用)。
  • 均匀空间 :元素被分布为使得任意两个元素之间的距离(以及到边缘的距离)相同。

请注意,浏览器对这些值的支持有其细微差别。 例如, 间隔之间从未获得过Edge支持,并且Chrome中还没有开始/结束/左/右。 MDN 具有详细的图表 。 最安全的值是flex-startflex-endcenter

您还可以将两个其他关键字与这些值关联: safeunsafe 。 使用安全机制可确保无论您如何进行这种定位,都无法定位元素,使其不在屏幕上显示(例如,从上方),从而也无法滚动内容(这称为“数据丢失”) 。

对齐项目




此属性确定如何在当前行上沿横向轴放置弹性项目的默认行为。 将其视为横轴(垂直于主轴)的合理内容版本。

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


  • 拉伸 (默认):拉伸以填充容器(仍遵守最小宽度/最大宽度)
  • flex-start / start / self-start :元素放置在横轴的起点。 它们之间的差异很小,在于遵守弹性方向规则或书写模式规则。
  • flex-end / end / self-end :元素位于横轴的末端。 差异还是很细微的,并且符合弹性方向书写模式规则。
  • center :元素在横轴上居中
  • 基线 :元素根据其基线对齐

安全不安全的修饰语关键字可以与所有这些关键字结合使用( 尽管并非所有浏览器都支持 ),这有助于防止元素对齐从而使内容不可访问。

对齐内容




当横向轴上有额外空间时,此属性将flex容器内的线对齐,就像对齐内容将主轴内的各个元素对齐一样。

注意 :仅一行弹性项目时,此属性不适用。

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

  • flex-start / start :项目转移到容器的开头。 受更多支持的flex-start使用flex-direction,start使用写入模式方向。
  • flex-end / end :项目移到容器的末尾。 受更多支持的flex-end使用flex-direction ,而end使用写入模式方向。
  • 中心 :项目在容器中居中
  • 间隔 :元素均匀分布; 第一行在容器的开头,最后一行在结尾
  • 空格 :元素均匀分布,每行相等
  • 均匀空间 :元素均匀分布,它们周围的空间相同
  • 拉伸 (默认):拉伸线以占据剩余空间

安全不安全修饰符关键字可以与所有这些关键字结合使用(尽管并非所有浏览器都支持),这有助于防止元素对齐,从而使内容不可访问。

第一个子元素(flex元素)的属性




订单




默认情况下,弹性项目按原始顺序排列。 但是, order属性控制它们在flex容器中出现的顺序。

 .item { order: <integer>; /* default is 0 */ } 

弹性成长




如果需要,此属性确定flex元素拉伸的能力。 它采用从零开始的值,该值用作比例。 此属性是元素应在柔性容器内占据多少空间。

如果所有flex-grow元素都设置为1,则容器中的剩余空间将在所有子元素之间平均分配。 如果其中一个孩子的值为2,则此元素将占用其余孩子两倍的空间(或至少尝试)。

 .item { flex-grow: <number>; /* default 0 */ } 

不支持负数。

弯曲收缩


如果需要,此属性确定柔性构件收缩的能力。

 .item { flex-shrink: <number>; /* default 1 */ } 

不支持负数。

弹性基础


此属性确定分配剩余空间之前的默认元素大小。 它可以是长度(例如20%,5rem等)或关键字。 auto关键字的意思是“看看我的width或height属性”。 关键字content表示“基于元素内容的大小”-仍未很好地支持此关键字,因此很难验证其使用的是max-contentmin-content还是fit-content

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

如果设置为0 ,则不考虑内容周围的多余空间。 如果设置为auto ,则根据其flex-grow值分配额外的空间。
看到这张照片。


屈曲


这是一起使用flex-growflex-shrinkflex-basis的简写。 第二和第三个参数( flex-shrinkflex-basis )是可选的。 默认情况下为0 1 auto

 .item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] } 

建议您使用此速记属性,而不要设置单个属性。 该缩写可以智能地设置其他含义。

自我调整




此属性使您可以覆盖单个弹性项目的默认对齐方式(或使用align-items指定)。
请查看align-items属性以了解可用值。

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

请注意, floatclearvertical-align属性不会影响flex元素。

例子


让我们从一个非常简单的示例开始,它解决了几乎一个日常问题:完美居中。 此任务最简单的解决方案是使用flexbox。

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

这是由于以下事实:在flex容器中设置为auto的垂直对齐页边距属性会吸收额外的空间。 因此,将margin设置为auto将使对象在两个轴上完美居中。

现在让我们使用更多属性。 考虑由6个元素组成的列表,所有元素均具有固定大小,但可能会有自动大小。 我们希望它们沿水平轴均匀分布,以便在调整浏览器大小时,所有内容都可以很好地缩放,并且无需媒体查询。

 .flex-container { /*    flex  */ display: flex; /*    flex-direction        * ,       : * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /*   ,     */ justify-content: space-around; } 

做完了 其他一切都只是样式。



如果更改屏幕分辨率或缩放比例,则将如下所示:



让我们尝试其他事情。 想象一下,我们在网站顶部具有右对齐的导航元素,但是我们希望它们在中型屏幕上的宽度对齐,并在小型设备上排成一列。 这很简单。

 /*   */ .navigation { display: flex; flex-flow: row wrap; /*           */ justify-content: flex-end; } /*   */ @media all and (max-width: 800px) { .navigation { /*       ,       */ justify-content: space-around; } } /*   */ @media all and (max-width: 500px) { .navigation { /*         ,    */ flex-direction: column; } } 

大屏幕

中屏

小屏幕


让我们通过弹性项目的灵活性来尝试更好的东西! 带有页眉和页脚的三列全页布局如何。 而且它不依赖于元素的初始顺序。

 .wrapper { display: flex; flex-flow: row wrap; } /*  ,      100%,  flex-base */ .wrapper > * { flex: 1 100%; } /*         * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /*   */ @media all and (min-width: 600px) { /*          */ .aside { flex: 1 auto; } } /*   */ @media all and (min-width: 800px) { /*            ,      ,      */ .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } } 

大屏幕

中屏

小屏幕


Flexbox的前缀
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); } 

失误
当然,Flexbox并非没有错误。 我见过的最好的收藏是Philip Walton和Greg Whitworth的Flexbugs 。 这是一个用于跟踪所有对象的开源存储库,因此,我认为最好只是引用它。

浏览器支持


按flexbox的“版本”细分:

  • (新)表示规范中的最新语法(例如display:flex;
  • (tweener)表示自2011年以来奇怪的非正式语法(例如display:flexbox;
  • (old)表示自2009年以来的旧语法(例如display:box;



Blackberry Browser 10+支持新语法。

有关如何混合使用语法以获得更好的浏览器支持的更多信息,请参考本文(CSS技巧)本文(DevOpera)

Source: https://habr.com/ru/post/zh-CN467049/


All Articles