← 動的パーツギャラリーへ戻る

パーツ番号 08-10-11 ・ JavaScript使用

矢印キーで移動するキーボード対応アコーディオン

↑↓キーで見出し間をフォーカス移動し、EnterまたはSpaceキーで開閉できます。WordPressのFAQセクションのキーボード操作性向上に使えます。

js

プレビュー

ソースコード

HTML

<div class="d08-10-11-accordion" role="presentation">
          <div class="d08-10-11-item">
            <button class="d08-10-11-head" type="button" aria-expanded="false" aria-controls="d08-10-11-panel-1" id="d08-10-11-head-1">送料はいくらですか?</button>
            <div class="d08-10-11-panel" id="d08-10-11-panel-1" role="region" aria-labelledby="d08-10-11-head-1">
              <p>全国一律550円、5,000円以上のご購入で送料無料です。</p>
            </div>
          </div>
          <div class="d08-10-11-item">
            <button class="d08-10-11-head" type="button" aria-expanded="false" aria-controls="d08-10-11-panel-2" id="d08-10-11-head-2">返品はできますか?</button>
            <div class="d08-10-11-panel" id="d08-10-11-panel-2" role="region" aria-labelledby="d08-10-11-head-2">
              <p>商品到着後7日以内であれば返品を承ります。</p>
            </div>
          </div>
          <div class="d08-10-11-item">
            <button class="d08-10-11-head" type="button" aria-expanded="false" aria-controls="d08-10-11-panel-3" id="d08-10-11-head-3">支払い方法は?</button>
            <div class="d08-10-11-panel" id="d08-10-11-panel-3" role="region" aria-labelledby="d08-10-11-head-3">
              <p>クレジットカード・銀行振込・代金引換に対応しています。</p>
            </div>
          </div>
        </div>

CSS

.d08-10-11-accordion{width:100%;max-width:280px;display:flex;flex-direction:column;gap:6px}
        .d08-10-11-item{border:1.5px solid #e6e7ee;border-radius:10px;overflow:hidden;background:#fff}
        .d08-10-11-head{width:100%;text-align:left;background:#f7f7fb;border:none;padding:10px 14px;font-size:12.5px;font-weight:700;color:#2a2d3a;cursor:pointer;outline:none;position:relative;padding-right:30px}
        .d08-10-11-head::after{content:'';position:absolute;right:14px;top:50%;width:8px;height:8px;border-right:2px solid #8a8fa3;border-bottom:2px solid #8a8fa3;transform:translateY(-65%) rotate(45deg);transition:transform .25s}
        .d08-10-11-head[aria-expanded="true"]::after{transform:translateY(-35%) rotate(-135deg)}
        .d08-10-11-head:focus-visible{box-shadow:inset 0 0 0 2px #6a5cff}
        .d08-10-11-panel{padding:0 14px;max-height:0;overflow:hidden;transition:max-height .25s ease}
        .d08-10-11-panel p{margin:0;padding:10px 0;font-size:11.5px;color:#666;line-height:1.6}
        .d08-10-11-item.is-open .d08-10-11-panel{max-height:90px}

JavaScript

(function(){
        var root=document.getElementById('item-08-10-11');if(!root)return;
        var heads=[].slice.call(root.querySelectorAll('.d08-10-11-head'));
        if(!heads.length)return;
        function toggle(head){
          var item=head.closest('.d08-10-11-item');
          var willOpen=!item.classList.contains('is-open');
          heads.forEach(function(h){
            var it=h.closest('.d08-10-11-item');
            it.classList.remove('is-open');
            h.setAttribute('aria-expanded','false');
          });
          if(willOpen){
            item.classList.add('is-open');
            head.setAttribute('aria-expanded','true');
          }
        }
        heads.forEach(function(head,i){
          head.addEventListener('click',function(){toggle(head);});
          head.addEventListener('keydown',function(e){
            if(e.key==='ArrowDown'){e.preventDefault();heads[(i+1)%heads.length].focus();}
            else if(e.key==='ArrowUp'){e.preventDefault();heads[(i-1+heads.length)%heads.length].focus();}
            else if(e.key==='Enter'||e.key===' '){e.preventDefault();toggle(head);}
          });
        });
      })();

クラス名 .d08-10-11 は本ライブラリ内での識別用です。複数のパーツを同じページで使う場合は、重複しないよう名前を変更してください。