<ul class="faq-05">
<li class="faq-05__item">
<p class="faq-05__question js-faq-05-question"><span class="faq-05__question-category">その他</span><span class="faq-05__question-text">質問が入ります。</span></p>
<div class="faq-05__answer">
<p class="faq-05__answer-inner">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
</div>
</li>
<li class="faq-05__item">
<p class="faq-05__question js-faq-05-question"><span class="faq-05__question-category">企業情報について</span><span class="faq-05__question-text">質問が入ります。</span></p>
<div class="faq-05__answer">
<p class="faq-05__answer-inner">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
</div>
</li>
<li class="faq-05__item">
<p class="faq-05__question js-faq-05-question"><span class="faq-05__question-category">株式情報について</span><span class="faq-05__question-text">質問が入ります。</span></p>
<div class="faq-05__answer">
<p class="faq-05__answer-inner">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</p>
</div>
</li>
</ul>
ul.faq-05
each faq in faqItems
li.faq-05__item
p.faq-05__question.js-faq-05-question
span.faq-05__question-category #{ faq.category }
span.faq-05__question-text #{ faq.question }
.faq-05__answer
p.faq-05__answer-inner #{ faq.answer }
{
"faqItems": [
{
"category": "その他",
"question": "質問が入ります。",
"answer": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
},
{
"category": "企業情報について",
"question": "質問が入ります。",
"answer": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
},
{
"category": "株式情報について",
"question": "質問が入ります。",
"answer": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
}
]
}
$BLOCK_NAME: '.faq-05';
// 変数
$color_answer_bg: #ebebeb;
$color_white: #fff;
$color_black: #2b2b2b;
$duration_default: 0.5s;
$easing_default: cubic-bezier(0.075, 0.82, 0.165, 1);
@mixin faq05Icon() {
font-family: 'Heebo', sans-serif;
font-size: 26px;
font-weight: 500;
line-height: 1;
letter-spacing: 0.05em;
}
#{ $BLOCK_NAME } {
&__item {
position: relative;
&::before,
&::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
display: block;
height: 1px;
content: '';
}
&::before {
background: $color_black;
opacity: 0.1;
}
&::after {
background: $color_black;
transition: transform $duration_default $easing_default;
transform: scaleX(0);
transform-origin: right;
}
&:hover::after {
transform: scaleX(1);
transform-origin: left;
}
}
&__question {
position: relative;
display: flex;
padding: 30px 50px 30px 55px;
cursor: pointer;
&::before {
position: absolute;
top: 32px;
left: 0;
content: 'Q.';
@include faq05Icon();
}
&::after {
position: absolute;
top: 38px;
right: 10px;
display: block;
width: 8px;
height: 8px;
content: '';
border-top: 1px solid $color_black;
border-right: 1px solid $color_black;
transition: transform $duration_default $easing_default;
transform: rotate(135deg);
}
&.is-active::after {
transform: rotate(-45deg);
}
}
&__question-category {
display: block;
flex-shrink: 0;
width: 160px;
padding-top: 8px;
font-size: 12px;
line-height: 1;
opacity: 0.6;
transition: opacity $duration_default $easing_default;
@at-root #{ $BLOCK_NAME }__item:hover & {
opacity: 1;
}
}
&__answer {
height: 0;
overflow: hidden;
}
&__answer-inner {
position: relative;
padding: 30px 30px 30px 85px;
background: $color_answer_bg;
border-top: 1px dotted $color_black;
&::before {
position: absolute;
top: 32px;
left: 32px;
content: 'A.';
@include faq05Icon();
}
}
}
import { gsap } from 'gsap';
export function faq05() {
const items = document.getElementsByClassName('js-faq-05-question');
[...items].forEach(item => {
const faq = new Faq05(<HTMLElement>item);
faq.init();
});
}
class Faq05 {
questionEl: HTMLElement;
answerEl: HTMLElement;
isOpen: Boolean;
speed: number;
constructor(questionEl: HTMLElement) {
this.questionEl = questionEl;
this.answerEl = <HTMLElement>this.questionEl.nextElementSibling;
this.isOpen = false;
this.speed = .5;
}
/**
* 初期化
*/
init() {
this.toggleHandler();
}
/**
* FAQを開閉する
*/
toggleAnswer() {
if (!this.isOpen) {
// 閉じている場合
const self = this;
this.questionEl.classList.add('is-active');
gsap.to(this.answerEl, {
duration: this.speed,
height: 'auto',
onComplete() {
self.isOpen = true;
}
});
} else {
// 開いている場合
const self = this;
this.questionEl.classList.remove('is-active');
gsap.to(this.answerEl, {
duration: this.speed,
height: 0,
onComplete() {
self.isOpen = false;
}
});
}
}
/**
* 開閉イベントの設定
*/
toggleHandler() {
this.questionEl.addEventListener('click', () => {
this.toggleAnswer.call(this);
});
}
}