CSS for JavaScript M4 Flexbox

When it was released a decade ago, Flexbox revolutionized layout on the web. It gave us a cohesive system for distributing items along an axis. In this module, we'll learn how to build sophisticated, adaptive layouts using Flexbox.

目前看過最讚的 flex 教學

An Interactive Guide to Flexbox in CSS

layout mode

  • 傳統上都是 Flow layout

  • flexbox 是另一個: Flexbox layout When we flip display to flex, we create a “flex formatting context”. This means that, by default, all children will be positioned according to the Flexbox layout algorithm.

  • the CSS we write is an input for these algorithms, like arguments passed to a function. If we want to truly feel comfortable with CSS, it’s not enough to learn the properties; we have to learn how the algorithms use these properties.

primary/cross axis (everything in Flexbox is pegged to the primary/cross axis.)

flexbox 使用的屬性都跟 primary/cross axis 關聯,所以一定一定要很清楚 primary/cross axis 觀念。

justify 跟著 primary cross

是全部子物件跟著調整。想像:子物件被 priamry cross 串成一串 kebab

align 跟著 cross axis

每個子物件像是一個 cocktail wieners,是獨立的

  • 所以 align items 代表調整全部子物件
  • align self 代表調整單獨一個子物件

有上面的心智模型之後就很好理解:當然不會有『justify-self』這樣的屬性(但是有 『align-content』,理解完 grow / shrink 之後再來看)

container 會侷限住 item 的最大寬度。item 不會超過 container 的寬度

Growing and shrinking

flex-basis

In a Flex row, flex-basis does the same thing as width. In a Flex column, flex-basis does the same thing as height. 在 row 流向,basis 就像是 width; column 流向,basis 就像是 height。

the Flexbox authors created a generic “size” property called flex-basis.

It’s like width or height, but pegged to the primary axis, like everything else. It allows us to set the hypothetical size of an element in the primary-axis direction, regardless of whether that’s horizontal or vertical.

  • flex-basis 跟 primary axis 掛鉤,決定 item 的高度/寬度。
  • 例外:flex-basis / width 用在 img ,效果是不太一樣的

flex-grow

去玩互動式操作,說得非常清楚,馬上懂! An Interactive Guide to Flexbox in CSS

flex-shrink

we can think of it as the “inverse” of flex-grow. They’re two sides of the same coin:

  • flex-grow controls how the extra space is distributed when the items are smaller than their container.
  • flex-shrink controls how space is removed when the items are bigger than their container.

去玩互動式操作,說得非常清楚,馬上懂! An Interactive Guide to Flexbox in CSS

總合以上: flex-grow 跟 flex-shrink 不可能同時一起作用(簡單的邏輯問題) only one of these properties can be active at once. If there’s extra space, flex-shrink has no effect, since the items don’t need to shrink. And if the children are too big for their container, flex-grow has no effect, because there’s no extra space to divvy up.

Preventing shrinking

我們通常不想要 shrink 圖片、svg

本篇文章最最重要的觀念:The minimum size gotcha

it’s super important. It may be the single most helpful thing in this entire article! An Interactive Guide to Flexbox in CSS

  • input 等等一些 html element 有瀏覽器預設的寬度,flexbox 無法用 flex-shrink 去縮減它
  • 可使用 min-width: 0 來跳過這個限制。 By setting min-width: 0px directly on the Flex child, we tell the Flexbox algorithm to overwrite the “built-in” minimum width. Because we’ve set it to 0px, the element can shrink as much as necessary. 但是還是要小心使用,有些地方用了會更糟糕(詳見文章的例子)

超實用技巧 margin: auto

An Interactive Guide to Flexbox in CSS

flex-wrap()

When we set flex-wrap: wrap, items won’t shrink below their hypothetical size. At least, not when wrapping onto the next row/column is an option!

一串 kebab 變成各自獨立的多串。 With flex-wrap: wrap, we no longer have a single primary axis line that can skewer each item. Effectively, each row acts as its own mini flex container. Instead of 1 big skewer, each row gets its own skewer:

如果 kebab 不只是一串…? (flex-wrap: wrap)

An Interactive Guide to Flexbox in CSS (flex-wrap: wrap) 會有多串 kebab, 此時:

  • grow / shrink 都失效!
  • justify-content 依舊跟 primary axis 掛鉤
  • align-items 依舊跟 cross axis 掛鉤(會套用到全部的 kebab)
  • 『align-content』 就有作用了,跟 cross axis 掛鉤 這邊觀念小複雜,多看幾次就懂了!

實際範例:解釋一個神奇的 RWD 效果

An Interactive Guide to Flexbox in CSS

Shorthand Gotchas

To summarize: when we use the flex shorthand, we set flex-basis to 0, and this value will override any width you set. In other words, width has no effect in this snippet (when used inside a flex-direction: row container):

1
2
3
4
5

.item {
  flex: 1;
  width: 200px;
}

To prevent this unwanted surprise, we should instead use flex-basis. And if you need to set either flex-grow or flex-shrink, you should use the shorthand:

1
2
3
4

.item {
  flex: 1 1 200px;
}