1. 1. 先看一个案例:
  2. 2. 为什么没有justify-self
  3. 3. 【译】更多的例子
    1. 3.1. 第一个flex item居左,其余flex item居右
    2. 3.2. 其他实用场景
  4. 4. 将flex item放置在一个角上
  5. 5. 水平、垂直居中
  6. 6. 居中一个flex item, 然后将第二个flex item 放在第一个flex item 和父元素的边界之间
  7. 7. 当相邻的flex item尺寸不同时,如何居中
  8. 8. justify-content: space-same(这只是一个概念!!!别当真)
Table of Contents ▼

如何灵活在控制Flex Item在主轴上的布局

先看一个案例:

(这个例子最简单,但并非特别有针对性,更好的例子是三栏布局,第一栏左对齐,第二栏要求居中。)
一个页面的头部,经常看到的是最左边放上logo,右边是几个导航链接。

采用Flexbox布局,可能这么写:

HTML

<div class = "header">
  <img class = "header__logo logo" src = "./img/logo.png" />

  <ul class = "nav">
    <li>
      <a href = "#" >Link 1</a>
      <a href = "#" >Link 2</a>
      ……
    </li>
  </ul>
</div>

CSS

.header{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

现在logo和导航在header中按照从左往右布局。
如何让导航在header的右端?

为什么没有justify-self

上述问题的解决的方法很多,只是如果你习惯了align-self,会不会情不自禁联想到justify-self,可惜啊,并没有这个属性——因为没有必要存在这个属性,我们通过其他两个属性完全可以实现类似align-self的功能:

  1. justify-content
  2. auto margins

先来看看W3C的原文:Aligning with ‘auto’ margins

8.1. Aligning with ‘auto’ margins

This section is non-normative. The normative definition of how margins affect flex items is in the Flex Layout Algorithm section.

Auto margins on flex items have an effect very similar to auto margins in block flow:

  • During calculations of flex bases and flexible lengths, auto margins are treated as ‘0’.
  • Prior to alignment via ‘justify-content’ and ‘align-self’, any positive free space is distributed to auto margins in that dimension.
  • Overflowing elements ignore their auto margins and overflow in the end/foot direction.

Note that, if free space is distributed to auto margins, the alignment properties will have no effect in that dimension because the margins will have stolen all the free space left over after flexing.

所以对于一个flex item,当设置margin auto,它的计算顺序如下:

  1. 先按照margin: 0 计算flex item的尺寸;
  2. 将所有父元素的剩余空间赋值给margin(margin的优先级大于justify-content,以及align-self。这有一个类似的场景:如何计算图片尺寸

现在再看看如何修改我们上边的导航:

.nav{
  margin-left: auto;
}

【译】更多的例子

注:原文请看stackoverflow上的回答

第一个flex item居左,其余flex item居右

其他实用场景

将flex item放置在一个角上

你会不会想这么写哈哈哈哈
.box { align-self: flex-end; justify-self: flex-end; }

水平、垂直居中

这次这玩意儿可是真的♪(^∇^*) .box56{ margin: auto; }

在flex item中,margin: auto 相当于在flexbox上设置了justify-center:center; align-items:center

除了在container上应用如下样式:

.container{
  justify-content: center;
  align-items: center;
}

你可以直接在flex item上使用margin:

.box56{
  margin: auto;
}

当我们要居中一个大小超出父元素的子元素来说,利用margin:auto将非常有用(http://stackoverflow.com/questions/33454533/cant-scroll-to-top-of-flex-item-that-is-overflowing-container)

译者注:在flexbox中,当子元素超出了父元素,而且我们采用了align-items: autojustify-content: center进行居中,会出现超出部门内容不可见的问题。比如说,flex item的高度是500px,而container高度是300;正常的情况是我们拉动垂直方向的滚动条,能够浏览flex item的全部内容;
但实际上是,你只能看到flex item的部分内容,顶部的内容是看不到的(0-100这一部分),不管你怎么拉动滚动条(如果不好理解,自己写代码试试就知道了)。其中的原因是设置justify-contentalign-items居中后,即使flex item超出container还是保持居中。

居中一个flex item, 然后将第二个flex item 放在第一个flex item 和父元素的边界之间

相关内容

Aligning two flex items: one to the top, the other centered
How to center one of two flex items in a flex container?
Flexbox: Align between bottom and center?
How to center-align one flex item and right-align another using Flexbox

注:这两个方法只能针对高度(宽度)相同的flex items 有效。不同高度的解决方案,看下一个例子。

当相邻的flex item尺寸不同时,如何居中

场景描述:
一行里边有三个flex items,将第二个item相对父元素居中(justify-content: center),同时,相邻的两个元素在container的两侧(justify-self:flex-startjustify-self: flex-end)。

注意:当flex items大小不同时,将container的justify-content设置成space-aroundspace-between是不能让第二个flex item居中的。

正如上边提醒的,除非所有flex items高度或者宽度一致,否者中间的元素是没办法真正居中的。这个问题真的让人觉得justify-self很有必要呀!!!。

但是,目前来说,我们可以对flex item采用绝对定位,虽然绝对定位会使元素浮出文档流,并非完美,你也许还是会用得找的:

另外一个不采用绝对定位的方法:

justify-content: space-same(这只是一个概念!!!别当真)

再来看justify-content,我们还会经常碰到一个需求:

  • space-same: space-betweenspace-around的中间产物(hybrid,词穷了。。。)。说白了其实很简单,就是相当于让flex items评分剩余的空间,同时让两侧的空白是等于相邻flex item间距的,而不是像space around那样等于一半。

来来来,用伪元素解决这个问题: