Misskey & Webテクノロジー最前線

MisskeyのUI設計

本連載は分散型マイクロブログ用ソフトウェアMisskeyの開発に関する紹介と、関連するWeb技術について解説しています。

今回はMisskeyのWebクライアント(Misskey Web)におけるUIデザインの工夫や各種コンポーネントについて紹介します。

なお、⁠デザイン」という語は設計という意味と、見た目・意匠という意味がありますが、この記事ではどちらも含みます。

Misskey Webの設計思想

Misskey Webの設計思想として、⁠デスクトップでもモバイルデバイスでも同じように使えるようにする」というのがあります。

“同じように使える⁠とは、機能や使い勝手といった面でもそうなのですが、コンポーネント(UIを構成する個々のパーツ)レベルの話も含んでいます。

現在はこのような設計思想で開発していますが、Misskey初期の頃は、デスクトップ版Webクライアントとモバイルデバイス向けWebクライアントを別々に作っていました。これにはメリットもあるのですが、コンポーネントを共通化できないデメリットのほうがはるかに大きく、しばしば「デスクトップ版ではこの機能が使えるけどモバイルでは使えない」といった差が生まれてしまいました。

そこで、デスクトップでもモバイルでも共通で使えるユニバーサルなUIに統一するという設計に変更ました。これはレスポンシブデザインとも言われますが、後ほど紹介するとおりMisskey Webではそれよりも深いレベルで統合を行っています。

UIコンポーネント

実際に個々のコンポーネントの一部を紹介します。

パネル

パネルは、基本的なコンポーネント(というよりデザイン)のひとつで、周りの背景と異なる色を持つ領域です。リスト内の個々の要素の領域を示すために使わることが多いです。

パネルの例(1)

パネルはグリッド状に置かれることもあります。

パネルの例(2)

なお、パネル内にあるパネルは背景色が同化することを防ぐため交互に色が変わるようにしています。しかし現在のMisskeyのクライアントでは、パネル単体の中に別のパネル単体があるケースは存在しないため、具体例の紹介はできません。ただし後述のように、別のコンポーネントの一部としてパネルが使われる場合に、パネルが入れ子になるケースがあります。

ボタン

ボタンは基本的な要素のひとつで、クリックすることにより何らかの操作を行うものです。

ボタンの例(1)

Misskeyでは通常のボタンに加え、以下のバリエーションがあります。

  • primary:テーマカラーの単色塗り潰し。何かの「決定」「保存」など
  • gradate:テーマカラーのグラデーション。primaryの中でもさらにボタンを強調したい場合(アカウント作成など)
  • danger:赤文字。何かを削除するときなど
  • rounded:角丸

特に使い分けが決まっているわけではなく、使われる場所に合うものを選んでいます。たとえば、次のボタンはroundedが設定されています。

ボタンの例(2)

フォルダ

フォルダは内容を折りたたむことができ、内容を表すテキストをヘッダーとして持つことができるコンポーネントです。内容の部分は前述したパネル扱いになります。

フォルダの例

ヘッダー部分はスクロールに追従します。このようなUIをWebではSticky Headerと呼びます。

フォルダのヘッダーはスクロールに追従する

フォルダを入れ子にすることもできます。パネルであるためこの場合も背景色が交互に代わり、背景と同化しないようになっています。

フォルダの入れ子例(1)

フォルダ内では、複数のパネルを持つことができます。

フォルダの入れ子例(2)

ヘッダーにはサフィックスとして簡単なステータスなども表示できます。

ステータスを表示しているヘッダーの例

このように、画面の情報量を少なく保ったまま必要な情報を詰め込めるため、特に設定画面などで多用されるコンポーネントになっています。

ツールチップ

ツールチップは、ボタンの説明などを表示することに使われるコンポーネントです。

ツールチップの例

ただ、モバイルデバイスとの相性が良くないため、できるだけツールチップなしでも操作に困らないUI設計を心がけています。

ポップアップメニュー

ポップアップメニュー(コンテキストメニュー)は、デスクトップとモバイルでデザインが異なります。

デスクトップのポップアップメニューは次のように表示されます。

デスクトップのポップアップメニューの例

モバイルでは、いわゆるドロワーメニューと呼ばれるデザインになります。

モバイルのポップアップメニューの例

あるコンポーネントを右クリックすることで、ポップアップメニューが出現する場合があります。その場合には「…」ボタンをクリックするなど、必ず右クリック以外の方法でも同じようにメニューを出現させることができるように設計しています。

というのも、スマートフォンやタブレットでは右クリックの概念がないからです(画面の長押しが右クリックに相当するとも考えられますが、Webにおいてはそれ用のAPIが提供されていないため、長押しを精度よく検知するのが不可能とは言わないまでも困難です⁠⁠。

また、メニューはネストする(入れ子にする)こともできます。

ネストされているメニューの例

画面右側に表示するスペースがない場合は左側に表示されます。

右側にスペースがない場合には、ネストされたメニューは左側に表示される

削除などの操作時にワンクッション入れる目的でも使用しています。

操作時のメニュー

メニューの背景色がパネルよりも明るいことに気づいたでしょうか。こうすることでコンポーネントの前後関係、重なりをわかりやすくしています。

セレクトボックス

セレクトボックスはメニューと同様に、デスクトップとモバイルでデザインが異なります。

デスクトップのセレクトボックスはプルダウンして表示されます。

デスクトップにおけるセレクトボックスの例

モバイルではドロワーで表示されます。

モバイルにおけるセレクトボックスの例

テキストボックス

テキストボックスのコンポーネントです。

テキストボックスの例(1)

背景がパネルである場合、ボーダーを表示して同化しないようにしています。

テキストボックスの例(2)

ネストされたパネルと同様に背景色を変えても良いのですが、ライトテーマで白背景の場合、こういったフォームで使われるコンポーネントが灰色だとグレーアウト(コンポーネントが無効化され入力を受け付けない)状態に見えてしまう問題があります。

ダイアログ

アイコン、テキスト、選択肢を設定可能なモーダルダイアログです。

ダイアログの例

ダイアログの外側をクリックして閉じることもでき、その場合はキャンセルが選択されたものとして扱います。

ウィンドウ

Misskey Webでは各種ページをアプリ内ウィンドウで開くことができます。たとえば、ページ遷移を発生させずに、ユーザー情報を確認するといったことが可能です。

以前の記事で少し触れましたが、それぞれのウィンドウを別々にルーティングするために、Vue標準のルーターは使わずに自前でルーターを用意しています。

ウィンドウの例

ウィンドウは辺をドラッグしてサイズを変更したり、最大化するためのボタンがあったりと、一通りのインタラクションを行えます。

iframeを使っているわけではなく、実際にそこにDOMを展開しているため、ウィンドウ内で表示されたポップアップやツールチップはウィンドウの外に飛び出して表示されることも可能です。

設定メニュー

設定メニューは、設定画面などで用いられるナビゲーションです。

デスクトップの場合は左に表示されます。

デスクトップの設定メニュー

モバイルでは全画面でグリッド状に表示されます。

モバイルの設定メニュー

タブ

タブはページ上部に表示されます。タイムラインの種類を切り替えるなど、ページ内容を複数の選択肢の中から選べる場合に使用されます。

タブの例

タブにはアイコンだけ表示し、ツールチップで完全なタイトルを表示するなど、画面の幅が狭い場合でも見やすいように工夫しています。それでも収まらない場合は横スクロールできるようになっています。

論理コンポーネント

目に見える形でのデザインを持たないコンポーネントを論理コンポーネントと呼んだりします。

そのひとつがSticky Containerというコンポーネントで、これは「フォルダ」でも触れた「Sticky header」を実現するために作られたコンポーネントです。

論理コンポーネント

単純なSticky headerであれば、CSS標準の機能で事足りますが、上記画像のように複数のSticky headerがネストされていて、それぞれが重ならずにスクロールに追従するようなUIを実現するためには一工夫必要になります。

そこで用意されたのがSticky Containerで、このコンポーネントでは内部的なスクリプトによってヘッダーが適切な位置に固定されるように設定します。

テーマ

Misskeyにはダークモードにも対応したテーマ機能があり、ユーザーが見た目を自由に変更できるようになっています。

テーマは以下のような形式で定義されていて、標準でインストールされているテーマのほかにも、サードパーティ製のテーマをインストールすることも可能になっています。

テーマの定義

ウィジェット

Misskeyではウィジェットと呼ばれる様々な種類のコンポーネントをクライアント上に自由に配置することができ、カスタマイズ性の高いインターフェイスを実現しています。

ウィジェットの例

ウィジェットの種類は豊富ですが、それぞれのコンポーネントはdynamic importで読み込んでいるため、使っていないウィジェットは読み込まれず軽量化が実現されています。

Storybook

Misskeyの開発においては、Storybookを導入しています。各種コンポーネントの表示を簡単に確認できるようになっているほか、表示の差分を検出して、コードを変更した際に表示が意図したものになっているかのチェックをするようにしています。

具体的な解説や紹介を行うと長くなってしまうので、Storybookについては別の機会に単独の記事として取り上げたいと思います。

まとめ

今回はMisskey WebにおけるUIデザインの工夫や各種コンポーネントについて紹介しました。

UIを設計する上では、レスポンシブ対応、アクセシビリティ、ダークモードなど考慮すべきことが多いですが、UXに直結する部分ですので丁寧な実装が求められます。

Misskeyでは採用していませんが、最近はTailwindなど便利なCSSフレームワークも増えていますので、開発者の学習コストが増えるというデメリットもありますがそれらを採用するのも選択肢のひとつです。

今回紹介したものは一部ですので、また機会があればMisskeyのUIについて取り上げたいと思います。

おすすめ記事

記事・ニュース一覧