點燈坊

學而時習之,不亦悅乎

CSS Flexbox 之 Cross Axis 對齊

Sam Xiao's Avatar 2019-07-08

row-direction 主要定義 Main Axis 方向,需搭配 justify-content 設定 alignment;若要針對 Cross Axis,則要使用 align-items

Version

macOS Mojave 10.14.5
WebStorm 2019.1.3
Chrome 75.0.3770.100
CSS 3

HTML

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flexbox</title>
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="box">
    <article>
      <header>
        <h1>Boston</h1>
      </header>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi asperiores debitis dolorem ducimus esse fugiat id libero minima minus, mollitia necessitatibus nostrum odit porro quaerat quia quod sint velit vero!
      </p>
    </article>
    <article>
      <header>
        <h1>New York</h1>
      </header>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Hic, nulla.</p>
    </article>
    <article>
      <header>
        <h1>Chicago</h1>
      </header>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aliquam animi asperiores at atque consectetur dolore dolorem ducimus ea error et expedita inventore ipsa iusto laboriosam laudantium magnam modi molestias nam nemo non numquam odit perspiciatis provident quaerat, quas qui quidem quos reiciendis reprehenderit saepe sit tenetur ullam unde vitae voluptate voluptatibus. Accusantium consectetur cumque delectus error inventore qui voluptatum?
      </p>
    </article>
  </div>
</body>
</html>

<div> 下有 3 個 <article>,各自內文長短不一。

CSS

style.css

article {
  background: #FFF;
  margin: 5px;
  flex: 1;
}

.box {
  display: flex;
  flex-direction: row;
}

第 7 行

.box {
  display: flex;
  flex-direction: row;
}

displayflex,表示使用 flexbox。

flex-directionrow,表示 main axis 為 row,cross axis 為 column

第 1 行

article {
  background: #FFF;
  margin: 5px;
  flex: 1;
}

設定每個 <article>flex1,表示其 flex-grow1,也就是每個 <article> 會以等比例平分 container 剩餘空間。

由於並沒有設定 width,但因為 flex1,所以相當於 3 個 <article> 等寬。

Main Axis vs. Cross Axis

align-items000

Flexbox 有兩個 axis:

  • Main axisrow-direction 所設定方向
  • Cross axis:與 main axis 垂直方向

Stretch

align-items001

Container 內 3 個 item 同高。

.box {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}

align-items 預設為 stretch,也就是在 cross axis 方向會自動 stretch 與 container 同高 (寬)。

由於 .box 沒設定 height,其高度是被最長 item 所撐高,較短的 item 會自動 stretch 與其同高

Flex-start

align-items001

Container 內 3 個 item 在 cross axis 方向皆 靠上對齊

.box {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
}

align-itemsflex-start,因為 cross axis 為 column,為 由上至下,相當於 靠上對齊

Flex-end

align-items003

Container 內 3 個 item 在 cross axis 方向皆 靠下對齊

.box {
  display: flex;
  flex-direction: row;
  align-items: flex-end;
}

align-itemsflex-end,因為 cross axis 為 column,為 由上至下,相當於 靠下對齊

Center

align-items004

Container 內 3 個 item 在 cross axis 方向皆 置中對齊

.box {
  display: flex;
  flex-direction: row;
  align-items: center;
}

align-itemscenter,因為 cross axis 為 column,相當於 垂直置中

Baseline

align-items006

Container 內 3 個 item 在 cross axis 方向皆與 第一行baseline 對齊

.box {
  display: flex;
  flex-direction: row;
  align-items: baseline;
}

align-itemsbaseline,但看起來與 flex-start 一樣。

align-items007

若將 <header> 拿掉,可明顯看出 baselineflex-start 差異。

Align-self

align-items005

Container 內第 1 個 item 與第 3 個 item 為 靠上對齊,但第 2 個 item 為 靠下對齊

.new-york {
  align-self: flex-end;
}

新增 new-york class,align-selfflex-end,表示只有套用該 class 的 item 使用獨特 alignment 設定。

align-self 預設為 auto,也就是自動根據 container 的 align-items 設定

Conclusion

  • justify-content 適用於 main axis;align-items 適用於 cross axis
  • align-items 預設為 stretch,會自動 stretch 與 container 同高 (寬)
  • align-itemsflex-startflex-endcenterjustify-content 相同,唯套用在 cross axis
  • align-itemsbaseline 會與第一行的 baseline 對齊,實務上較少使用
  • 若有 item 套用獨特的 alignment,就要使用 align-self

Reference

Garth Braithwaite, Demystifying alignment in flexbox children
MDN, Aligning Items in a Flex Container
MDN, align-items