介紹
這是關於 Flex 佈局的實踐,原想還水一點字數來介紹 Flex 相關屬性,想想還是算了,阮一峰大佬的兩篇文章推上:
如何用 CSS 來增進對 Flex 的理解:
常規佈局
1. 兩欄佈局
左側定寬,右側自適應:
<Layout-Layout
:background-color="bgColor"
class="flex-layout"
>
<div class="flex__item">left</div>
<div class="flex__item">right</div>
</Layout-Layout>
複製程式碼
.flex-layout
display flex
.flex__item
&:nth-child(1)
background-color #c04851 // 玉紅
flex 0 0 200px
&:nth-child(2)
background-color #440e25 // 古銅紫
flex 1 1 auto
複製程式碼
原因解釋:
flex
是一個簡寫屬性,用來設定 flex-grow
、flex-shrink
、flex-basis
。一般來說讓元素等高需要額外設定,而 flex
容器的存在一個預設屬性值:align-items:stretch
,它會幫助你,當然也會給你帶來糟糕的體驗。
2. 三欄佈局
聖盃佈局與雙飛翼佈局都是三欄佈局,稍微介紹一下:聖盃佈局關鍵是父元素設定 padding
,接著子元素通過 margin
負值以及定位;雙飛翼佈局關鍵是中間一欄多了子元素並設定 margin
,然後側邊欄使用 margin
負值。而通過 flex
實現則簡單多了:
<Layout-Layout
:background-color="bgColor"
class="holy-grail"
>
<div class="flex__content">content</div>
<div class="flex__nav">nav</div>
<div class="flex__side">side</div>
</Layout-Layout>
複製程式碼
.holy-grail
display flex
.flex__content
flex 1 1 auto
background-color #009999
.flex__nav, .flex__side
flex 0 0 120px
.flex__nav
order -1
background-color #1D7373
.flex__side
background-color #33CCCC
複製程式碼
原因解釋:
中間一欄為核心,所以需要優先渲染,DOM 結構也就放在了前面,主要是使用 order 屬性將 nav
放置到前方。
常見佈局
除了整體結構用到這些佈局以外,對於一些元件也常常需要一些簡單的佈局。
1. 導航欄
模仿示例:
實現效果圖:
<header class="header">
<div class="header__avatar"></div>
<div class="header__title">Title</div>
<div class="header__more"></div>
</header>
複製程式碼
.header
height 100px
width 100%
background-color #f9f1db // 蚌肉白
display flex
align-items center
> *
margin 0 10px
&__avatar, &__more
flex 0 0 80px
height 80px
border-radius 50%
&__avatar
background-color #FFAC40
&__title
color #FF9000
&__more
margin-left auto
background-color #A65E00
複製程式碼
原因解釋:
此處主要是利用了 margin-auto
來佔據剩餘的空間,就與我們使用 margin: 0 auto
來獲取水平居中一樣。
2. 輸入框
模仿示例:
實現效果圖:
<Layout-Layout
align-center
justify-center
:background-color="bgColor"
>
<div class="input-group">
<span class="title" @click="message = !message" v-if="message">Message</span>
<input type="text" class="input-text">
<span class="icon" @click="icon = !icon" v-if="icon"></span>
</div>
</Layout-Layout>
複製程式碼
.input-group
flex 0 0 75%
height 40px
border 2px solid red
border-radius 4px
display flex
align-items center
> *
box-sizing border-box
.input-text
font-size 20px
padding-left 10px
height 100%
flex 1
outline none
border none
.icon
flex 0 0 24px
height 24px
border-radius 50%
background-color #648e93 // 晚波藍
複製程式碼
原因解釋:
這也是一個常規的三欄佈局,關鍵是 .input-text
的 flex: 1
屬性可以佔據剩餘空間,當其餘配件不存在時也可以相應的擴張。
3. 卡片
實現效果圖:
<Layout-Layout
:background-color="bgColor"
class="flex-card"
>
<header class="header"></header>
<article class="article">
<div class="article__item">1</div>
<div class="article__item">2</div>
<div class="article__item">3</div>
<div class="article__item">4</div>
<div class="article__item">5</div>
<div class="article__item">6</div>
</article>
<footer class="footer"></footer>
</Layout-Layout>
複製程式碼
.flex-card
display flex
flex-flow column nowrap
.header
flex-basis 80px
background-color #4E51D8
.footer
flex-basis 50px
background-color #00B060
.article
flex auto
background-color #FF9000
display flex
flex-flow row wrap
align-content center
justify-content space-around
&__item
width 28%
height 50px
box-shadow 0 2px 4px rgba(255, 255, 255, .4), 3px 0 5px rgba(0, 0, 0, .6)
複製程式碼
原因解釋:
將主軸修改為垂直方向,header
和 footer
因為 article
的 flex:auto
屬性被分別頂至上方和下方,可以避免 absolute
的濫用。在中間使用 align-content
區別於 align-items
,可以將多行元素視為一個整體。
4. 瀑布流
實體效果:
在編譯時會賦予 CSS 顏色,所以直接重新整理頁面是不可行的,只有重新儲存程式碼進行編譯可以變更顏色。
<Layout-Layout
:background-color="bgColor"
class="flex-flow"
>
<div
class="flow-column"
v-for="m in 5"
:key="m"
>
<div
class="flow-item"
v-for="n in 8"
:key="n"
></div>
</div>
</Layout-Layout>
複製程式碼
$flow-columns = 5; // flow 的列數
$flow-items = 8; // flow 每列的個數
// 函式
randomColor(min, max) {
return floor(math(0, 'random') * (max - min + 1) + min);
}
randomPx(min, max) {
return floor(math(0, 'random') * (max - min + 1) + min) px;
}
.flex-flow {
display: flex;
justify-content: space-between;
overflow: hidden;
.flow-column {
display: flex;
flex-direction: column;
flex: 0 0 18.6%;
.flow-item {
width: 100%;
margin: .1rem 0;
}
}
}
for column in (1 .. $flow-columns) {
.flow-column:nth-child({column}) {
for item in (1 .. $flow-items) {
.flow-item:nth-child({item}) {
flex: 0 0 randomPx(30, 100);
background-color: rgb(
randomColor(0, 255),
randomColor(0, 255),
randomColor(0, 255)
);
}
}
}
}
複製程式碼
原因解釋:
flex 實現瀑布流還是比較簡單的。友情提示:當使用 stylus
時還是加上標點符號吧,找編譯錯誤花了我近二十分鐘。
最後
合併多個 commit
在 push 前需要合併 commit:
git log --oneline
git rebase -i xxxxxxx
git log --oneline
git status
git push
複製程式碼
初步地把 CSS 稍微過了一遍,下一步繼續完善那個簡陋的 簡歷 了…
參考資料
- VSCode 的友情提示
- Vuetify