最近看到几篇博文讲解margin:auto在flex容器中的使用,可惜的是大多讲解都浮于页面表现,没深究其中的作用机理,本文在此浅薄对其表现机理做简单探讨.

引子

日常业务迭代过程中,flex已经是前端工程师解决常见布局的神兵利器.但是随着使用的深入,偶然会发觉flex对于简单的布局足够直接迅速,但是对于稍稍复杂一些的布局,就需要层层的包裹分组来解决.举个栗子,下图是我们常见的布局图:

如果flex容器之中仅仅只有三个元素,彼此分离,我们借助于justify-content就足够应付.但是如果其中两个元素需要当成一组来处理,比如图一中的BC,使用flex布局,就不能保证布局结构足够简单,就需要把AB用一个div之类的标签包括起来当成一个元素,并且BC需要在新的包裹容器中居中,才可以实现上图布局.代码如下:

<div class="flex-container">
<div class="A">A</div>
<div class="BC">
<div class="B">B</div>
<div class="C">C</div>
</div>
<div class="D">D</div>
</div>
.flex-container {
display: flex;
justify-content: space-between;
}
.A {
background: #FFE6CC;
width: 100px;
}
.BC {
flex:;
display: flex;
justify-content: center;
align-items: center;
}
.B {
background: #FFF2CC;
width: 100px;
}
.C {
background: #F8CECC;
width: 100px;
}
.D {
background: #E1D5E7;
width: 100px;
}

那么有没有比上面更简单的布局方式么?有,那就是使用margin:auto.

使用margin:auto给元素分组

如果使用margin:auto的话,那么怎么更加简单实现上图的布局.
下面是布局代码.

<div class="flex-container">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
<div class="D">D</div>
</div>
.flex-container {
display: flex;
justify-content: space-between;
}
.A {
background: #FFE6CC;
width: 100px;
}
.B {
background: #FFF2CC;
width: 100px;
margin-left: auto;
}
.C {
background: #F8CECC;
width: 100px;
margin-right: auto;
}
.D {
background: #E1D5E7;
width: 100px;
}

相对与引子中的代码来说,图中标红的是改动的地方.
主要是下面三个改动:

  • 去掉外层flex中的justify-content属性.[margin:auto优先级比justify-content高,会使此属性失效,所以删除]

  • 简化html结构.原来需要三层结构,简化后只需要两层.

  • B的margin-left和C的margin-right设置为auto.

机理探讨

最好的原理说明在css的规范中.我们首先查阅规范中对于flex容器margin:auto的说明[资源来源可参阅文末的参考资料].

规范中明确说明了两个重要的点,:

  • margin:auto优先级比 justify-content,align-self优先级高

  • 如果正常分配空间之后,仍然有未分配的空间,剩下的空间将分配给margin:auto的元素.

但是此规范没有说明,如果有多个margin:auto的元素,空间将如何分配?对此,mdn文档有说明[资源来源可参阅文末的参考资料]:

mdn明确告知,空间将会平均分配给margin:auto的元素.
总结来看,就是可以使用margin:auto在flex容器主轴方向给子元素的左右两侧分配空间.

更多示例

1. 设置外边距auto越多,分配数量越多

到此有看官可能有疑问了,如果flex容器,一个子元素margin-left,margin-right都设置为auto,另外一个子元素仅仅只设置了margin-left,那么空间该如何分配.实测证明,在主轴方向上,有几个外边距(指margin-left,margin-right)设置为auto,那么就分几份.

.flex-container {
display: flex;
}
.A {
background: #FFE6CC;
width: 100px;
}
.B {
background: #FFF2CC;
width: 100px;
margin-left: auto;
margin-right: auto;
}
.C {
background: #F8CECC;
width: 100px;
margin-left: auto;
}
.D {
background: #E1D5E7;
width: 100px;
}

上述代码显示效果如下:

B因为左右两个外边距都是auto,所以会各占一份,C因为只有左边距是auto,因此只占用一份.

2. flex列容器

上面的举例主轴都是水平方向.那么主轴是竖直方向的是否也适用呢?这里可以肯定回答: 列容器margin:auto仍然有效.不过需要把margin-left,margin-right改成设置 margin-top,margin-bottom为auto.

.flex-container {
display: flex;
flex-direction: column;
height: 500px;
}
.A {
background: #FFE6CC;
width: 100px;
}
.B {
background: #FFF2CC;
width: 100px;
margin-top: auto;
}
.C {
background: #F8CECC;
width: 100px;
margin-bottom: auto;
}
.D {
background: #E1D5E7;
width: 100px;
}

 

上述代码显示效果如下:

从示例中可以看出,margin:auto有空间占有效应. 使用margin:auto在某些情况下可以替代 flex:1, justify-content: space-between等的使用.这里不再展开阐释.

总结

margin:auto适合用来给flex容器的子元素间(在主轴方向)增加空间,适当的使用margin:auto可以简化dom的布局结构以及样式代码,提高编程效率.

参考资料

[1] w3c css-flexbox规范: https://www.w3.org/TR/css-flexbox-1/#auto-margins

[2] mdn关于margin:auto对flex容器的影响说明: https://developer.mozilla.org/zh-CN/docs/Web/CSS/margin-left

  微信搜索 ''十八将君'',关注我的公众号和我一起成长~

[CSS七分钟系列]都1902年了,还不知道用margin:auto给flex容器内元素分组?的更多相关文章

  1. CSS学习笔记——盒模型,块级元素和行内元素的区别和特性

    今天本来打算根据自己的计划进行前端自动化的学习的,无奈早上接到一个任务需求需要新增一个页面.自从因为工作需要转前端之后,自己的主要注意力几 乎都放在JavaScript上面了,对CSS和HTML这方面 ...

  2. CSS布局十八般武艺都在这里了

    CSS布局十八般武艺都在这里了 Shelley Lee 4 个月前 布局是CSS中一个重要部分,本文总结了CSS布局中的常用技巧,包括常用的水平居中.垂直居中方法,以及单列布局.多列布局的多种实现方式 ...

  3. HTML和CSS 入门系列(一):超链接、选择器、颜色、盒模式、DIV布局、图片

    一.超链接 二.CSS选择器 CSS的全称叫做: Cascading Style Sheets 级联样式表的缩写. 2.1 类型选择器 2.2 派生选择器 2.3 伪类选择器 <style &g ...

  4. CSS 魔法系列:纯 CSS 绘制各种图形《系列六》

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  5. CSS 魔法系列:纯 CSS 绘制各种图形《系列五》

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  6. CSS 魔法系列:纯 CSS 绘制图形(各种形状的钻石)

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  7. CSS 魔法系列:纯 CSS 绘制图形(心形、六边形等)

    <CSS 魔法系列>继续给大家带来 CSS 在网页中以及图形绘制中的使用.这篇文章给大家带来的是纯 CSS 绘制五角星.六角形.五边形.六边形.心形等等. 我们的网页因为 CSS 而呈现千 ...

  8. CSS 魔法系列:纯 CSS 绘制基本图形(圆、椭圆等)

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  9. IE CSS Bug 系列

    1.[IE CSS Bug系列]IE6&IE7图片链接无效 <!doctype html> <html> <head> <meta charset=& ...

随机推荐

  1. Andriod Studio设置代码字体大小

  2. fenby C语言 P9

    逻辑运算 真1 假0 &&与 真&&真为真 真&&假为假 假&&真为假 假&&假为假 ||或 真||真为真 真||假为真 ...

  3. 2018-7-30 python基本数据类型

    python基本数据类型 int      整数 str      字符串. 一般不存放大量的数据 bool   布尔值. 用来判断. True, False list      列表.用来存放大量数 ...

  4. 超融合与传统IT架构对比:成本价格优势有哪些

    之前文章中,我们已经介绍了超融合给用户 IT 基础架构带来的各个方面的价值,其中成本只是超融合架构的优势之一.但很多用户还是会非常关心这个话题,希望能有更具体的了解,所以本文整理超融合和传统 FC S ...

  5. 搭建邮件服务器,使用Postfix与Dovecot收发电子邮件

    小知识: 我们为什么要搭建邮件服务器呢?有时候我们处于一个局域网内,不能及时的分享各自的研究成果,迫切的需要一种能够借助于网络且建立在计算机之间的传输数据的方法.所以我们需要搭建邮件服务器,这样的话既 ...

  6. 虚拟机kali linux与windows主机共享文件

    在windows中我们可以直接拖拽文件,有的时候wmtools无效 很苦恼 从kali中托文件就不可以, 于是那就用到了共享文件夹 一.在虚拟机名称处右键,选择设置,会弹出一个设置框 二.选择选项-& ...

  7. 程序员接私活经验总结,来自csdn论坛语录

    以下为网上摘录,以做笔记: 可是到网上看看,似乎接私活也有很多不容易,技术问题本身是个因素,还有很多有技术的人接私活时被骗,或者是合作到最后以失败告终,所以想请有经验的大侠们出来指点一下,接私活是怎么 ...

  8. SpringBoot之集成MyBatis

    引入工程依赖包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  9. 7.30 NOIP模拟10

    T1.辣鸡 考试的时候竟然被我以“麻烦”弃掉了,赛后发现这题好水啊,直接sort一下寻找四周即可. T2.模板 考试时期望得分70,实际得分5 首先看到这种题基本就是线段树,我们以时间为下标,对每一个 ...

  10. EffectiveJava-3

    一.如果其他类型更适合,则尽量避免使用字符串 1. 字符串不适合代替枚举类型 2. 字符串不适合代替聚合类型,例如: String compoundKey = className+ "#&q ...