CSS的flexbox布局最难理解的部分是flex
属性,该属性的取值形式为1 1 auto
。当我们深入研究flex
属性的时候,会发现它只是flex-grow
和flex-basis
属性的一个简写方式,这会让我们感到相当迷惑。
大部分对flex
属性规范的解释都是使用非常专业的术语,相当难理解。经过仔细研究之后,我们发现它实际上指的是flexbox视觉权重。
默认的Flexbox算法
我们一般会认为flexbox会均匀的分布排列它的子元素。让我们来做个试验:在<section>
元素中放置一组<article>
子元素。
<section> <article> <img src="1.jpg" alt> <h1>Washington D.C. Attacked By Flying Saucers</h1> <h2>Dateline Washington D.C.</h2> <h3>Frank Bragg reporting</h3> <p>The country was brought to a standstill today when flying saucers appeared over the nation’s capital. </article> <article> … </section>
我们在<section>
元素上设置display: flex
,然后会期望得到的结果是所有的<article>
元素都是等宽排列的。但是结果却不是这样的。
如下图所示,每一个flex 子项都会有它各自的宽度,这取决于它们的内容的多少。
制作等宽的Flex Items
如果我们想使<section>
中的三篇文章都有相同的宽度,你可以为每个<article>
元素都设置33%的宽度值,但这种方式并不是最佳的解决方案,它会使flexbox布局的优势得不到最好的体现。我们建议使用下面的方式来解决这个问题:
article { flex: 1 0 0px; }
乍一看我们不明白它是什么意思,现在让我们来翻译一下:
第一个参数相当于flex-grow: 1;
。它的意思是使用flex-grow: 1
来确保这个元素的宽度等于其它flex项的宽度。
第二个参数相当于flex-shrink: 0;
。它的意思是不要缩小这个元素来适应它的可用空间。
第三个参数相当于flex-basis: 0px;
.它的意思是这个元素从0像素宽度开始进行调整。
这个写法可以简写为:
article { flex: 1; }
强烈建议你在CSS中用这种简写的方法:不是因为这样书写方便,而是这样写可以更好的适应跨浏览器的需要。
flex
属性只有一个无单位的值,它被定义为flex-grow
。如果flex
只有一个带有单位(例如px)的值,它会被定义为flex-basis
。我们可以像下面这样书写CSS样式:
section { display: flex; } article { margin: 1rem; flex: 1; } article img { width: 100%; height: auto; }
上面的代码会创建等宽的flexbox布局。
Flexbox布局的优势在于它是自适应的:如果再添加一个<article>
元素,所有<article>
的空间会重新分配来适应等宽的需求。
设置其中一个Flex项不同的宽度
我们的demo是一个新闻版块的内容。这种布局每一条新闻都需要一个较大的版块来展示,而其中头疼新闻要比其它新闻占用更大的空间,我们为头条新闻设置class为breaking
:
<article class="breaking">
我们要制作头条新闻是其他文章宽度的2倍,我们可以为这个class使用flex
属性设置一个不同的flex-grow
值。
article.breaking { flex: 2; }
这个flex-grow
属性会将当前的头条新闻的宽度设置为其它文章的两倍。文章的高度由它的内容来决定,根据网页布局的一个基本原则,flexbox布局同一行的元素的高度由这一行中内容最多的元素来决定。
小屏幕设备的解决方案
在小屏幕的设备上,我们每一行只显示一篇文章:
@media screen and (max-width: 750px) { section { -webkit-box-orient: vertical; flex-direction: column; } }
-webkit-box-orient: vertical
属性是为IOS 7定制的,不知为什么它不支持flex-direction: column
属性。注意在单行排列时所有文章的宽度都是一致的,flex-grow
属性不会影响它们的宽度设置。每一篇文章的宽度由它的内容来决定。
小结
grow
是flexbox的视觉权重属性。在下一篇文章中,我们会讲述flex的另外两个的属性:flex-shrink
和flex-basis
。