前端特效
-如何用 CSS 做 Accordion 手風琴?不再需要用 JS 計算高度
accordion 是前端非常常見的組件,他長這個樣子 👇
點擊時候展開顯示內容,再次點擊就關閉。
因為 css height 屬性如果從 0 到 auto 是吃不到 transition 效果的,所以早期我們只能利用 JS 算出內容的高度,比如 500px,點擊時再用 js 調整 css hiehgt 為 500px,這樣才能吃到 transition 屬性的效果。
但現在可以利用 grid-template-row
來快速做到一樣的事情並且簡單很多,讓我們看看怎麼做吧!
基本 HTML & CSS
先設定基本的 HTML & CSS。
<div class="accordion">
<h4 class="accordion__title">TITLE 1
<div class="accordion__icons">
<span class="accordion__icon--plus">+</span>
<span class="accordion__icon--minus">−</span>
</div>
</h4>
<div class="accordion__content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero maiores obcaecati rerum repudiandae quo ratione
deleniti facere autem! Unde in quibusdam eligendi eaque vero accusamus soluta facilis enim dicta obcaecati.</p>
</div>
</div>
HTML 架構分為 title、icons、content 沒有很複雜就不說太多。
.accordion {
width: 300px;
padding: 16px;
border-bottom: 2px solid;
}
.accordion__title {
display: flex;
justify-content: space-between;
cursor: pointer;
font-size: 2rem;
}
.accordion__icons {
border: 3px solid;
border-color: transparent;
border-radius: 50%;
width: 2rem; height: 2rem;
display: grid; place-content: center;
transition: 0.4s;
}
.accordion__icon--plus, .accordion__icon--minus {
grid-area: 1/1/2/2;
transition: 0.4s ease-in-out;
font-size: 1.2rem;
}
.accordion__icon--minus {
opacity: 0;
transform: rotate(-2turn);
}
CSS 的部分,icons 的我利用 grid 以及 grid-area: 1/1/2/2
來將 icon 疊在一起。其他沒有太特別的地方。
CSS Accordion Style
接下來是重頭戲,要來製作 Accordion 的功能了
.accordion__content {
display: grid;
grid-template-rows: 0fr;
transition: .4s ease-in-out;
}
.accordion__content>* {
overflow: hidden;
}
我們在 content 設定 display: grid
和 grid-template-row: 0fr
,這個意思是 row 的高度為 0。
並且在 content 的子元素設定 overflow: hidden
,這樣他才可以被壓縮。
當這兩件事情加在一起後,你就會發現 content 消失了!他已經被縮起來了。
如果要打開,只要設定 content grid-template-row: 1fr
即可!並且他也能吃到 transition 的效果。
所以讓我們完善 CSS。
/* active */
.accordion.is-active .accordion__content {
grid-template-rows: 1fr;
}
.accordion.accordion.is-active .accordion__icons {
border-color: var(--white);
}
.accordion.is-active .accordion__icon--plus {
opacity: 0;
transform: rotate(2turn);
}
.accordion.is-active .accordion__icon--minus {
opacity: 1;
transform: rotate(0turn);
}
因為 active 時,除了 content 要展開,icon 也要變化,所以我直接在 .accordion 加 .is-active
的效果讓所有子元素都能吃到。
最後,只要加一點點的 JS 就完成全部的功能了~
JS Accordion 功能
const accordionsTriggers = document.querySelectorAll('.accordion__title');
accordionsTriggers.forEach((trigger) => {
trigger.addEventListener('click', (e) => {
const target = trigger.closest('.accordion');
target.classList.toggle('is-active');
})
})
整體內容非常簡單,就是找到所有的 accordion__title
並添加事件,點擊後在父元素 .accordion
添加 is-active
即可。
到這邊就完成了!附上 codepen 當作參考~
補充
前陣子我遇到 accordion 裡面還要有 tooltip 的需求,但 tooltip 會因為 content 的子元素添加了 overflow: hidden
的關係而被截掉。
如果你不希望展開時仍有 overflow: hidden 的話,可以利用 animation 來控制 overflow,算是非常實用的小技巧~
.accordion.is-active .accordion__content>* {
animation: overflowModify .5s ease-in-out forwards;
}
@keyframes overflowModify {
0%,
99.9% {
overflow: hidden;
}
100% {
overflow: visible;
}
}
這樣在 is-active 後,就不會 overflow: hidden
了~
小結
今天用 grid-template-row 來製作前端 accordion 手風琴效果,是非常常用的組件,使用率很高。
那這篇就這樣,希望能幫助到你學 CSS 的應用,下篇貼文見~!