長いコンテンツを省略して表示し、ボタンを押すとすべて表示させるアノUI。
スマホでは省略表示、それ以外は全表示という実装が多いのですが、これが毎回地味に大変…
というわけで、汎用的に利用できるコンポーネントを作成しました。
仕様
- 表示・非表示
-
<input type="checkbox">
のチェックの有無で管理
-
- 省略時のコンテンツの高さ
- CSS変数(Custom Properties)で管理
- スライドアニメーション
- CSS の
transition
でmax-height
をアニメーション -
max-height
の値は JavaScript で要素の高さを取得し、CSS変数に設定
- CSS の
HTML
親要素の div
に設定している class="js-showMore"
は JavaScript のトリガーです。
アニメーションさせない場合は不要です。
HTML
<div class="showMore js-showMore">
<input class="showMore_trigger" id="showMore" type="checkbox">
<label class="showMore_btn" for="showMore"></label>
<div class="showMore_contentWrapper">
<div class="showMore_content">
<!-- ここにコンテンツを挿入 -->
</div>
</div>
</div>
Sass
アニメーションさせない場合は、73行目の --mask-height: auto;
のコメントアウトを解除してください。
SCSS
.showMore {
--mask-height: 500px;
--mask-color: 40 42 54;
--transition-easing: cubic-bezier(0.075, 0.82, 0.165, 1);
--transition-duration: 0.5s;
display: flex;
flex-direction: column;
}
.showMore_btn {
position: relative;
display: block;
order: 2;
width: 50px;
height: 50px;
margin: 20px auto 0;
font-size: 2rem;
color: #fff;
cursor: pointer;
background-color: #000;
border-radius: 50%;
&::before,
&::after {
position: absolute;
top: 50%;
left: 50%;
content: "";
background-color: #fff;
transform: translate(-50%, -50%);
}
&::before {
width: 20px;
height: 2px;
}
&::after {
width: 2px;
height: 20px;
}
}
.showMore_contentWrapper {
position: relative;
order: 1;
max-height: var(--mask-height);
overflow: hidden;
transition: max-height var(--transition-duration) var(--transition-easing);
&::before {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
content: "";
background: linear-gradient(
0deg,
rgb(var(--mask-color) / 1) 0%,
rgb(var(--mask-color) / 0) 100%
);
}
}
.showMore_trigger {
// チェックボックスは常に非表示
display: none;
&:checked {
// ボタンをマイナス表示
+ .showMore_btn {
&::after {
display: none;
}
}
// コンテンツをすべて表示
~ .showMore_contentWrapper {
// アニメーションさせない場合はコメント解除
// --mask-height: auto;
// マスク要素を非表示
&::before {
display: none;
}
}
}
}
JavaScript
アニメーションさせない場合は JavaScript は不要です。
JS
class ShowMoreShowLessButton {
#defaults = {
selector: '.js-showMore',
customPropertyName: '--mask-height'
}
#options
#showMoreList
constructor(config) {
this.#options = { ...this.#defaults, ...config }
this.#showMoreList = document.querySelectorAll(this.#options.selector)
this.#init()
}
#init() {
for (const el of this.#showMoreList) {
const trigger = el.querySelector('input[type="checkbox"]')
const contentWrapper = el.querySelector('div')
const content = contentWrapper.querySelector('div')
const contentHeight = content.getBoundingClientRect().height
trigger.addEventListener('change', () => {
if (trigger.checked) {
contentWrapper.style.setProperty(
this.#options.customPropertyName,
contentHeight + 'px'
)
} else {
contentWrapper.removeAttribute('style')
}
})
}
}
}
const showMoreShowLessButton = new ShowMoreShowLessButton()
DEMO
See the Pen Show More / Less Content Button by Takuya Mori (@taqumo) on CodePen.