其實這篇文章寫到一大半時它的名字還叫作 《重溫 Flex 佈局》,結果寫着寫着就走了心,附上一圖表示心情吧:css
其實我並非一個喜歡搞事的人,真的,從我遊戲:屠夫沉默(DOTA2),蓋倫(LOL),亞瑟(農藥)的英雄池徹底能夠看出來。html
這三個元素做爲這個 《CSS 搞事技巧》的第一篇並不是僅僅是在接下來的 《重溫 Flex 佈局》中要使用,而是由於這個技巧的確是很基礎。vue
核心概念:所謂技巧,無非就是保存狀態(劃重點啦)。git
示例部分僅放 Gif 圖樣及源碼地址,詳情請查看技巧說明部分(技巧是通用的)。github
樣式模仿的是 Vuetify 的 Switches 。ide
Gif 預覽:佈局
上面實現了開關,那麼一個簡單的聯想固然是開關燈啦。測試
Gif 預覽:flex
在 JavaScript 中,咱們能夠利用變量,DOM 來保存狀態,而 CSS 當中,咱們也能夠利用僞類選擇器來保存狀態,這就是 CSS 搞事的核心了,也是上面示例實現的本質。
回到主題,也就是 Flex 佈局來,咱們初步回顧一下,Flex 佈局的相關概念,首先被聲明瞭 Flex 彈性佈局的元素叫作彈性容器,其子元素被稱爲彈性項目。這個彈性容器中默認存在兩個軸,一個叫作主軸(main axis),側軸(cross axis)。整個 Flex 容器具備六個屬性,這次僅介紹兩個:justify-content
和 align-items
(提一下 align-content
是多行的概念)。
列出這個兩個屬性的經常使用值(看 MDN 可知已經增長了更多的值):
.flex {
justify-content: flex-start | flex-end | center | space-between | space-around;
align-items: flex-start | flex-end | center;
}
複製代碼
該項目是經過 VuePress 來渲染的,因此會使用到 Vue 的語法,不過此處僅使用 Vue 的 for
循環來解決重複書寫 DOM 的問題;該效果參考 來源 。
功能欄與展現欄分列兩側,首先是完成 DOM 結構:
flex__feats
爲左側功能欄,flex__exh
爲展現欄。
<div class="flex">
<section class="flex__feats">
<div class="feat__list">
<h4 class="feat__list_title">justify</h4>
<div class="feat__list_labels">
<label>flex-start</label>
<label>flex-end</label>
<label>center</label>
<label>space-between</label>
<label>space-around</label>
</div>
</div>
<div class="feat__list">
<h4 class="feat__list_title">align</h4>
<div class="feat__list_labels">
<label>flex-start</label>
<label>flex-end</label>
<label>center</label>
</div>
</div>
</section>
<div class="divider"></div>
<section class="flex__exh"></section>
</div>
複製代碼
接着使用 Flex 佈局來將它們分割,由於此次主要將的不是 Flex,因此就不進行闡述了。
<style lang="stylus" scoped>
.flex
width 100%
height 100%
display flex
*
box-sizing border-box
&__feats
flex-basis 28%
height 100%
display flex
justify-content space-around
.feat__list
display flex
flex-direction column
justify-content flex-start
align-items center
.feat__list_labels
flex-grow 1
display flex
flex-direction column
justify-content space-around
align-items center
.divider
width 1px
height 100%
margin 0 2px
background-color #000;
</style>
複製代碼
能夠注意到功能欄的 DOM 結構是重複的,使用 Vue 來簡化一下吧:
<section class="flex__feats">
<div class="feat__list" v-for="(feat, index) in feats()" :key="index">
<h4 class="feat__list_title">{{feat.title}}</h4>
<div class="feat__list_labels">
<label v-for="(item, index) in feat.list" :key="index">{{item}}</label>
</div>
</div>
</section>
<script>
export default {
data() {
return {
bgColor: "#c0c4c3", // 月影白
feats: () => {
return [
{title: "jusitify", list: ["flex-start", "flex-end", "center", "space-between", "space-around"]},
{title: "align", list: ["flex-start", "flex-end", "center"]}
]
}
};
}
};
</script>
複製代碼
接着須要一堆 checkbox 來觸發狀態,由於 DOM 解析是深度優先,CSS 中也沒有父選擇器這一說,雖然有必定的辦法 hack 一下,因此這一堆 checkbox 就須要放在頂部:
<div class="flex">
<input type="checkbox" class="toggle" v-for="(checkbox, index) in checkboxs()" :id="checkbox">
</div>
複製代碼
接着須要將其隱藏:
.toggle[type="checkbox"]
width 0
height 0
filter opacity(0)
opacity 0
display none
複製代碼
要想生效的話,還須要將 input 的 id 綁定到 label 上:
<label v-for="(item, index) in feat.list" :key="index" :for="`${feat.title}-${item}`">{{item}}</label>
複製代碼
接着利用 selector(選擇器),獲取到 label 並改變其顏色證實它是被選召的孩子,舉個例子(完整版):
#jusitify-flex-start:checked ~ .flex__feats .jusitify-flex-start
padding 4px 4px
background-color #5a191b // 慄紫
color #fffef9 // 雪白
複製代碼
測試綁定狀況:
首先在其中添加三個元素,幫助咱們觀察效果:
<section class="flex__exh">
<div class="exh__item" v-for="n in 3" :key="n"></div>
</section>
複製代碼
&__exh
flex-grow 1
padding 16px
.exh__item
width 15%
height 15%
box-shadow 0 0 4px rgba(0, 0, 0, .5)
&:nth-child(1)
width 18%
height 20%
&:nth-child(2)
width 14%
height 18%
&:nth-child(3)
width 15%
height 15%
複製代碼
接着繼續使用 selector 來完成最後的任務,示例(完整版):
#jusitify-flex-start:checked ~ .flex__exh
display flex
justify-content flex-start
複製代碼
這樣就大功告成啦,在線查看 。
CSS 的美麗是有多個屬性組合而成。切記要和設計師搞好關係,否則你這些屬性都會了,作出來的東西仍是會很難看的……
預告:《重溫 Flex 佈局》正在路上。
連接:《重溫 Flex 佈局》
相關連接: