2016/02/22

CSS 小技巧之四:用 label 設計勾選框

HTML 的表單資料,除了文字輸入之外,應用最廣泛的還有勾選框,HTML 如下:

<input type="checkbox"> 是否同意...


由於勾選框本身不大,因此很多開發者都期許一種更方便作法 - 當使用者點選說明文字時,同時觸發這個勾選框,因此誕生了 label 標籤:

<!-- label 標籤有一個屬性 for,需填入與之互動的 input id -->
<input id="test" type="checkbox"><label for="test">是否同意...</label>

當使用者點選了 label 標籤,相當於點選了 input,是不是很方便呢?
也因為 label 的這個特性,讓我們能使用純 html + css 來實現 ios 的開關。





首先我們使用一個 ::before 偽元素,當作勾選框的底:

#test {
  
}

#test + label { /* + 號代表 "下一個",意指 #test 的下一個節點 label */
    display: block;
    position: relative;
    font-size: 16px;
    line-height: 20px; /* 將 label 的高設為 20px */
    padding-left: 50px; /* 避開勾選框 */
}

#test + label::before { /* 勾選框的底 */
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 40px;
    height: 20px;
    background-color: #CC4541;
}



我把 label 設為 relative,讓 ::before 偽元素設為 absolute ,對齊 label 的左邊。接著,我們使用 ::after 偽元素來製作撥動按鈕的開關,對齊 label 的左上角:

#test + label::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 18px; /* 製作一個 20px * 20px 的開關 */
    height: 18px;
    border-width: 1px;
    border-style: solid;
    border-color: #CC4541;
    background-color: #fff;
}

此時,已經可以得到一個概略的雛型如下:



接著,我們需要依照 input 勾選的狀態,來改變這組開關的樣式。這時可以使用 :checked 選擇器,:checked 有點類似 :hover (當指標滑入) ,都是在表示元素的某種狀態。 :checked 表示的是 當物件被勾選的狀態

當 #test 被勾選時,我們去改變 #text 的下一個 label 的 ::before 與 ::after 偽元素:

#test:checked + label::before {
    background-color: #83cc41;
}

#test:checked + label::after {
    border-color: #83cc41;
    left: 20px; /* 開關往左移動 20px */
}



到此,我們已經得到了一個可以用的 ios 開關,到這個階段,別忘了把原本醜醜的 input 給隱藏起來:

#test {
  display: none;
}

如果你想要補間動畫,可以使用 CSS transition,也可以為它加上圓角、陰影等裝飾。以下是我使用的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #test {
            display: none;
        }

        #test + label {
            display: block;
            position: relative;
            font-size: 16px;
            line-height: 20px;
            padding-left: 50px;
            cursor: pointer;
        }

        #test + label::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 40px;
            height: 20px;
            background-color: #CC4541;
            border-radius: 10px;
            transition: 300ms;
        }

        #test:checked + label::before {
            background-color: #83cc41;
        }

        #test + label::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 18px;
            height: 18px;
            border-style: solid;
            border-width: 1px;
            border-color: #CC4541;
            background-color: #fff;
            border-radius: 10px;
            transition: 300ms;
        }

        #test:checked + label::after {
            border-color: #83cc41;
            left: 20px;
        }
    </style>
</head>
<body>
    <input id="test" type="checkbox"><label for="test">是否同意...</label>
</body>
</html>



 這個方法還可以用於多選選單 <input type="radio"> ,試試看吧!

沒有留言:

張貼留言