アコーディオンメニューで解答欄の上下の余白が取得できない

下記の記事を参考にアコーディオンメニューを作成しております。
素のJavaScriptでアコーディオンメニューを作る
ここでの仕様としては、.c-questionボタンをクリックすると親要素の .p-faq(アコーディオンの一つ)にactiveクラスが付与されて同時に .c-anser(回答となる部分)が開くという設定です。.c-anser は閉じている状態ではheight: 0; 上下のpadding: 0;で、これが開くとjavascriptで高さを取得して、またcssでpaddingの高さも40pxほど上下に追加されます。
しかし下の画像にあるように、回答部分の上下にはpaddingが付与されていませんでした。

イメージ説明

これについてはscssの階層の順番が間違っているのではないか、名称が間違っているのではないかとも考えその辺を見て回り、記述する場所も変えてみましたが、そういう訳でもなさそうでした。
下記が今現在の記述になります。

index.html

<div class="p-faq"> <article class="p-faq__single"> <div class="c-question"> <p>初期費用無料とはどういう意味ですか?</p> <div class="c-lamp"></div> </div> <div class="c-anser"> <p>初期費用無料とは、サービスに登録する際に発生する初期費用が無料であることを意味します。登録に際して費用がかからないため、コストを抑えてサービスを利用できます。</p> </div> </article> <article class="p-faq__single"> <div class="c-question"> <p>3ヵ月間の月額利用料無料とは何ですか?</p> <div class="c-lamp"></div> </div> <div class="c-anser"> <p>3ヶ月間の月額利用料無料とは、サービスを契約した後の最初の3ヶ月間は月額利用料が無料であることを意味します。初めの3ヶ月間は費用を心配せずにサービスを利用できます。</p> </div> </article> <article class="p-faq__single"> <div class="c-question"> <p>特典の適用条件はありますか?</p> <div class="c-lamp"></div> </div> <div class="c-anser"> <p>特典の適用条件はサービスによって異なる場合があります。詳細はご利用のプランや特典の詳細ページに記載されていますので、そちらをご確認ください。</p> </div> </article> </div>

mystyle.scss

<!-- アコーディオンが閉じている状態 --> .p-faq{ &__single{ margin: auto; &:not(:last-of-type){ margin-bottom: 4rem; } .c-question{ position: relative; justify-content: space-between; display: flex; padding: 24px 40px; align-items: center; gap: 24px; border-radius: 20px; background: base.$lightBlue; box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); &::before{ @include mixin.background_url('pc/question.svg', 32px, 21.4px); position: absolute; top: 3.83rem; left: 4rem; } p{ width: 706px; line-height: 28.8px; padding-left: 5.6rem; } .c-lamp{ position: relative; width: 50px; height: 50px; border-radius: 25px; background: #fff; // 疑似要素で中に小さな円形を作成 &::before{ content: ''; position: absolute; top: 50%; left: 50%; width: 30px; height: 30px; border-radius: 15px; background: base.$lightBlue; transform: translate(-50%, -50%); } } } .c-anser{ position: relative; height: 0; width: 100%; overflow: hidden; margin-top: -2.4rem; word-break: break-word; align-items: center; border-radius: 0px 0px 20px 20px; border: 2px solid base.$lightBlue; padding: 0px 60px 0px 40px; &::before{ @include mixin.background_url('pc/anser.svg', 32px, 20.4px); position: absolute; top: 4.8rem; left: 4rem; } p{ width: 100.4%; line-height: 28.8px; padding-left: 5.6rem; } } } } <!-- アコーディオンが開いたとき --> .p-faq{ &__single{ .active .c-question .c-lamp::before{ background: base.$pink; } .active .c-anser{ height: auto; padding: 48px 60px 40px 40px; } } }

script.js

// アコーディオンが開く瞬間 const shingleDown = (el) => { el.style.height = 'auto'; let h = el.offsetHeight; el.style.offsetHeight = h + 'px'; el.animate([ // animate(keyframes, options) { height: '0px'}, { height: h + 'px'} ], { duration: 300, }); el.style.height = 'auto'; } // アコーディオンが閉じるとき const shingleUp = (el) => { el.style.height = 0; } const acoShiBtns = document.querySelectorAll('.c-question'); acoShiBtns.forEach((acoShiBtn, index) => { acoShiBtn.addEventListener('click', (e) => { const clickedIndex = Array.from(acoShiBtns).indexOf(e.currentTarget); e.currentTarget.parentNode.classList.toggle('active'); const content = acoShiBtn.nextElementSibling; if(e.currentTarget.parentNode.classList.contains('active')) { shingleDown(content); }else { shingleUp(content); } console.log(content.clientHeight + 'px'); acoShiBtns.forEach((acoShibtn, index) => { if(clickedIndex !== index) { acoShibtn.parentNode.classList.remove('active'); const openedContent = acoShibtn.nextElementSibling; shingleUp(openedContent); } }); }); });

この記述の中身をchatGPTに確認してもらったところ、shingleDown関数のところで以下のような修正案が提示されました。
script.js

const shingleDown = (el) => { el.style.height = 'auto'; // 初期値が0にならないように一旦autoにする el.style.transition = 'height 0s'; // アニメーションの適用を一時的に無効化 let h = el.scrollHeight; // 要素の高さを取得(コンテンツ全体の高さ) let paddingTop = parseFloat(window.getComputedStyle(el).paddingTop); let paddingBottom = parseFloat(window.getComputedStyle(el).paddingBottom); h += paddingTop + paddingBottom; // paddingを高さに加算する el.style.height = '0px'; // 高さを一時的に0にする el.style.transition = ''; // アニメーションの適用を有効化 el.offsetHeight; // 要素の高さを再取得するためにリフローを発生させる el.style.height = h + 'px'; // 高さを設定 }; const shingleUp = (el) => { el.style.height = 0; };

つまり「window.getComputedStyle(el)を使用することで、要素の計算されたスタイル(paddingや他のプロパティ)にアクセスできます。」ということでしたが、しかしこれも高さの変化はありませんでした。
これ以上認識を広げることができなかったため、今は停滞しております。
どのようにすれば .c-anser の上下の高さを取得できますでしょうか。

何卒よろしくお願いします。

コメントを投稿

0 コメント