使用CSS實現頁面複選框的方法

來源:互聯網
上載者:User

   產品篇

  在我們的後台中,需要設定廣告精準投放的地區,也就是要在全國31個省、自治區、直轄市中選擇。那麼,出現下面這幅景象也就理所應當了:

  這樣做有幾個問題:

  選項很多,沒有規律,找起來很累

  如果是一個已經選擇了部分選項的廣告,修改時仍然需要用肉眼尋找,無法一眼看出來投放到哪些省份

  選完一個,再選下一個,還要從頭找,甚至會被已經選過的影響

  於是我想,首先應該把所有選項分為“已選中”和“未選中”兩批,解決第2個問題,減輕第3個問題;其次複選框本身的價值不大,可以被替換為其它樣式;唯一可能引入的問題,就是點選時,使用者的預期是看到複選框裡出現一個小對勾,表示選中,如果我把它移開放到“已選中”組裡,使用者可能會迷惑,需要一些時間學習。

  於是我跟某產品經理朋友聊了聊這個想法,他表示確實可能造成使用者迷惑,不過如果能加入動畫效果,那麼基本沒問題。嗯,開始動手。

  技術實現篇

  近日flexbox規範定案,各瀏覽器相繼支援display:flex;,同時傳來一條好訊息,新實現比老實現display:box;快很多。這次我打算用flexbox來解決問題,因為裡面有一個很重要的屬性:order(之前叫box-ordinal-group),它可以改變布局中元素的排列順序,配合CSS3新增的選取器,應該可以滿足需要。

  第一步 分拆選中/未選中

  (關於flexbox的知識,可以通過Google瞭解,雖然搜到的多是上一個版本,不過和最終版差別不大,只是叫法不同。本文不再過多講解,我就當大家都會了)

  本身的樣式不能修改,所以我們必須藉助的協助;實現選中/未選中區分,那自然就要用到偽類:checked;選取器一定是從外到內、從前到後的,沒法選擇父級元素,所以不能用去包,那麼最終布局就只能是:

  CSS Code複製內容到剪貼簿

  

 

  

  小寶3225

  

  王老白白白

  

  空夫31

  

  穀大白話

  

  Meathill

  

  一毛不拔大師

  

 

  很簡單哈,不解釋了。CSS3新增了“下一節點”選取器 +,用來選擇某節點的下一個節點,結合:checked偽類就可以將選中的和它臨近的通過改變order屬性移到前面去:

  CSS Code複製內容到剪貼簿

  #container {

  display:flex;

  flex-direction:row;

  flex-wrap:wrap;

  }

  #container input,

  #container label {

  order: 2; //所有選項、label順序為2

  }

  input[type=checkbox]:checked,

  input[type=checkbox]:checked + label {

  order: 0; // 越小越靠前

  }

  不過這樣只是把選中的內容提前,視覺上沒有真正的分割。所以我決定再加入一根分割線,上面是選中的,下面是未選的。這個時候我們需要用到 ~ 這個選取器,選擇某節點後面的節點:

  CSS Code複製內容到剪貼簿

  hr {

  display:none; // 預設情況下,沒選任何選項,分割線隱藏

  order: 1; // 分割線順序為1

  width:100%; // 保證獨霸一行

  }

  input[type=checkbox]:checked ~ hr {

  display:block; // 有選項被選中後才會顯示分割線

  }

  http://jsfiddle.net/meathill/fPN3p/5/embedded/result/

  這樣基礎功能實現了。不過視覺上,排版仍然不整齊,選中的選項和未選中的選項區分不算太明顯,所以下一步我準備美化下checkbox。

  第二步,美化CHECKBOX

  做法與前面類似,也要用到CSS3新增的選取器。前面為了實現提前,沒有用它包裹,所以在選項很多很長導致換行的時候,可能出現複選框和標籤脫離的尷尬狀況。好在複選框的價值可以用別的樣式取代,所以先把小方框隱藏起來,轉而將作為操作目標,再來點邊框底色圓角(參考自Bootstrap 3),就可以了:

  CSS Code複製內容到剪貼簿

  input[type=checkbox] {

  display: none;

  }

  label {

  min-width: 120px;

  border: 1px solid #CCC;

  padding: 2px 8px;

  text-align: center;

  margin: 0 5px 5px 0;

  background: #FFF;

  color: #333;

  border-radius: 3px;

  box-sizing: border-box;

  }

  label:hover {

  border-color: #ADADAD;

  background: #EBEBEB;

  cursor: pointer;

  }

  input[type=checkbox]:checked + label {

  order: 0;

  background-color: #5cb85c;

  border-color: #4cae4c;

  color: #FFF;

  }

  input[type=checkbox]:checked + label:hover {

  background-color: #47a447;

  border-color: #398439;

  }

  這樣看起來還有上升空間,如果加上幾個表徵圖響應使用者操作,那麼學習成本會更低,對操作後的預期也會更準確。於是引用CDN上的font-awesome,使用:before偽類加上小表徵圖,就得到了最終效果

  。

  http://jsfiddle.net/meathill/fPN3p/4/embedded/result/

  我無意中發現,這樣大量新增刪除時,滑鼠可以常點不動,應該也是個意外的收穫吧。

  第三步,加入動畫教育使用者(失敗)

  至此功能基本做好了,不過由於修改了行為,可能導致使用者迷惑,所以準備加個動畫協助使用者理解這個互動。

  可惜作為一個新功能,瀏覽器的支援尚不完善,雖然規範中規定“animatable: yes”,但是實測在Chrome v.30下也無法工作:

  http://jsfiddle.net/meathill/Ka66W/1/

  看來只有等新版瀏覽器發布後再去完善了。

  相容性

  使用純CSS做組件,幾乎不用擔心相容性問題,因為瀏覽器本身就做了很好的向下相容,代碼最多不生效,一般不會錯。

  具體到這個組件,因為只針對視覺效果,沒有增刪改任何瀏覽器行為,所以相容性也沒有任何問題。不過最終效果呢,只有支援flexbox和CSS3選擇符的瀏覽器才能正常渲染。

  我的環境是Window 8 + Chrome v.30,以及小米2 + Chrome v.30,測試通過。

  後記

  如今CSS很強,純CSS可以實現很多功能,希望今後能做出更多有價值的東西。分享這個組件的實現,希望對大家有用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.