らぼるてっく。

てっくてっく歩いてっく。

アコーディオンUIのデザインからコーディングまで

はじめに

こんにちは🧑‍💻

ラボルのUIデザイナー/フロントエンドエンジニアの寺岡です。

みなさんはアコーディオンUIのデザイン・コーディングはどのようにしてますでしょうか? よくある質問とかに使われる、こういったUIですね。

情報を階層的に定義する」・「コンテンツの高さをコンパクトにする」といった目的でアコーディオンUIは用いられますが、 デザイン・コーディングに関して初学者の方は、以下の問題点が生じると思います。

  • デザイン問題点: アコーディオンのUIをどのようなデザインにすべきかわからない
  • コーディング問題点: 開閉の処理をどのように実装するのかわからない

本記事では、これらをデザイン・コーディングそれぞれの文脈で解決していきます!

目次

デザイン

UIの構成

まずはUIの構成要素を整理しましょう。 アコーディオンUIの最低限の構成要素としては以下です。

  • summary(タイトル部分)
    • テキストラベル
    • Caretアイコン(矢印のアイコン)
  • コンテンツ
    • 表示/非表示させたい要素

「コンテンツ」の部分は「summary」をクリックしたら表示/非表示が切り替わるイメージですね。

Caretアイコン

Caretアイコンとは、アコーディオンUIでよく目にするのようなアイコンです。 ではなぜCaretなのでしょう?

それは、Accordion Icons: Which Signifiers Work Best? で行われている調査の結果にもあるように、アコーディオンに関してはユーザーにとってCaretアイコンが最も望ましいアイコンだからです。

少しだけこちらの調査の内容を紹介します。

調査では、同じUIでアコーディオンにcaret含む以下のアイコンを設置して検証しています。

136人の被験者に異なるアイコンでプロトタイプを見せ、結果として以下のような差が生まれました。

新しいページに遷移することへのユーザーの期待値が以下のグラフです。 この調査では、期待値が50%を超えるとユーザーは新しいページへ遷移することを期待しているとしています。 ページが変わらないことを伝えたいアコーディオンの場合、50%未満であることが望ましいです。

この中で、Caretのみが「今のページにとどまるはずだ」という期待が、統計学的に有意であると結論づけられました。

この調査から言えるのは、アコーディオンに限らず「アイコンが示す役割とUIの機能を切り離さないようにする」というデザインアドバイスです。

他のアイコンの意味を一般的に考えてみると、Plusアイコン+は「追加・増やす」というアクションを期待し、Arrowアイコン>は「右へ移動・遷移」というアクションを期待しますよね。

話をアコーディオンに戻すと、今回使うべきアイコンはPlusアイコンでもArrowアイコンでもなく、Caretアイコンであるべきことがわかりました。

完成イメージ

上記のロジックから、以下のようなUIの完成イメージになりました。 今回は、コンテンツの部分はリストにしました。

ここからはコーディング作業に移ります!

コーディング

details/summaryタグ

<details><summary>は、共にHTML5で追加されたタグです。

コンテンツを階層的に定義し、ユーザーが追加で得られる詳細情報を含む要素として使われます。

<details>の子要素として<summary>を含み、<summary>の情報が「要約」としての役割になります。

今回は以下のメリットのケースに該当するので、details/summaryタグを使ってコーディングしていきましょう!

details/summaryタグのメリット

アコーディオン実装はJavaScriptを使って実装することがほとんどだと思いますが、開閉するだけのアコーディオンであれば、このdetails/summaryタグだけで実装可能です。

  • 開閉フラグの切り替え
  • コンテンツ表示/非表示のスタイル

これらの処理を行うコードがまるっと削れるので、実装の手間が減らせますね。

details/summaryタグのデメリット

「コンテンツを表示/非表示する開閉機能」だけならdetails/summaryタグで事足りてるのですが、それ以上のことはできません。

例えば「アコーディオンのリストのうち開いているのは一つだけとする」という仕様で実装したいときは、details/summaryタグではなくJavaScriptの出番です。

開閉機能以外の機能が必要になりそうであれば、大人しくJavaScriptでの実装を検討しましょう。

準備

下記のCodePenをみてください。準備はこれだけです。

これでデフォルトでは詳細は非表示になっており、summary要素をclickすると詳細が表示されます。

必須事項としては、details > summary + 何かの構造になっていればOKです。

<details>タグの中に<summary>タグを含み、<summary>の兄弟要素に非表示にしたい要素を記述するだけです!

open属性

<details>タグにはopen属性というものが付与できます。

open属性がある場合に詳細が表示され、ない場合は詳細が非表示になります。

なので、実はopen属性を<details>タグにつけていれば、デフォルトで詳細が表示されているんですね。

open時の装飾に関して、CSSのセレクターをdetails[open]にすればスタイルを当てることができます。

/* 閉じてる時は赤文字色で */
details summary {
    color: red;
}

/* 開いてる時は青文字になる */
details[open] summary {
    color: blue;
}

markerの消し方

▶︎のmarker消したいですよね?消しましょう。

リストの装飾と同じで、list-style: none;を適用したら消せます。

ただし注意点として、スマホなどの特定ブラウザではこれだけでは消せないんですよね。

なので、以下のCSSも記述する必要があります。

/* markerを非表示 */
summary {
  list-style: none;
}

/* 特定ブラウザでmarkerを非表示 */
summary::-webkit-details-marker {
  display: none;
}

これでOK👌

スタイルしてみる

あとは以下のようにイイ感じにCSSを書いて、装飾してみましょう!

開閉時のアニメーションとして、矢印アイコンがくるっと回るアニメーションは以下で、

rotate: 0deg→180deg

コンテンツがふわっと出現するアニメーションは、以下のように設定しています。

opacity: 0→1
translateY: -20px→0px

これでアコーディオンUIのデザイン〜コーディングの完了です!お疲れ様でした👏

まとめ

今回は以下2つの観点でアコーディオンUIの作成方法を記事にしました。

  • アコーディオンのUIをデザインする上でのロジック
  • details/summaryタグを使ってHTML/CSSだけでコーディング

シンプルなアコーディオンであれば、この手順でデザイン〜コーディングできますね! 是非参考にしてみてください。

参考

最後に

ラボルでは、エンジニアを積極採用中です。1、2年目のエンジニアから経験豊富なテックリードやエンジニリングマネージャーまで、興味がある方はぜひご応募ください!!

labol.co.jp