JavaScriptを使った折り畳み展開メニューは、JSが動作しなかった場合のことも考える

日付:
2012/8/20
カテゴリ:
SEO
ライター:
畑岡大作

近年、ユーザビリティ向上のための「プラスアルファ」としてJavaScriptを用いたUIが実装されることが多くなりました。
その中の一つに「アコーディオンメニュー」があります。

アコーディオンメニューの見本

グループの親メニューをクリックすると、非表示になっていたその親の子メニューがずらずらっと出てくるUIですね。いわゆる折り畳み型の展開メニューのことです。
ユーザーにとってもページの遷移を減らせるメリットがあって、ユーザビリティの良いUIと言ってもいいでしょう。

しかし、最近ではほとんどの環境でJavaScriptが動くこともあり、逆に「JavaScriptが動作しない場合」に対する備えができていないケースもよく見かけます。
また、そう言った場合はSEO的にも大なり小なりあまりよろしくないことが多いです。

JavaScriptを用いてプラスアルファを足すのであればそもそもJSが動作しなかった場合でも問題なく使えるべきですし、そういった面でも丁寧に作ることはSEOとしてもプラスに働くでしょう。
今回はそんな、SEOも含んではいますが、どちらかと言えばユーザビリティについてのコラムです。

  1. アコーディオンメニューの基本
  2. JS無効の環境を意識した作り方

アコーディオンメニューの基本

まずは改修前の前提として、基本的な作り方を紹介します。
JSで展開する折りたたみ型のメニューですが、作りは比較的簡単で、ざっくりと説明するとこんな感じになっています。

  1. 親子構造をもったHTMLを用意
  2. 子に当たるメニューは最初は非表示にする
  3. 親に当たるメニューをクリックした際、子に当たるメニューの表示/非表示をJSで切り替える

「親子構造をもったHTML」というのは、ul/liタグを入れ子にするのが一般的ですね。また、たまに「親がdtタグ」「子がddタグ」という風にdlタグを使用しているのも見かけます。
要は文書構造として「親と子の関係がわかる」ものです。

JS無効の環境を意識した作り方

さて、アコーディオンメニューはJavaScriptを使用したUIです。JavaScriptを使っていますので、当然ながら、JavaScriptが動かない環境ではアコーディオンメニューになりません。
JavaScriptを使用するのであれば、JSが動かない場合でも問題なく利用できるようにするか、または代替となるコンテンツ(や「JSをONにしてください」などのメッセージ)を提供するべきです。いわゆるnoscriptの理念ですね。

以下がJavaScriptが動作しない場合もあることを踏まえた、作る上でのポイントです。

  • 親メニューのaタグにもリンクURL(href属性)を記述しておく
  • 最初は子メニューも表示しておき、JSの動作時に非表示にする
  • 子メニューの件数が多い場合はHTMLには記載せず、JSで後からDOMへ追加する

それぞれについて、簡単に理由やメリットを解説します。

親メニューのaタグにもリンクURL(href属性)を記述しておく

前述の通り、最近ではJavaScriptが動く環境の方が圧倒的に多く、逆にJavaScriptが動作しない環境はとても少なくなりました。
そのためか「JavaScriptは動くのが当たり前」として「親メニューは折りたたまれた子のメニューを表示させるだけ」と割り切って、親メニューのaタグにはクリックイベントだけを仕込んでリンクURL(href属性)を記述していないケースをときどき見かけることがあります。

これではJavaScriptが動かない場合、何の意味も持たないaタグとなってしまいます。リンクURL(href属性)にはきちんと代替ページのURLを設定しておきましょう。
そうすることでJSが動かない環境であっても、リンクとしてきちんと機能するようになります。(リンクURLが指定されていてもJSが有効であれば、クリックイベントの最後に「return false;」を入れておくことでページ遷移しなくなります)

代替ページと言うのは、例えば「大カテゴリ(親)と小カテゴリ(子)」をアコーディオンメニュー化するのであれば、親メニューの代替ページは大カテゴリのページになりますね。
なお、代替ページが存在しない場合はどうしようもありませんので、リンクURLの部分には「javascript:void(0);」と記述しましょう。古式ゆかしい「このリンクはJS動作用のものですよ」というサインです。

アコーディオンメニューの見本

ところで皆さまは、タブブラウザでブラウジングしている時にマウスの中クリック(マウスのホイール部分でクリック)を使っていますでしょうか?
一般的なタブブラウザではリンクを中クリックすると別タブで開いてくれて、便利なんですよね。ですがこれがリンクURLが指定されていないと空のブランクタブが開かれてしまうので、特に中クリックを多用するユーザーには結構なストレスになってしまいます。

また、リンクURLをきちんと記述しておくと、検索エンジンのクローラーへの導線確保にもなります。

  • JSが動作しない環境でもユーザーに代替ページへのリンクを提供できる
  • マウスの中クリックにも対応できる
  • 代替ページへの導線を検索エンジンのクローラーに提供できる

親メニューにリンクURLを指定しておくことは、こんなにもメリットがあるのです。

最初は子メニューも表示しておき、JSの動作時に非表示にする

最初からCSSで子のメニューを非表示にしてしまっていると、JavaScriptが動作しない環境では折りたたまれたまま展開できないので、ずっと非表示のままのユーザーがクリックできないリンクになってしまいます。
そこで最初はきちんと表示させておくことで、JavaScriptが動作しなかった場合でもユーザーに使用可能なリンクにしておこう、というのが趣旨です。

やり方としては簡単で、要は「CSSじゃなくてJSで非表示にする」ということです。

  1. CSSでは普通に表示させておく(display:none;にしない)
  2. アコーディオン化させるJSを実行時に、非表示にする

初期状態を表示にしておくことで、JavaScriptが実行できない環境でも利用可能になるのがユーザビリティ上のメリットになります。
またSEO面でも「ユーザーに見えないリンクがなくなる」というメリットがあります。JS有効時にはユーザーにも見えるようになるとはいえ、それでも隠れているリンクよりは見えているリンクの方が、検索エンジンにも覚えはいいでしょう。

  • JSのON/OFFどちらの環境でもリンクが利用可能になる
  • 「ユーザーが見えないかもしれない」リンクがなくなる

上記のようなメリットがありますが、JavaScriptが実行されるまでは表示されたままとなる、というデメリットもあります。
それの対処については次にまとめました。

子メニューの件数が多い場合はHTMLには記載せず、JSで後からDOMへ追加する

こちらは前述の「子メニューは最初は表示させておこう」と絡む話になりますが、JSで子メニューを非表示にするということは、JSが実行されるまでは子メニューは表示された状態です。
子メニューが大量にあった場合、全表示されるとどうなるでしょう? ブロックの縦幅がかなりの高さになってしまいますよね。そうなると、下手をするとメニューの下にある他のブロックが画面外に出て見えなくなってしまったりといった「使い勝手の悪い」状況になってしまいます。

使い勝手を良くしたいのに、結果的に悪くなってしまっては本末転倒です。
ですので件数が多い場合は、子メニューはJavaScriptで出力することも考慮に入れてみましょう。

具体的には、HTMLには子メニューを書かずに(もしくは主要な子メニューのみHTMLに記載しておく)、JavaScriptのdocument.writeinnerHTMLなどで、動的にDOMへ追加させる手法です。
この方法であればJSがオフの場合でも画面が圧迫されず、またJSがオンであれば使い勝手も変わらなくなります。

また、SEO的にもリンク数を削減できるため、特にページ内のリンク数が多いページで効果的になります。
大量の非表示リンクが減らせるのもうれしいところです。

  • 子メニューが全件表示されても過剰にブロックの縦幅が広がらない
  • ページ内のリンク数を減らせる
  • 非表示リンクテキストを減らせる

以上、今回はJavaScriptを用いたUIとして、よく見かけるアコーディオンメニューについて書かせていただきましたがいかがだったでしょうか。
アコーディオンメニューに限らないことですが、JSをプラスアルファとして使うのであれば、JSが動かない環境でも最低限の利便性は確保しておきたいものです。