CSS 點擊展開或收折的選單
這篇教學會使用 HTML 的 checkbox 和 label 作為按鈕,實作可以展開或收折的選單,並進一步搭配 button 元素和美化樣式,做出可以一鍵收起和漂亮的特色選單。
快速導覽:
點擊後展開選單
要單純使用 CSS 實現點擊後展開選單的功能,可以藉由類型為 checkbox
的 input
元素,搭配選擇器中的「虛擬類別選擇器」和「相鄰兄弟選擇器」,就能實現勾選 checkbox
時展開選單的功能,進一步搭配 label
的 for
屬性,也能做到點擊 label
就展開選單的效果。
<!-- HTML 程式碼 -->
<div class="menu">
<label for="b1">點我開啟/收折選單</label>
<input type="checkbox" id="b1">
<div class="submenu">
<div>Apple</div>
<div>Banana</div>
<div>OXXO</div>
<div>Orange</div>
</div>
</div>
<!-- CSS 程式碼 -->
<style>
.menu {
box-sizing: border-box;
width: 300px;
padding: 10px;
margin: 20px;
font-size: 30px;
border: 1px solid #000;
}
label {cursor: pointer;}
.submenu {display: none;} /* 隱藏子選單 */
/* 勾選 checkbox 時,相鄰的下一個兄弟元素 .submenu 就顯示 */
input:checked + .submenu {
display: block;
}
</style>
了解原理之後,就能隱藏 checkbox
,單純透過點擊 label
展開或收折選單,搭配 transition
實現簡單的轉場效果,但需要注意如果「沒有設定子選單的高度」,會造成轉場失效的狀況,這時可以透過設定 max-height
,讓子選單仍然在展開時可保持內容高度,但又具有轉場效果 ( 不過 transition
的持續時間需要設定「兩組不同時間」,才能讓展開和收折的轉場速度接近 )。
<!-- HTML 程式碼 -->
<div class="menu">
<label for="b1">點我開啟/收折選單</label>
<input type="checkbox" id="b1" class="btn">
<div class="submenu">
<div>Apple</div>
<div>Banana</div>
<div>OXXO</div>
<div>Orange</div>
</div>
<label for="b2">點我開啟/收折選單</label>
<input type="checkbox" id="b2" class="btn">
<div class="submenu">
<div>Apple</div>
<div>Banana</div>
<div>OXXO</div>
<div>Orange</div>
</div>
</div>
<!-- CSS 程式碼 -->
<style>
.menu {
box-sizing: border-box;
width: 300px;
margin: 20px;
padding: 10px;
font-size: 30px;
border: 1px solid #000;
}
input {display: none;} /* 隱藏 checkbox */
label {cursor: pointer;} /* 滑鼠移動到上方時為手形指標 */
.submenu {
overflow: hidden; /* 超過範圍就隱藏 */
width: 100%; /* 寬度為父元素寬度 100% */
max-height: 0; /* 設定最大高度為 0,讓 transition 能有作用 */
transition: .5s; /* 轉場時間 0.5 秒 */
padding-left: 10px;
margin-bottom: 10px;
}
/* 勾選 checkbox 時,相鄰的下一個兄弟元素 .submenu 就顯示 */
input:checked + .submenu {
max-height: 500px; /* 設定最大高度為 500px,讓 transition 能有作用 */
transition: 1s; /* 因為最大高度可能比內容高度高得多,所以秒數設定較多 */
}
</style>
點擊後收折全部選單
上述的範例在 checkbox
「取消勾選」時會收折選單,如果要透過單一顆按鈕收折全部的選單,則可以透過類型為 reset
的 button
,點擊之後就會重設 form
元素中所有的表單元素,但需要注意,使用這種方法需要將 button
和 checkbox
放在同一個 form
裡,下方範例會展示收折全部選單的效果 ( 一鍵開啟選單的效果則需要透過 JavaScript 才能順利實現 )。
<!-- HTML 程式碼 -->
<form class="menu">
<button type="reset">收折全部選單</button>
<label for="b1">點我開啟/收折選單</label>
<input type="checkbox" id="b1">
<div class="submenu">
<div>Apple</div>
<div>Banana</div>
<div>OXXO</div>
<div>Orange</div>
</div>
<label for="b2">點我開啟/收折選單</label>
<input type="checkbox" id="b2">
<div class="submenu">
<div>Apple</div>
<div>Banana</div>
<div>OXXO</div>
<div>Orange</div>
</div>
</form>
<!-- CSS 程式碼 -->
<style>
.menu {
box-sizing: border-box;
width: 300px;
margin: 20px;
padding: 10px;
font-size: 30px;
border: 1px solid #000;
}
input {display: none;} /* 隱藏 checkbox */
label {cursor: pointer;} /* 滑鼠移動到上方時為手形指標 */
.submenu {
overflow: hidden; /* 超過範圍就隱藏 */
width: 100%; /* 寬度為父元素寬度 100% */
max-height: 0; /* 設定最大高度為 0,讓 transition 能有作用 */
transition: .5s; /* 轉場時間 0.5 秒 */
padding-left: 10px;
margin-bottom: 10px;
}
input:checked + .submenu {
max-height: 500px; /* 設定最大高度為 500px,讓 transition 能有作用 */
transition: 1s; /* 因為最大高度可能比內容高度高得多,所以秒數設定較多 */
}
button {
font-size: 20px;
display: block;
margin: 5px 5px 10px 5px;
}
</style>
點擊後彈出選單
運用勾選和取消 checkbox
的做法,搭配修飾過後的選單,就能做出點擊後彈出和收起的漂亮選單,下方範例將選單都設計成圓形,並使用一些簡單的圖案符號,就能讓選單別具特色。
<!-- HTML 程式碼 -->
<div class="menu">
<label for="b1">㊕</label>
<input type="checkbox" id="b1">
<div class="submenu">♠</div>
<div class="submenu">♦</div>
<div class="submenu">♣</div>
<div class="submenu">♥</div>
</div>
<!-- CSS 程式碼 -->
<style>
.menu {
position: relative;
box-sizing: border-box;
width: 300px;
margin: 20px;
font-size: 30px;
}
input {display: none;} /* 隱藏 checkbox */
label {
position: absolute; /* label 絕對定位 */
top: 0;
left: 0;
display: block; /* 改成 block 區塊容器 */
cursor: pointer; /* 手形指標 */
width: 50px;
height: 50px;
line-height: 50px; /* 讓內容圖案垂直置中 */
text-align: center; /* 讓內容圖案水平置中 */
border-radius: 50%; /* 圓角 */
background: #09f;
color: #fff;
}
.submenu {
position: absolute; /* 所有子選單絕對定位,位置和 labe 相同 */
top: 0;
left: 0;
z-index: -1; /* 子選單放在 label 之下 */
cursor: pointer; /* 手形指標 */
width: 50px;
height: 50px;
line-height: 50px; /* 讓內容圖案垂直置中 */
text-align: center; /* 讓內容圖案水平置中 */
border-radius: 50%; /* 圓角 */
color: #fff;
opacity: 0; /* 透明度為 0 */
}
.submenu:nth-of-type(1) {
background: #f55; /* 第一個子選單的顏色和轉場時間 */
transition: .3s;
}
.submenu:nth-of-type(2) {
background: #f90; /* 第二個子選單的顏色和轉場時間,延遲 0.1s */
transition: .3s .1s;
}
.submenu:nth-of-type(3) {
background: #0c0; /* 第三個子選單的顏色和轉場時間,延遲 0.2s */
transition: .3s .2s;
}
.submenu:nth-of-type(4) {
background: #f7f; /* 第四個子選單的顏色和轉場時間,延遲 0.3s */
transition: .3s .3s;
}
input:checked ~ .submenu {
opacity: 1; /* 顯示子選單時,透明度為 1 */
}
input:checked ~ .submenu:nth-of-type(1) {
left: 120px; /* 第一個子選單出現的位置 */
}
input:checked ~ .submenu:nth-of-type(2) {
top: 50px; /* 第二個子選單出現的位置 */
left: 90px;
}
input:checked ~ .submenu:nth-of-type(3) {
top: 90px; /* 第三個子選單出現的位置 */
left: 50px;
}
input:checked ~ .submenu:nth-of-type(4) {
top: 120px; /* 第四個子選單出現的位置 */
left: 0;
}
</style>
小結
CSS 的故障文字效果其實並不困難,基本上只要新增出紅色和藍色兩種重複文字,搭配錯位和動畫,就都可以做出滿逼真的故障文字效果。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~