メニューの階層化

メニューバーの項目が増えてきた。現在のメニュー項目を羅列してみると以下のような感じ。

CSVリスト 設定 パスワード変更 権限管理 ユーザー管理 アクセス権管理 フィルターSQL フィルターSET   ログアウト

ずいぶん項目が増えたものだ。上記のうち、権限の無いメニュー項目は表示されないので、システム管理者以外の一般的なユーザーは「パスワード変更」の右側には「ログアウト」が表示されているだけ。スッキリした印象だ。ユーザーからの苦情は無い。
しかし、システム管理者は自分自身でもあるので、もっと見やすいメニューにしておきたい。それに、これ以上メニュー項目が増えると、メニューバーに入りきらなくなってしまう...。(この後、管理用のdefaultsテーブルのメニューも追加しておきたいのだ。)ということで、メニューバーを階層化します。

調べてみると、制限のない多階層化を目指すとかなり複雑になり、今の自分には理解できそうもない。なるべくシンプルに実現したいので、以下のような方針でやってみることに。

  • 現在のメニューバーはスタイルシートによって実現しているので、このままスタイルシートの設定を工夫して階層化を実現したい。
  • 階層化することによってメニュー項目の追加や削除が面倒になるのは避けたい。
  • メニューバーの項目をクリックすると、その下に1階層だけプルダウンリストが表示されれば、それで満足。それ以上の多階層化は今は不要。(階層が深くなると、操作性も悪くなりそうだ。)

以前からお世話になっているサイト、Listamatic2: Pure CSS hover listCSSを参考に、以下のようにやってみた。

スタイルシート

public/stylesheets/list_o_matic.css
スタイルシート
  • スタイルシートは設定する順番が重要であったり、指定項目の階層の深さが関係したりと、いまいち理解しきれていない。
  • うまく説明できないので、コメントを可能な限り詳細に書いてみた。
  • ついでに、設定項目の単位を一部emに変更して、ブラウザの文字表示を拡大、縮小した時もメニューのデザインが大きく崩れないようにしてみた。
/*
 *  ul#navlist
 *  情報バーの基本デザイン
 */
#info_bar
{
  font-size: 85%;
  line-height: 1.5em;
  _background-color: whitesmoke;
}

#info_bar span
{
  margin-right: 10px;
  margin-left: 10px;
  _background-color: whitesmoke;
}

/*
 *  ul#navlist
 *  メニューバーの基本デザイン
 */

/*  メニューバーul領域のデザイン */
body { 
  min-width: 1000px;
}
ul#navlist
{
  font-family: verdana, arial, helvetica, sans-serif;
  margin: 0;
  padding: 0 0 1.8em 10px;
  border-top: 1px solid #000;
  border-bottom: 1px solid #000;
  background-color: white;
}
ul#navlist li
{
  float: left; 
  list-style-type: none; /* リスト先頭のマークを非表示 */
  margin: 0;
  padding: 0;
}

/*
 *  ul#navlist li a:
 *  マウスをメニューバー上で移動させた時の、リンクの変化をデザイン
 */

/*  メニューリンク未訪問、訪問済 */
ul#navlist li a:link, 
ul#navlist li a:visited
{
  font-weight: bold;
  padding: 1px 10px 0.08em 10px;
  text-decoration: none;
  color: #666;
}
/*  メニューリンク未訪問、訪問済(現在のページと同じURLの場合) */
ul#navlist li a:link#current, 
ul#navlist li a:visited#current
{
  font-weight: bold;
  border-bottom: 0.45em solid #000;
  padding: 1px 10px 0.08em 10px;
  background: transparent;
  color: #000;
}
/*  マウスが上に乗った時のメニューリンク */
ul#navlist li a:hover
{ 
  font-weight: bold;
  border-bottom: 0.45em solid #ddd;
  padding: 1px 10px 0.08em 10px;
  background: #ddd;
  color: #000;
}
/*  マウスが上に乗った時のメニューリンク(現在のページと同じURLの場合) */
ul#navlist li a:hover#current
{ 
  border-bottom: 0.45em solid #000;
  padding: 1px 10px 0.08em 10px;
  background: #ddd;
  color: #000;
}
/*  メニューバーの「ログアウト」の間隔を広げる。 */
ul#navlist li#logout a:link, 
ul#navlist li#logout a:visited
{
  margin-left: 4em;
}

/*
 *  ul subnavlist
 *  サブメニューの基本デザイン
 */
ul#subnavlist
{
  display: none; /* サブメニューの基本は非表示 */
  border-width: 1px;
  border-style: solid;
  border-color: #ddd #999 #999 #999;
  background-color: white;
}
ul#subnavlist li
{
  float: none;
}

/*
 *  ul subnavlist li:hover ul#subnavlist
 *  マウスが上に乗った時の、サブメニューのデザイン
 */
 
/*  サブメニューul領域のデザイン。 縦型リスト、メインメニューとの位置関係等。*/
ul#navlist li:hover ul#subnavlist
{
  display: block; /* サブメニューを縦型リスト表示 */
  position: absolute;
  font-size: 95%;
  font-weight: normal;
  margin: 2px 0px 0px 0px;
  padding: 5px 0 5px 0;
}
/*  サブメニューリンクのデザイン。リンク文字列の配置や書式等。 */
ul#navlist li:hover ul#subnavlist li a
{
  display: block;
  width: 10em;
  font-weight: normal;
  text-indent: 2em;
  margin: 0;
  padding: 2px 15px 2px 5px;
  border: none;
}
/*  マウスを上に乗せた時、サブメニューリンクを強調表示する。 */
ul#navlist li:hover ul#subnavlist li a:hover
{
  text-indent: 2em;
  background-color: #ddd;
}
/*  現在のページと同じURLのサブメニューリンクは強調表示する。 */
ul#navlist li:hover ul#subnavlist li a#current
{
  font-weight: bold;
  text-indent: 0em;
}
/*  サブメニューの文字列の先頭にマークを付ける。 */
ul#navlist li:hover ul#subnavlist li a:before
{
  content: " ";
}
/*ul#navlist li:hover ul#subnavlist li:hover a:before,*/
ul#navlist li:hover ul#subnavlist li#current a:before{
  content: ">> ";
}
参考ページ

以下のページが大変参考になりました。感謝です!

ビュー

上記のスタイルシートに対して、ビューは以下のように記述した。

app/views/layouts/_menu2.rhtml
ビュー(メニューの表示)
  • プルダウンするリストは、メニューバーの<li>タグの中に、さらに<ul id="subnavlist">タグで囲ったリストを追加すれば表示される。
  • 見た目もシンプルで、メニューの追加、削除のメンテナンスも簡単だ。
...(途中省略)...
<div id="navcontainer">
  <ul id="navlist">
  <%= link_if_authorized_current 'CSVリスト', {:controller => 'csvs', :action => 'list'}, :wrap_in => "li" %>
  <%= link_if_authorized_current '設定', {:controller => 'defaults', :action => 'edit_preference'}, :wrap_in => "li" %>
  <%= link_if_authorized_current 'パスワード変更', {:controller => 'user', :action => 'change_password'}, :wrap_in => "li" %>
  <li id="active"><%= '<a href="#">管理</a>' if admin? %>
    <ul id="subnavlist">
    <%= link_if_authorized_current '権限', {:controller => 'role', :action => 'list'}, :wrap_in => "li" %>
    <%= link_if_authorized_current 'ユーザー', {:controller => 'user', :action => 'list'}, :wrap_in => "li" %>
    <%= link_if_authorized_current 'アクセス権', {:controller => 'permission', :action => 'list'}, :wrap_in => "li" %>
    <%= link_if_authorized_current 'フィルターSQL', {:controller => 'filtersqls', :action => 'list'}, :wrap_in => "li" %>
    <%= link_if_authorized_current 'フィルターSET', {:controller => 'filtersets', :action => 'list'}, :wrap_in => "li" %>
    <%= link_if_authorized_current 'デフォルト', {:controller => 'defaults', :action => 'list'}, :wrap_in => "li" %>
    </ul>
  </li>
  <%= link_if_authorized_current 'ログアウト', {:controller => 'user', :action => 'logout'}, :wrap_in => "li", :id => 'logout' %>
  </ul>
</div>
      • コードが横に長くなってしまったので、ブラウザのウィンドウ幅を、MacBookの画面いっぱいの1280pxに広げないと自動改行して見づらい。はてなのこのデザインでは、自動改行させない設定が、どうもうまく出来ないのだ...。


以上で、メニューバーから、このようなプルダウンが表示されるようになった。