スクロールしないUI
無限スクロールは、本来「巨大なリスト」であったものをWeb上にそのまま再現したもの、あるいは分割されてしまったページを連結することで、使い勝手を向上させるアプローチでした。次に、ページが分割されたままで使い勝手を向上させるための工夫を考えていきましょう。
無限スクロールは「下までスクロールして、次のページに移動」という2種類の組み合わせを、スクロールという1種類の動作だけで可能になるように変換したものと言えます。今度は逆に、スクロールを排除して、次ページへの移動だけで快適にコンテンツを閲覧できるようにしてみたいと思います。無限スクロールに対して、今回のもう一つのテーマであるページング[6] を考えることが非常に重要です[7] 。
今回は高速ページ切り替えを主体としたAmazon検索のサンプルコードをJavaScriptで作りました。スクロールしないUIを作るときには参考にしてみてください[8] 。
リスト1 にサンプルの抜粋を掲載しますが、スクロールしないUIのコンセプトは次のとおりです。
表示する件数を画面にフィットさせてスクロール不要にする
画面サイズに合わせて表示件数や倍率を動的に変更する
前後のページはあらかじめデータをキャッシュしておき、切り替えを高速に行えるようにする
リスト1 キーボードで操作できるようにする工夫
var current_query; //現在のクエリページ
var current_page = 1;
var current = -1;
//検索ボックスにフォーカスを残したしたまま、矢印キーで読み進められるようにする
function keydown(e){
var kc = e.keyCode;
if (kc == 40) { //下方向キー
//下アイテムへカーソルが移動 or 次ページへ進む
if (current == 9 && get_cache(current_query, current_page+1)) {
current_page++;
current = 0;
refresh();
} else {
current = Math.min(9, current+1);
}
} else if (kc == 38) { //上方向キー
//上アイテムへカーソルが移動 or 前ページへ進む
if (current == 0 && current_page != 1) {
current_page--;
current = 9;
refresh();
} else {
current = Math.max(0, current-1);
}
}
if (kc == 40 || kc == 38) {
var el = jQuery(".item").removeClass("active")
.eq(current)
.addClass("active")
.get(0);
show_info(el);
}
if (current_query != this.value && e.keyCode == 13) {
current = -1;
current_page = 1;
search(this.value, current_page);
current_query = this.value;
}
}
var CACHE = { };
function get_cache(keyword, page) { return CACHE["_" + keyword + "_" + page] }
function set_cache(keyword, page, items) { return CACHE["_" + keyword + "_" + page] = items }
function prefetch(keyword, page) {
var param = "keyword=" + encodeURIComponent(keyword) +
"&page=" + page;
if ( get_cache(keyword, page) ) return;
jsonp(api + "?" + param , function(items){
set_cache(keyword, page, items) });
}
function refresh() {
search(current_query, current_page, function() {
jQuery(".item").removeClass("active")
.eq(current)
.addClass("active");
});
}
function search(keyword, page, cb) {
var show_result = function(items){
var start = (current_page - 1) * 10 + 1;
$("result").innerHTML =
"<h3>検索結果 " + start + "-" + (start + 9) + "</h3>"
+ items.map(function(item){
return tmpl.replace(/\$(\w+)/g, function($0,$1){
return item[$1] || ""
})
}).join("");
if (cb) cb();
};
if (get_cache(keyword, page)) { //キャッシュされていれば使う
show_result(get_cache(keyword, page));
prefetch(keyword, page + 1); //次ページを先読みする
} else {
var param = "keyword=" + encodeURIComponent(keyword) +
"&page=" + page;
jsonp(api + "?" + param , function(items){
set_cache(keyword, page, items);
show_result(items);
//まだ結果があれば次ページをあらかじめキャッシュする
if (items.length) { prefetch(keyword, page + 1) }
});
}
}
さらに、サンプルコード中には検索ボックスにフォーカスしたまま、方向キーで商品を選択、さらに次ページへ飛べる工夫を施しました。一般的な検索エンジンでは検索ボックスをフォーカスしたまま、方向キーでページを選択できません。検索ボックスからフォーカスが外れてしまうと、キーボードをマウスに持ち替えて画面をスクロールしなければならず、検索とページ閲覧の間に操作モードの切り替えが発生してしまいます。リスト1のような工夫により、検索ボックスにフォーカスを合わせたままキーボード操作で閲覧できるようにすることで、このモード切り替えのコストをなくしています。
ページングの最適化
スクロールだけで済むもの(無限スクロール) 、前後のページにものすごく速く切り替えられるもの(スクロールしないUI)と、どちらも単純な操作で次々に読み進められるという点では同じです。
しかしページングに注目すれば、必ずしもどちらが正しいという性質のものではありません。表示するデータの性質や、使用しているデバイスによって、最適なUIは変わっていきます。
使用環境による最適化
画面サイズにコンテンツをフィットさせるUIがうまく機能した場合、たとえばおおよそ同じサイズの画像を連続で表示するような場合は、スクロールよりも高速に動作するスライドショー形式で表示したほうが快適にコンテンツを閲覧できます。
スクロールが快適に行えるかどうか、というのも要因です。特殊なケースですが、低速回線でのリモートデスクトップ環境であればスクロールが快適に行えませんし、Amazon Kindleのような電子ペーパーの場合は、描画速度やレスポンスといったデバイスの性質上、スクロールをなるべく行わないという選択を取ることになります。
入力デバイスに特化した最適化
タッチパネルデバイスの登場によってスクロールバーのあり方が変化したように、最適なUIというのは外的な要因によって日々変化していくことが考えられます。
入力デバイスごとにUIが変化しているのも事実です。表1 にデバイスごとのメリット・デメリットを挙げました。
表1 デバイスに合わせた最適化を考える
デバイス メリット デメリット
キーボード(ノートPC、デスクトップPC)
ボタンがたくさんついている
同じキーを繰り返し押すことが容易 画面上の要素を直接選択するのは苦手
ホイールつきマウス(ノートPC、デスクトップPC)
どの位置にカーソルがあってもホイールでスクロール可能
細かい要素の選択が可能 ポインタが1つしかない
トラックパッド(ノートPCなど)
ジェスチャ操作でスクロール・拡大・縮小などが行える タッチパネルほど直感的ではない
タッチパネルデバイス
カーソルがない
機種によってはマルチタッチが可能
画面の要素に直接タップすることで要素を選択できる 細かい要素の選択は苦手
デバイスの差でUIが変化する要因としては次のようなことが挙げられます。
ユーザの習熟度
画面の解像度
入力デバイス
通信速度や使う場所
ここではスマートフォンの影響で最近普及しているタッチパネルを取り上げます。
タッチパネル
タッチパネルは最も直感的に要素を選択できる一方で、マウスカーソルに相当するものが存在しないため、マウス操作を前提とした既存のUIと相容れない場合があります。
たとえばメニュー項目に対して「カーソルを重ねて変化が起きる」といったhoverやonmouseoverで実現していたUIは、タッチパネルデバイスでは実現できなくなりました。
マウスを前提とする場合は、何を行うアイコンなのか多少わかりにくくても、マウスオーバーさせるとツールチップでヘルプが表示される、といったUIを作ることができました。しかし、タッチパネルを前提としたUIでは、マウスオーバーでヘルプを表示するといったことが、そもそも表現できません。
そのため、最初からラベルを表示したり、アイコンが何を示すのかわかりやすくする必要があります。
先にも触れたように、どのデバイスでもそこそこ使いやすいような80点のUIを目指すのであれば、デバイスの特性に左右されにくいようなUI設計にする必要があります。
デバイスの弱点を克服する取り組み
ここではデバイスに特化したUI、あるいは入力デバイスごとの弱点を克服するための発明として、いくつか興味深い事例を挙げていきます。
キーボードブラウジングの革命
デバイスに特化したUIとして、キーボードによるナビゲーションを考えていきます。Firefoxのアドオンですが、Hit-a-hint とVimperator という2つのアドオンは、まさにキーボードブラウジングの革命と言ってよいでしょう。
今までのキーボードブラウジングは、カーソル(キャレット)を目的位置まで複数回のキー操作で移動し、リンクの上まで持っていって[Enter]という操作が必要でした。マウスを使う場合にも、目的のリンクまで移動させてクリックするという、2ステップの操作が必要になります。現在のカーソル位置とリンクが物理的に離れていれば、その分だけ移動に時間がかかってしまいます。
この2つのアドオンは本来ならばキー操作が割り当てられていないリンクに対して、ブラウザ側でキーを割り当てて上書きしてしまうわけです(図5 ) 。このアドオンを使うことで、2~3回のキー操作でリンクを選択することができるようになりました。利用可能なキーの数が多いことを前提に、脳への負担が高い分、キー入力が速い人であれば、最短でメニューを選択することができるのです。
図5 Vimperatorでhttp://gihyo.jp/を見たところ。すべてのリンクにキー操作が割り当てられている
キー操作によるリンクの選択が今までなかったかというと、そういうわけではありません。CUI(Character User Interface )ブラウザの代表格であるlynx にはリンクに対して数字を割り当てて、数字入力によってリンク先へ遷移するという機能がありました。慣れれば、マウスやタッチパネルよりも速くリンクを選択することができます。
バブルカーソル
バブルカーソルとは、マウスカーソルを拡張し、マウスを適当にクリックしたときに、一番近くにある選択可能な要素を「クリックしたことにする」しくみのことです(図6・注9 ) 。「 バブルカーソル」を参考にした派生の研究をいくつか見つけることができます[10] 。
図6 バブルカーソルは近くの要素をすばやくクリックすることができる
バブルカーソルのようなしくみがあれば、選択する要素が確定した段階で、正確にポインティングしなくても要素をクリックすることができます。
マウスの移動距離が減るのですばやく操作することができるようになり、また、マウスの操作に不慣れで正確な操作ができない場合でも快適に使うことができるようになります。
マウスジェスチャ
マウスジェスチャとは、ボタンを押しながら特定のパターンでカーソルを移動させることで、割り当てられた操作が実行されるというものです。ジェスチャ操作によって、どの位置にカーソルがあっても機能を発動できるわけです。
Operaが搭載したことで広く知られるようになりました。たとえば、右クリックしながらカーソルを左方向へと動かしてボタンを離すと戻り、右クリックしながらカーソルを右方向へと動かしてボタンを離すと進みます。
Operaはブラウザ本体の機能でサポートしていますが、ほかのブラウザでも拡張機能でマウスジェスチャ機能を実装しているものがあります。
ゲームや少ボタン端末向けのUI
次に、ゲームでよく使われるリングコマンドという名前で知られているUIを紹介します[11] 。
正確な起源を把握しているわけではありませんが、リング上にメニューを表示するUIは、「 聖剣伝説2」で使われたことで有名になったという記憶があります。
リングコマンドの特徴は、回転するメニューアイコンと、状況依存ヘルプ、望んだ状態になるまで同じ操作を繰り返して決定ボタンを押す、というシンプルな操作方法です。状況依存ヘルプはその機能の「プレビュー表示」と読み替えてもよいでしょう。通常のGUIにおけるメニュー操作では、
目的となるメニューを探す
移動するカーソルを見る
カーソルを合わせて決定ボタンを押す
という流れが必要です。
カーソルが今どこにあるのかを常に意識しないといけませんし、「 目的となるメニュー」と「カーソル」の間で視線移動が発生することが避けられません。
リングコマンドでのメニューの選択は
リングコマンドが出現する固定位置を見る
目的となるメニューが表示されるまで繰り返す
決定ボタンを押す
となり、自分が行いたいメニューがどこにあるのか覚える必要がありません。
リングコマンドはボタンの数が少ない状況下でも機能するのが特徴のUIです。望んだ状態になるまで単純な操作を繰り返し、決定キーを押すだけで良いのです。同じ操作の繰り返しは素早く行えるということをうまく活用したUIといえます。キーの数が多いことを前提とした、脳への負担が高い設計のHit-a-hintなどとは好対照です。
UIの変化と改良プロセス
使いやすさは「なんとなく」で決めてしまいがちです。配色、配置、行間など、デザイナの中には理詰めで決める人もいれば、フィーリングで決める人もいます。
どっちのほうが好み? という質問には明確な解答を得ることは難しいものですが、「 どちらのほうが目的を早く達成できるか」「 どちらのほうが操作ミスが少ないか」「 どちらのほうが脳への負担が少ないか」といった問いに置き換えれば定量化が可能です。
「発明」と呼ばれるような新しいUIには、共通の特徴、いくつかのコツを見出すことができます。
Hit-a-hintは、旧来必要だったタイピング数を大幅に減少させました。バブルカーソルはカーソルの移動距離を短くしました。マウスジェスチャはボタンまでマウスカーソルを移動させる手間をまるっきりなくしてしまいました。
このうちいくつのUIがユーザに受け入れられ、標準化されていくのでしょうか。もしくはすべて淘汰されてしまうでしょうか。
「どこからでも使えるようにする」「 操作の手間を最小にする」「 視線移動を最小にする」「 単純な操作を繰り返す」........。それぞれのアイデアを細かく見ていけば、アプローチこそ違うものの、目的を達成するために必要な操作が短略化されていることがわかります。
最近では特にスマートフォンの普及に伴って、デスクトップ向けのUIであってもタッチパネルデバイスとの整合性を高めるために、変化していく兆候が見られます。
エンジニアの中には「自分にはデザインのセンスがない」と思い込んでしまっている人が多いのではないでしょうか。配色やアイコンなど見た目のデザインは筆者も苦手です。
しかし、ユーザの操作に応じた動きを伴うデザインについてはプログラミングの知識が欠かせません。
ゲームなど異なる分野ではよく知られていたり、ハッカーやギークと呼ばれる人の間では知られているものの、多くのユーザには知られていないような隠れた発明的なUIは、まだまだ数多く存在します。
本稿を読んでいるみなさんでしたら、普段何気なく使っているソフトウェアの中からも、きっと多くの知見を得ることができるでしょう。エンジニアはUIデザインに関して、すでに多くのことを知っているはずですから。
革新的なUIはユーザ体験の変化をもたらし、想定される使い方に応じてデータ構造、サービス全体のーキテクチャをも変化させます。本稿がエンジニアのみなさんにとって、UIへ踏み出す第一歩となれば幸いです。