CSS 搞事技巧:checkbox+label+selector

介紹

其實這篇文章寫到一大半時它的名字還叫作 《重溫 Flex 佈局》,結果寫着寫着就走了心,附上一圖表示心情吧:css

其實我並非一個喜歡搞事的人,真的,從我遊戲:屠夫沉默(DOTA2),蓋倫(LOL),亞瑟(農藥)的英雄池徹底能夠看出來。

這三個元素做爲這個 《CSS 搞事技巧》的第一篇並不是僅僅是在接下來的 《重溫 Flex 佈局》中要使用,而是由於這個技巧的確是很基礎。html

核心概念:所謂技巧,無非就是保存狀態(劃重點啦)。vue

示例

示例部分僅放 Gif 圖樣及源碼地址,詳情請查看技巧說明部分(技巧是通用的)。git

1. switch 開關

樣式模仿的是 Vuetify 的 Switchesgithub

Gif 預覽:ide

動畫源碼在線動畫佈局

2. 關燈效果

上面實現了開關,那麼一個簡單的聯想固然是開關燈啦。測試

Gif 預覽:flex

動畫源碼在線動畫動畫

技巧說明

在 JavaScript 中,咱們能夠利用變量,DOM 來保存狀態,而 CSS 當中,咱們也能夠利用僞類選擇器來保存狀態,這就是 CSS 搞事的核心了,也是上面示例實現的本質。

回到主題,也就是 Flex 佈局來,咱們初步回顧一下,Flex 佈局的相關概念,首先被聲明瞭 Flex 彈性佈局的元素叫作彈性容器,其子元素被稱爲彈性項目。這個彈性容器中默認存在兩個軸,一個叫作主軸(main axis),側軸(cross axis)。整個 Flex 容器具備六個屬性,這次僅介紹兩個:justify-contentalign-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 的問題;該效果參考 來源

1. label

功能欄與展現欄分列兩側,首先是完成 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>

2. checkbox

接着須要一堆 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

3. selector

要想生效的話,還須要將 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 // 雪白

測試綁定狀況:

4. 右側展現

首先在其中添加三個元素,幫助咱們觀察效果:

<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 佈局》正在路上。

參考資料

  1. Vuetify
  2. 配色方案:中國色
  3. MDN
相關文章
相關標籤/搜索