立体的に開くアコーディオンは、見出しの位置を固定したまま、説明文を奥から手前へ浮き上がらせるように表示するアコーディオンです。見出しをクリックすると、隠れていた内容が斜めに傾いた小さな状態から、正面を向きながら拡大して現れます。
内容が開くときは、見出しの下に表示領域が広がり、説明文のカードが手前へ移動しながら徐々に表示されます。閉じるときは反対に、カードが小さく傾きながら奥へ引っ込み、説明文が消えて表示領域も閉じます。
見出し右側の丸い開閉アイコンも、クリックに合わせて斜め方向に1回転します。開くときは青い背景に白いマイナス記号へ変わり、閉じるときは淡い青色の背景にプラス記号へ戻ります。3つの項目は独立して開閉できるため、ほかの項目を開いても、すでに開いている内容はそのまま表示されます。
デモ
見出しを固定したまま、内容が奥から手前へ現れるように開閉します。
各見出しをクリックすると「+」が「-」へ切り替わり、内容だけが奥から手前へ立体的に表示されます。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>立体的なアコーディオン</title>
<!-- CSSファイル -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- アコーディオン全体 -->
<div class="depth-3d-accordion_wrap">
<!-- タイトル -->
<div class="depth-3d-accordion_title">
奥行きのある3Dアコーディオン
</div>
<!-- 説明文 -->
<p class="depth-3d-accordion_text">
見出しを固定したまま、内容が奥から手前へ現れるように開閉します。
</p>
<!-- アコーディオン一覧 -->
<div class="depth-3d-accordion_list">
<!-- 項目1 -->
<div class="depth-3d-accordion_item">
<button
class="depth-3d-accordion_button"
type="button"
aria-expanded="false">
<span>
アコーディオンとは?
</span>
<span
class="depth-3d-accordion_icon"
aria-hidden="true">
+
</span>
</button>
<div class="depth-3d-accordion_content">
<div class="depth-3d-accordion_content-inner">
<div class="depth-3d-accordion_content-card">
アコーディオンは、見出しをクリックして必要な内容だけを表示できるUIです。
</div>
</div>
</div>
</div>
<!-- 項目2 -->
<div class="depth-3d-accordion_item">
<button
class="depth-3d-accordion_button"
type="button"
aria-expanded="false">
<span>
どんな場面で使う?
</span>
<span
class="depth-3d-accordion_icon"
aria-hidden="true">
+
</span>
</button>
<div class="depth-3d-accordion_content">
<div class="depth-3d-accordion_content-inner">
<div class="depth-3d-accordion_content-card">
FAQ、商品説明、お問い合わせページ、管理画面の設定項目などで利用できます。
</div>
</div>
</div>
</div>
<!-- 項目3 -->
<div class="depth-3d-accordion_item">
<button
class="depth-3d-accordion_button"
type="button"
aria-expanded="false">
<span>
必要なファイルは?
</span>
<span
class="depth-3d-accordion_icon"
aria-hidden="true">
+
</span>
</button>
<div class="depth-3d-accordion_content">
<div class="depth-3d-accordion_content-inner">
<div class="depth-3d-accordion_content-card">
HTML・CSS・JavaScriptの3ファイルで作成できます。外部ライブラリは使用しません。
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JavaScriptファイル -->
<script src="script.js"></script>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
このサンプルでは、見出しを固定したまま、説明文のカードだけを奥から手前へ立体的に動かしています。HTMLで見出しと説明文のカードを配置し、CSSで奥行き・傾き・移動距離・影を設定します。JavaScriptはクリックした項目の開閉状態と、プラス・マイナス記号の切り替えを担当します。使用するファイルは次の3つで、外部ライブラリや画像ファイルは必要ありません。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlには、3つの見出しボタンと、それぞれに対応する説明文を配置しています。説明文はdepth-3d-accordion_content-cardで囲み、カード単位で立体的に動かせる構造にしています。style.cssでは、説明文の開閉、3D変形、フェード、影、丸い開閉アイコンの回転を設定しています。script.jsでは、クリックされた項目にis-openクラスを付け外しして、開閉状態を切り替えています。
設置方法・使い方
「サンプル一式をダウンロード」からZIPファイルを保存して展開し、index.html・style.css・script.jsを同じフォルダに配置してください。index.htmlをブラウザで開くと、そのまま動作を確認できます。見出しをクリックすると対応する説明文が立体的に表示され、もう一度クリックすると閉じます。各項目は独立しているため、複数の説明文を同時に開くこともできます。
説明文が奥から手前へ現れる仕組み
立体的な動きの中心となるのは、style.cssのdepth-3d-accordion_content-cardです。閉じた状態では、説明文のカードを奥へ120px、上へ34px移動させ、35度傾けて90%の大きさに縮小しています。
/* コンテンツカード */
.depth-3d-accordion_content-card{
position:relative;
margin-top:18px; /* 見出しとの間隔 */
padding:22px 24px; /* 内側余白 */
border:1px solid #bfdbfe; /* 枠線 */
border-radius:18px; /* 角丸 */
background:#ffffff; /* 背景色 */
color:#4b5563; /* 文字色 */
font-size:16px; /* 文字サイズ */
line-height:1.8; /* 行間 */
opacity:0; /* 初期状態は非表示 */
transform:
perspective(1200px)
translateZ(-120px) /* 奥へ120px配置。値を変更すると奥行きが変わる */
translateY(-34px) /* 上へ34px配置 */
rotateX(-35deg) /* X軸回転 */
scale(.9); /* 少し縮小 */
transform-origin:center top; /* 上中央を基準 */
box-shadow:
0 4px 0 #dbeafe,
0 16px 24px rgba(37,99,235,.10),
0 32px 50px rgba(15,23,42,.12);
transition:
transform .65s cubic-bezier(.22,1,.36,1),
opacity .45s ease,
box-shadow .55s ease;
/*
transformは0.65秒で立体表示する。
値を大きくすると動きがゆっくりになる。
*/
}
translateZ(-120px)はカードを画面の奥へ移動させる設定です。translateY(-34px)は上方向への移動、rotateX(-35deg)は横方向の軸を中心にカードを傾ける設定です。さらにscale(.9)で少し縮小し、opacity:0;で透明にしています。
transform-origin:center top;は、カードの上中央を変形の基準にする設定です。これにより、カードが上側を基準に傾きながら動きます。
開いたときにカードを手前へ移動させるCSS
見出しをクリックしてis-openクラスが付くと、説明文のカードには次の設定が適用されます。
/* カード(開いた状態) */
.depth-3d-accordion_item.is-open
.depth-3d-accordion_content-card{
opacity:1;
transform:
perspective(1200px)
translateZ(60px) /* 手前へ60px移動。値を大きくすると飛び出しが強くなる */
translateY(0)
rotateX(0deg)
scale(1);
box-shadow:
0 8px 0 #bfdbfe,
0 20px 36px rgba(37,99,235,.16),
0 42px 70px rgba(15,23,42,.18);
}
開いた状態では、translateZ(60px)によってカードを手前へ移動させ、rotateX(0deg)で傾きをなくします。同時にscale(1)で通常の大きさへ戻し、opacity:1;で完全に表示します。
閉じた状態の-120pxから開いた状態の60pxへ変化するため、奥行き方向の移動量は合計180pxです。この変化をtransitionで滑らかにつなぐことで、カードが奥から手前へ浮き上がるように見えます。閉じるときは、同じ設定を逆方向へ変化させます。
説明文の表示領域が広がる仕組み
カードの立体的な動きとは別に、見出しの下にある表示領域も開閉しています。次のCSSでは、閉じた状態を0fr、開いた状態を1frに切り替えています。
/* コンテンツ */
.depth-3d-accordion_content{
display:grid;
grid-template-rows:0fr; /* 閉じた状態 */
transition:grid-template-rows .6s cubic-bezier(.22,1,.36,1);
/*
0.6秒で開閉する。
値を大きくするとゆっくり開閉する。
*/
}
/* コンテンツ(開いた状態) */
.depth-3d-accordion_item.is-open
.depth-3d-accordion_content{
grid-template-rows:1fr; /* 開いた状態 */
}
grid-template-rowsは、説明文を配置する行の高さを制御しています。0frから1frへ変化させることで、見出しの下に説明文の表示領域が広がります。transitionには.6sを指定しているため、0.6秒かけて開閉します。
このサンプルでは、表示領域の開閉とカードの3D移動を組み合わせています。そのため、単に説明文が下へ広がるだけでなく、カード自体も傾きを戻しながら手前へ移動します。
丸い開閉アイコンが3D回転する仕組み
見出し右側の丸いアイコンには、説明文とは別の3D回転を設定しています。開いた状態では、次のCSSによって斜め方向に360度回転し、少し手前へ移動して拡大します。
/* +-ボタン(開いた状態) */
.depth-3d-accordion_item.is-open
.depth-3d-accordion_icon{
background:#2563eb; /* 背景色 */
color:#ffffff; /* 文字色 */
transform:
perspective(800px) /* 奥行き。値を小さくすると立体感が強くなる */
rotate3d(1,1,0,360deg) /* 360度回転 */
translateZ(16px) /* 手前へ16px移動。値を大きくすると飛び出しが強くなる */
scale(1.08); /* 少し拡大 */
box-shadow:
0 6px 0 #1d4ed8,
0 16px 26px rgba(37,99,235,.28);
}
rotate3d(1,1,0,360deg)は、X軸とY軸を組み合わせた斜めの軸を中心に360度回転させる設定です。translateZ(16px)で手前へ移動させ、scale(1.08)で108%の大きさにしています。
開くときは淡い青色のアイコンが濃い青色へ変わり、閉じるときは回転を戻しながら元の色と大きさに戻ります。アイコンの回転時間はdepth-3d-accordion_iconのtransitionにある.6sで設定しています。
クリックした項目だけを開閉するJavaScript
script.jsでは、クリックされた見出しに対応する項目を取得し、is-openクラスを切り替えています。
/* 開閉状態を切り替える */
const isOpen=item.classList.toggle(
"is-open"
);
/* aria-expandedを更新 */
button.setAttribute(
"aria-expanded",
String(isOpen)
);
/* +と-を切り替える */
icon.textContent=isOpen ? "-" : "+";
classList.toggle("is-open")は、閉じている項目にはis-openを追加し、開いている項目からは削除する処理です。CSSはこのクラスの有無を判定して、表示領域の高さ、カードの立体的な位置、アイコンの回転を切り替えます。
aria-expandedには開いているときにtrue、閉じているときにfalseを設定します。また、icon.textContentでプラスとマイナスの記号を切り替えています。ほかの項目のis-openは変更しないため、複数の項目を同時に開けます。
カスタマイズできる内容
見出しや説明文を変更する場合は、index.htmlのdepth-3d-accordion_buttonとdepth-3d-accordion_content-cardの文章を編集してください。項目を追加する場合は、既存のdepth-3d-accordion_itemを複製し、見出しと説明文を書き換えます。
デザインを変更する場合はstyle.cssを編集します。見出しボタンの背景色はdepth-3d-accordion_buttonのbackground:#ffffff;、説明文カードの背景色はdepth-3d-accordion_content-cardのbackground:#ffffff;で変更できます。丸いアイコンの色はdepth-3d-accordion_iconと、その開いた状態のCSSで設定しています。
立体感・移動距離・回転角度の数値調整
3D表現を変更する場合は、style.cssの次の数値を調整してください。
・translateZ(-120px)
閉じた状態のカードを奥へ配置する距離です。-200pxにするとさらに奥から現れる動きになり、-50pxにすると奥行き方向の移動が小さくなります。
・translateZ(60px)
開いた状態のカードを手前へ配置する距離です。100pxにするとさらに手前へ飛び出し、0にすると奥行き方向の最終位置が基準位置になります。
・translateY(-34px)
閉じた状態のカードを上へ移動させる距離です。-60pxにすると上から移動する距離が長くなり、-10pxにすると上下方向の動きが小さくなります。
・rotateX(-35deg)
閉じた状態のカードの傾きです。-60degにすると傾きが大きくなり、-15degにすると傾きが小さくなります。開いた状態のrotateX(0deg)は正面を向く設定です。
・scale(.9)
閉じた状態のカードの大きさです。.7にすると70%の大きさから拡大し、1にすると縮小せずに表示されます。
・perspective(1200px)
説明文カードの3D変形に使う遠近感です。600pxにすると遠近感が強くなり、2000pxにすると弱くなります。カード以外にもdepth-3d-accordion_listとdepth-3d-accordion_content-innerにperspective:1200px;が設定されています。
・rotate3d(1,1,0,360deg)
丸い開閉アイコンの回転角度です。360degは1回転、720degは2回転、180degは半回転を表します。ただし、回転の見え方は回転軸や裏面の非表示設定によって変わります。
・translateZ(16px)とscale(1.08)
開いた状態のアイコンの飛び出し距離と大きさです。translateZ(30px)にすると奥行き方向の移動が大きくなり、scale(1.2)にすると120%の大きさになります。
・transform .65s
説明文カードの立体的な移動時間です。1sにするとゆっくり動き、.3sにすると素早く動きます。表示領域の開閉時間はgrid-template-rows .6s、アイコンの回転時間はtransform .6sで別々に設定されています。
影による立体感の調整
説明文カードの奥行きは、移動や回転だけでなくbox-shadowでも表現しています。depth-3d-accordion_content-cardには複数の影が設定されており、開いた状態では影の広がりと濃さが変化します。
box-shadow:
0 8px 0 #bfdbfe,
0 20px 36px rgba(37,99,235,.16),
0 42px 70px rgba(15,23,42,.18);
例えば0 42px 70pxは、横方向のずれが0、下方向のずれが42px、ぼかしの大きさが70pxという意味です。下方向のずれやぼかしを大きくすると、カードが浮いているような印象が強くなります。
さらにdepth-3d-accordion_content-card::afterでは、カードの下にぼかした影を追加しています。filter:blur(14px);の値を大きくすると影が柔らかく広がり、小さくすると輪郭がはっきりします。
レスポンシブ対応
style.cssでは、アコーディオン全体にwidth:100%;とmax-width:720px;を設定しています。画面幅が640px以下になると、内側余白を上下24px・左右18pxに変更し、見出しボタンの高さや文字サイズ、丸いアイコンの大きさ、説明文カードの余白を小さくします。
スマートフォンでも開閉と3D変形は同じ設定で動作し、カードの移動距離や回転角度は画面幅によって変更されません。
コメント