CSS3 彈性盒子(flexbox),是一種新的佈局方式。使用 flexbox,可以很方便的實現常見的佈局以及居中效果。Bootstrap v4 的 Media object 也是使用 flexbox 來實現。flexbox 相關的屬性較多,本文便結合幾種的情形來探討 flexbox 的應用場景。
Boostrap v3 中的 Media object 使用 table-cell 實現,新版本則採用了 flexbox。table-cell 是一個不太常見的屬性,使用該屬性主要是:1. 實現兩欄或者多欄佈局;2.很容易實現元素垂直居中效果。
v4 版本使用了 flexbox,完成功能的同時,相較於 v3 更加簡潔了。下面我們來結合 Media Object 介紹 flexbox 的相關知識。
1. 常見的 Media object
Media object 用來實現常見的兩欄或者多欄佈局。
html 片段:
<div class="media">
<img class="media-left media-pic" src="../assets/logo.png" />
<div class="media-body">body</div>
<div class="media-right">right</div>
</div>
複製程式碼
scss 片段:
.media {
display: flex;
.media-pic {
width: 50px;
height: 50px;
margin-right: 10px;
}
.media-body {
flex: 1 1 230px;
background-color: #b1b1b1;
}
.media-right {
width: 50px;
}
}
複製程式碼
在需要佈局的區域設定 display: flex 就完成了最基本的佈局。通過在 media-body 部分設定 flex: 1 來讓這部分自動佔據剩餘寬度。flex 是 flex-grow,flex-shrink 與 flex-basis 的簡寫,flex: 1 相當於 flex: 1 1 none,其中 flex-shink 為 1,該元素寬度擴張為剩餘的寬度。
2. 常見的居中效果
有了 flexbox,我們可以很方便實現一些居中效果。這裡討論兩種情形的居中。
2.1 元素的居中
在沒有 flexbox 之前,讓一個塊級元素垂直居中用的是 負外邊距
或者 table-cell
的方式來實現。現在有了 flexbox,居中很容易實現。
html 片段:
<div class="vertical-container">
<p>簡單的垂直居中佈局的方法</p>
</div>
複製程式碼
scss 片段:
.vertical-container {
display: flex;
align-items: center;
justify-content: center;
}
複製程式碼
2.2 align-self-center
在進行多欄佈局中,我們其中的某一項垂直居中,Bootstrap 提供了一個 align-self-center
的類。把這個類新增到需要垂直居中的 flex item 上即可。
.align-self-center {
align-self: center;
}
複製程式碼
3. 關於 Flexbox 的一些細節
3.1 flex 與 flex-wrap 屬性
flex 是 flex-shrink flex-grow flex-basis 的縮寫,初始值是 flex: 0 1 auto。 預設情況下 flex-shrink 為 1,也就是說當 flex item 元素的寬度大於 Flexbox 的寬度時,flex item 元素的寬度會自動等比縮小,以避免撐破父元素。如果不希望子元素縮放,有兩種情形。
- 設定 flex-shrink 為 0,父元素加上滾動條。
.media {
overflow-x: scroll;
.box {
flex-shirnk: 0;
}
}
複製程式碼
- 設定父元素的 flex-wrap 為 wrap。
.media {
flex-wrap: wrap;
}
複製程式碼
3.2 當使用 text-overflow 需要注意的細節
CSS 的 text-overflow 可以用來控制超長溢位的文字內容的顯示方式,對於超出的內容可以是直接截斷、用省略號表示,或用自定義的字元替代。但是要想使該屬性生效,還需設定元素的 overflow,white-space 屬性。我們可以簡單寫一個 text-overflow 的類,專門用來控制文字的顯示。
.text-overflow {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
複製程式碼
white-space: no-wrap
表示文字不會換行,除非遇到 <br>。與 Media object 想結合時,可能會導致文字把 Flex 容器撐破的情形。
<h4>情形-1</h4>
<div class="media">
<img class="media-left" src="../assets/logo.png" />
<div class="media-body text-overflow">
Vue.js (讀音 /vjuː/,類似於 view) 是一套構建使用者介面的漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。
</div>
<div class="media-right"></div>
</div>
<h4>情形-2</h4>
<div class="media media3 media3-3">
<img class="media-left" src="../assets/logo.png" />
<div class="media-body">
<p class="text-overflow">Vue.js (讀音 /vjuː/,類似於 view) 是一套構建使用者介面的漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。</p>
</div>
<div class="media-right"></div>
</div>
複製程式碼
渲染效果如下:
我們發現text-overflow
作用在 flex item 下的元素時,flex item 寬度被撐破,整個 Flexbox 排版也全亂掉。情形-2演示的場景很常見。為了排版的靈活性,一般情況下,並不會把 media-body 的寬度設定為一個固定值。一種最簡便的解決方案是設定 media-body 的 min-width 為 0。
.media-body {
min-width: 0;
}
複製程式碼
當設定 min-width 為 0,media-body 的寬度就不會超過 Flexbox 的剩餘寬度。
4. 總結
flex 彈性盒子的屬性眾多,一篇文章詳解全部的屬性也不太可能。一種好的方法是結合常見的排版情形來學習 flexbox。 下面總結一下文中涉及到的 flex box 相關的屬性。
作用在 flex container 的屬性:
- justify-content
- align-items
- flex-wrap
作用在 flex item 上的屬性:
- flex (flex-shrink flex-grow flex-basis)
- align-self
本文只是結合自己的開發經驗總結出一些常見情形,文中未涉及到或者講解不詳細的地方,大家可以在 mdn 上查閱關於 flex 的資料。