CSS3 Flexible Box模型解释了

The finished page - although not particularly complex, this has been laid out entirely using Flexible Box Layout properties

完成的页面 - 虽然不是特别复杂,但已经完全使用Flexible Box Layout属性进行了布局

我们此刻布置网页的方式有点像hacky。无论您是使用浮动,定位还是技术组合,总是需要额外的工作来使一切看起来都像您想要的那样 - 通常需要大量计算边距,高度和宽度。这主要是因为我们将这些CSS属性用于他们最初未设想的任务。我们努力工作并获得了一些很好的结果,但是去寻找一些应该简单得多的东西确实是一件非常麻烦的事情。

输入W3C称之为'CSS3 Flexible Box Layout Module'的内容,许多设计师将其称为Flexible Box模型。为简洁起见,我将在本文的其余部分将其称为Flex Box。这是第一个具有任何类型的实际实现的模块,专门用于相对于彼此布置页面元素。我将向您展示如何使用它来制作简单,适应性强且响应迅速的网页。

方法

在我进行实际演示之前,让我试着解释一下Flex Box方法实际上做了什么。

我应该重申,Flex Box的大部分功能已经可以通过现有的CSS属性实现,例如float,margin和position。不同之处在于Flex Box的创建意图是布置网页,因此它使这项任务变得更加容易。

以下是它的作用的快速总结:在元素之间平均分配空间,而无需进行复杂的计算;使您能够制作等高的列并垂直对齐其父级中的元素;使您能够更改元素的显示顺序,而不管DOM树中的顺序如何;无需使用float属性进行布局。简而言之,它使您能够完成过去不得不进行的所有操作。听起来很完美!

最大的缺点是目前浏览器支持。 Firefox和WebKit浏览器(包括Safari和Chrome)现在支持这一点,但IE9是否会效仿尚不确定。

技术预览显示了基本的支持,但在Beta中已被删除。交叉你的手指,它将及时恢复最终版本,无论何时可能。与此同时,您必须为不支持的浏览器创建后备样式表。

为了最好地展示Flex Box的功能,我将建立一个小型促销网站。这是一个非常简单的网站 - 带有标题和简介副本的标题,三个推广内容部分和一个页脚。毫无疑问,你建造的网站比以前复杂得多,但不是我要向你展示的方式 - 本文中重要的不是目的地,而是旅程。您可以在我们的可下载教程文件中看到完成的网页flexbox-complete.html。您必须使用Firefox,Chrome或Safari(或其他Gecko或WebKit浏览器)来查看它,因为我故意不为此示例创建任何后备样式。

The section elements all have the value of 1 for the box-flex property, and so are equally resized. Compare this to the main example to see the difference

对于box-flex属性,section元素的值都是1,因此同样调整大小。将此与主要示例进行比较以查看差异

在示例中需要注意三件事:首先,标题中的标题和介绍副本的垂直对齐;二,三个促销箱的分布;第三,促销箱的等高柱。所有这些都是使用Flex Box以最少的努力实现的。让我们从头部开始详细了解每个区域。

对齐元素

标题的标记非常简单;请注意,我在这里和整篇文章中都使用了一些HTML5结构元素,但是在您自己的页面中绝对没有要求您这样做:

...

...

要使内部div元素在标题内水平和垂直居中对齐,需要使用三个属性:一个具有新值的CSS2.1属性,以及两个CSS3新属性,可能对您不熟悉。现有属性显示;我们目前使用它与块或内联等值,但在Flex Box中我们得到一个新选项:框。

标题{display:box; }

事实上,由于模块仍然没有被认为是完全稳定的(工作组仍然在迭代一些更精细的点),我们必须为每个支持布局引擎使用前缀属性关键字,因此我们的完整代码要求是:

header {display:-moz-box; display:-webkit-box; }

但是,为了避免重复并使代码示例更加清晰,我将只引用本文中的非前缀属性和值;您可以在教程文件中看到实际所需的值。哦,请注意,如果Flex Box在IE9中实现,它也会加上前缀,因此您必须在上面的代码中添加-ms-box,以及所有其他新属性。

This demo of a three-column layout made with Flex Box properties can be found on the blog of York-based web agency Isotoma

这个使用Flex Box属性制作的三列布局演示可以在位于约克的网络代理商Isotoma的博客上找到

那么新的盒子值实际上做的是它指示元素使用盒子布局算法来渲染它的子元素,在能够使用任何新的Flex Box属性之前我们需要这样做。

现在我们已经触发了盒子布局渲染,让我们看看我们如何使元素在其父元素中集中对齐。我的示例中的标题元素是800px宽和220px高,但其中的div元素是480px宽和116px高。这意味着两个元素之间有相当多的额外空间(水平320像素,垂直104像素)。使用CSS2.1,我可以使用margin:auto来水平地集中对齐div,但是垂直地执行相同操作会涉及一些计算和使用负边距,这在处理动态内容时根本不实用。

使用Flex Box解决问题要容易得多,并且需要使用我提到的两个新属性:box-align和box-pack。

标题{display:box; box-align:center;盒装:中心; }

第一个box-align通过在垂直于元素方向的轴上分布额外空间来定位子元素(在我们的示例中为div) - 也就是说,如果元素水平定向,则空间将垂直分布,而副-versa。默认情况下,子元素的方向是水平的,因此框对齐作用于垂直方向。当我们给出center的值时,box-align会在元素的上方和下方分配空白空间,因此将其置于中心位置。

Partial support for the Flexible Boy Layout module was in the platform previews of IE9, but removed from the Beta; will the be reinstated for the final release?

对Flexible Boy Layout模块的部分支持在IE9的平台预览中,但已从Beta中删除;是否会恢复最终版本?

第二个属性box-pack以类似的方式工作,但沿着元素所朝向的同一轴分布空间(正如我们刚刚看到的那样,默认情况下是水平轴)。我们再次提供了中心的值,因此沿水平轴的额外空间在元素的左侧和右侧之间均匀分布,再次将其定位在中央。具有中心值的两个属性的组合使得我们的标题副本整齐地位于父元素的水平和垂直中间,并且我们不必关心边距,位置或百分比。简单!

更改对齐值

通过更改这些属性中的一个或两个的值,我可以将我的元素放置在父元素中的任何位置。

要看到这个插图,请查看我的页脚:

...

p元素位于父元素的右侧和垂直中心,因为我给出了一个box-align值为center,box-pack值为end:

页脚{显示:框; Box-align:center;盒装:结束;身高:200px; }

box-align的其他值包括start,baseline和stretch;然而,对于盒装,启动和证明 - 后一个值在Firefox中不起作用。

Box-flex属性

如果您通过查看示例文件中使用的代码一直关注本文,那么您将发现还有另一个我尚未提及的属性。这是box-flex属性,与我们到目前为止看到的属性不同,它适用于子元素而不是父元素:

标题div,页脚p {box-flex:0; }

给box-flex赋值为0表示元素将保留其原始尺寸,不受动态调整大小的影响。为了解释这意味着什么并看看不同值有什么影响,让我们来看看页面的主要内容区域。

在标题下面有三个部分元素,宣传Project Gutenberg提供的不同标题(如果你知道标题之间的联系,奖励极客点):

...

...

如果您查看样式表,您会注意到所有三个都具有相同的指定宽度 - 180px - 但在页面本身中右侧的那个更宽。这是怎么回事?这是因为这段代码:

section {box-flex:0;宽度:180px; } section:first-of-type {box-flex:1; }

每个section元素的box-flex值为0,正如我刚才提到的,这意味着它们不受动态大小调整的影响。但是,应用了第一个类型选择器的部分的box-flex值为1.当元素的box-flex值大于0时,它们变得灵活,并且它们的尺寸将增加,直到它们为止填充他们的父元素。这种增加是由box-flex属性的值决定的,它是一种比率。
想象一下,你有一个90px宽的父母和两个30px宽的孩子,这意味着沿着水平面有30px的差异(额外的空间)。

如果第一个孩子的box-flex值为1,第二个孩子的值为2,则额外的空间将以1:2的比例分配到每个孩子的宽度 - 因此第一个孩子的宽度将增加10px,第二,20px。

在我们这里的三节布局的情况下,额外的空间以1:0:0的比例分布 - 也就是说,它全部分布到第一部分,这意味着它扩展以填充空白空间而另外两个空间保持原来的大小。

如果所有三个截面元素具有相同的box-flex值(大于0),则它们将全部扩展到相同的宽度。您可以在教程文件flexbox-alternate.html中看到这种替代方法;每个部分的值都是1(一),因此它们都分配了相同的分配份额,并调整为213px宽。但你不限于0或1;允许任何数字值,空白空间将以该比率分配。

顺便说一下,请注意每个截面元素的高度相同。这是使用Flex Box的固有奖励 - 同一轴上的所有元素将沿与其方向相反的轴(在这种情况下,水平方向)给予相同的尺寸。默认情况下,等高列!

内容订单

您可能已经注意到,在我的代码中,我的标记中的第一个元素元素(id为section-section的那个元素)实际上显示在三个元素的右侧 - 也就是说,它出现在它的显示顺序中DOM。

在Flex Box之前执行此操作意味着要么计算浮动或定位的宽度,要么使用JavaScript。与我在这里实现它的方式相比,它们都不是最佳的。

实际上有两种方法可以用Flex Box来解决这个问题。第一种是使用盒子方向属性;这适用于父级并设置灵活子元素的显示顺序(我给它们提供了唯一的ID,以便更容易理解)。默认情况下,该值是正常的,因此我的元素将以DOM顺序显示 - 即1-2-3 - 但使用reverse值将表示我的元素显示为3-2-1:

第{节方向:反向; }

但是,我的元素实际显示的顺序是2-3-1,这是我使用box-ordinal-group属性实现的。通过此操作,您可以通过为属性指定整数值(整数)来创建元素组。具有相同值的元素将形成一个组;组中的所有元素将以DOM顺序显示,但组将按其box-ordinal-group值的升序显示。默认情况下,该值为1(一),但在我的代码中,我已指定第一个section元素的值为2:

Section:first-of-type {box-ordinal-group:2; }

由于第二和第三部分元素在值为1的组中,它们将首先以DOM顺序(2-3)显示。第一个元素在组中,值为2,因此将显示下一个元素。结果是我的最终订单2-3-1。

摘要

就是这样了!我没有机会提到box-flex-group,box-lines或box-orient属性,但我希望这篇文章让你好奇,能够自己找到更多。
我也希望我向您展示Flex Box使动态布局变得简单,但实际上我几乎没有涉及新模块的潜力。它真正发挥作用的地方在于它将它与媒体查询结合起来,以制作响应页面尺寸的布局。

WebKit浏览器目前有一个良好,稳定的Flex Box实现,所以尽管这个模块缺乏桌面浏览器支持(* cough * Internet Explorer * cough *),但有一个领域已经可以被利用 - iOS Web App开发。

想象一个针对两种不同屏幕尺寸的功能进行了优化的应用程序,应该不会太过分。然而,那是另一天的教程......



翻译字数超限