2023年 UI1グランプリ【THE FINAL】
このスクラップでは、どのようなケースでどのようなUIライブラリを使うのが、ベストな選択なのか、雑にまとめていきます。
大会風に書いているのはあくまでノリであって、ベストな選択は状況によって結論は異なります。
ナンバーワンを決めるのは不可能なことは重々承知です。
全く使ったことのないライブラリについても紹介しているため、どうしても情報に誤りがあったり、大事な情報が欠けていたりもするかと思います。
知見のある方に訂正や補足をいただければと思い、スクラップ形式にしてみました。
「UIライブラリの技術選定に関する知見がたまるスクラップ」という感じにしたいです。
ご紹介したもの以外にも有力なライブラリがあるかもしれませんし、お気軽にコメントください🙏
EntryNo.0381 MUI
観客投票では圧倒的人気ぃぃぃ〜
彼らはゆぅぅぅ〜う、「我らがマテリアルデザインの体現者」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
MUIのメリット
- コンポーネントの豊富さは◎
- ドキュメント充実
- 知名度が高く、使用経験のある人が多い
- コンポーネントのデフォルトの
props
を変更できるなど、カスタマイズの手段が多い - スタイルエンジン(
emotion
,styled-component
など)を選べる - マテリアルデザインを簡単に実現できる
MUIのデメリット
- デザインがマテリアルデザインを踏襲していない場合には、カスタマイズが大変になる
-
fieldset
をネストしたInput系のコンポーネントなど、知見がないとカスタマイズは難しいこともある
コメント
いやぁ〜、さすがでしたね、昨年の覇者としての風格を見せつけたというか、そんな印象でした。
ネタも進化していて、JSS
をデフォルトのスタイルエンジンにするのは止めたようです。
パフォーマンスの面で、それはとても良い決断だったと思います。
近年のUnstyled
化、ロジック部分と見た目部分との分離を進めていく方向性もうまく進んでいるようで、今後も期待できるライブラリです。
ただ一方で、CSS-in-JS
の知見がなく、マテリアルデザインと大きく異なるデザインをMUI
で表現しようとすると、どうしても実装の労力が高く感じてしまう場合があります。
その点は、注意が必要ですね。
スタイルエンジンが選べるのは、人によってはメリットと感じるかもしれないですが、emotion
とstyled-component
の書き味の違いは大きくないですし、特にこだわりがなければどちらでも良いのかもしれません。
参考記事
EntryNo.2093 ChakraUI
あの人気漫画ぁぁぁ、『NARUTO』のチャクラに由来する、ライブラリぃぃぃ〜
カスタマイズのしやすさでは、「圧倒的実力を誇る」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
ChakraUIのメリット
- コンポーネントの豊富さは○
- ドキュメント充実
- 型安全にカスタマイズが可能
- 便利なカスタムフックも同梱
-
Chakra Factory
のおかげで、自分でコンポーネントを足す場合にも非常に楽
ChakraUIのデメリット
- スタイルエンジンは
emotion
固定
コメント
いやぁ〜、さすがでしたね、MUI
の欠点をちゃんと克服しているというか、そんな印象でした。
CSS-in-JS
ベースのライブラリを検討していて、マテリアルデザインとは大きく異なるデザインを実装したい場合には、最有力候補なのではないでしょうか。
当初は、クリックイベントで発生する青いOutline
があったのですが、それを消すのが若干面倒で、不評だったようです。
今大会では、しっかりそこも克服してきて扱いやすくなりましたね。
加えて、chakra-cliというものは、他のライブラリにはないの利点です。
このCLIがあることによって、デフォルトのテーマを変更したときのtheme
の型の変更が非常に楽になります。
この点について、MUI
は型の定義をdeclare
で上書きするのが少し複雑で、差をつけてきた感じですね。
参考記事
EntryNo.4608 Mantine
今大会のダークフォースぅぅぅ〜
知名度こそまだ高くないものの、「近年急上昇してきたライブラリ」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
Mantineのメリット
- コンポーネントの豊富さは◎
- ドキュメント充実
- バージョンアップ、進化のスピードが速い
- 便利なカスタムフックがあり、しかも種類が豊富
- フォームのバリデーションも対応(
Mantine Form
) - ポリモーフィックコンポーネントを作ることのできるUtility関数が便利
- デザインが落ち着いていて、業務系のアプリケーションを作るのに向きそう(主観)
Mantineのデメリット
- 他のライブラリと比べてまだ知名度が低く、ネット上でにある情報も少ない
コメント
いやぁ〜、驚きでしたね。
正直、初めて聞いたライブラリだったんですけど、あまりの完成度にびっくりしました!
コンポーネントの豊富さについて、個人的には期間が選べるDate Pickerがあるのは、すごく助かります。
DatePicker
はChakraUI
にはないですし、MUI
だとMUIX
という有料版になってしまいます。
このように他のライブラリに比べても、コンポーネントの守備範囲が広いのはMantine
の大きな魅力です。
ポリモーフィックコンポーネントというのは、聞きなれない言葉ですが、以下のようなイメージです。
<Button /> // -> buttonタグになる
<Button component="a" /> // -> aタグになる
見た目はそのままに、HTMLタグを変更できます。
これを型安全に実現できるのがcreatePolymorphicComponent
のすごいところで、初めて見たときは感動しましたね。
他のライブラリと比べて顕著な違いとしては、@mantine/hooks
で豊富な種類のカスタムフックが提供されているところです。
ChakraUI
もフックスを提供していますが、その数はMantine
の方が多く、充実しています。
参考記事
EntryNo.1243 HeadlessUI
ヘッドレスという新たなアプローチぃぃぃ〜
彼らはゆぅぅぅ〜う、「UIライブラリに見た目は必要ない」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
HeadlessUIのメリット
- スタイルを上書きする必要がなく、1からデザインを作っていくことができる
- カスタマイズのしやすさは◎
-
Tailwind Labs
が開発を進めており、tailwindCSS
との相性が◎ - 近年のパフォーマンス的な観点で問題があると指摘され始めている
CSS-in-JS
を使わない選択が可能。
HeadlessUIのデメリット
- カスタマイズするのが前提なので、初速は出ないかもしれない
- コンポーネントがあまり豊富ではない
コメント
いやぁ〜、『ヘッドレス』、これが斬新な発想でしたね。
でも改めて言われてみると、むしろ挙動部分と見た目部分を一緒にしてしまう方が間違いで、ヘッドレスの発想こそが、UIライブラリの向かうべき本来の方向性という感じがします。
そもそもヘッドレスとは何か
例えばダイアログを例にとると、
挙動部分
- ボタンを押すと、ダイアログが開く
- ダイアログの背景(
Backdrop
)をクリックすると、ダイアログが閉じる - ダイアログが開いている間は、ダイアログの後ろにある要素はスクロールできない
見た目部分
-
Backdrop
の背景色はrgba(0,0,0,0.7)
というように、分類できそうです。
このとき、挙動部分がありがちな要件は固まっているのに対し、見た目部分は様々なデザインのバリエーションが考えられます。
見た目部分は「カスタマイズの要件が高い部分」だと言えそうです。
UIライブラリが挙動と見た目の両方に関心を持ってしまっている場合には、見た目を変更する際に①デフォルトでどういうCSSが当たっているのか調べる、②デフォルトであっているCSSを上書きする、という面倒なことになるかもしれません。
ヘッドレスは、この問題を解決します。
HeadlessUI
は挙動とアクセシビリティを担保し、スタイルを持たないので、見た目は自由にこちらで変えられます。変幻自在のライブラリと呼ぶこともできそうです。
デザイナーさんが一番喜ぶライブラリかもしれません。
ただ、強調しておきたいのは、「ヘッドレスはHeadlessUI
の専売特許ではない」という点です。
次にあげるRadix UI
もヘッドレスです。
また、@mui/material
を使わないで、@mui/base
だけを使った場合、これもかなりヘッドレスに近いアプローチになります。
このようなことを考えると、HeadlessUI
を導入する決め手は、意外とヘッドレスなUIを求めるか否かではなく、tailwindCSS
を選ぶか否かということになるのかもしれません。
参考記事
EntryNo.2639 Radix UI
アクセシビリティの高いコンポーネントを自在にぃぃぃ〜
彼らはゆぅぅぅ〜う、「UIコンポーネントの車輪の再発明に、いつまで時間を浪費しているの?」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
RadixUIのメリット
-
HeadlessUI
よりもコンポーネントの種類が豊富 - スタイルを上書きする必要がなく、1からデザインを作っていくことができる
- アクセシビリティ対応が◎
- カスタマイズのしやすさは◎
-
stitches
でもtailwindCSS
でも何でもOKな姿勢が素晴らしい
Radix UIのデメリット
- カスタマイズするのが前提なので、初速は出ないかもしれない
- 昨年7月にメジャーリリース、ネット上にある情報はまだまだ少ない
コメント
どういうときになぜasChild
をつける必要があるか、というようなところはReactに詳しい人でないと、理解が難しいのではないかと思います。
フルスクラッチでUIコンポーネントを開発することが面倒であれば、RadixUI
とtailwindCSS
をベースとしたshadcn/uiを一部で利用するなど、柔軟な技術選定も可能かもしれません。
個人的には注目しており、今後が期待できるライブラリです。
参考記事
EntryNo.4192 Semantic UI React
美しい見た目のWebサイトをスピーディにぃぃぃ〜
彼らはゆぅぅぅ〜う、「冗長なBEM
やSMACSS
とはおさらばだ」
さぁ、その実力をぉぉぉ〜、見ぃせつけろぉぉぉぉぉ〜!!!
レッツゲガンガンガン!!!
SemanticUIReactのメリット
- コンポーネントの豊富さは○
-
sass
やless
に馴染みが深い人には扱いやすい
SemanticUIReactのデメリット
-
theming
の仕組みがない - アクセシビリティ対応が不十分
- ライブラリがアクティブにメンテナンスされておらず、ここ数年のコントリビュートは数得るほどしかない
-
will-change
という禁断のCSSが使用されているなど、メンテナンスしにくい面がある - 型安全性が低く、想定されていない
props
をany
で受けつけてしまう
コメント
今から新規開発を始めるなら、SemanticUIReact
を選ぶ選択はまずないと思います。
やめておいた方が無難です。
万一、SemanticUIReact
を使う場合には、スタイルの変更は公式の方法に則って行うのが良さそうです。
Recreating GitHub
というところにあるように、リポジトリをフォークして直接less
を上書きしていくような方向性です。
SemantciUIReact
のスタイルの変更をCSS-in-JSで行うアプローチはオススメしません。
詳細度の問題に絶えず頭を悩まされることになりますし、バグの温床にもなりえます。
このアプローチでは、上書きしたいスタイルがsemantic-ui
のデフォルトのスタイルよりも詳細度が高いのかどうか逐一確認しながら進めていくことになります。
非常に手間です。
!importantの辛み
ライブラリ側ですでに!importantが使われている箇所が多々あり、頑張って詳細度を考えても結局、!important
を使わざるを得ないという切ない感じになります。
具体的には次のようなコードです。
const button = css`
&&&.ui.button:disabled {
opacity: 0.9 !important;
}
`
Semantic UI
なのに!important
という禁じ手を書かざるを得ないのは、あれ、セマンティクスってなんだっけ...?という気分にさせられます。
もちろん2016頃には有力なライブラリだったと思いますし、ライブラリのコントリビューターの方々には感謝したいです。
しかし、メンテナンスがアクティブに行われることは、もうないでしょう。
実際、下記参考記事のディスカッションは、Jack Lukicさんの次のような悲痛なコメントで締められています。
寄付金や広告の額は、開発者の給料の10分の1程度です。それは、貯金を取り崩すことなく、フルタイムで開発することを可能にする金額ではありません。
🥲
参考記事
EntryNo.0000 UIライブラリを使わない選択
長くなってしましたが、最後に
「UIライブラリを使わない」というのも非常に有力な手段です。
その理由は、UIライブラリは栄枯必衰で、移り変わりの激しいものだからです。
かつては有力な選択肢だったライブラリも時代の変遷を経て負債化してしまうかもしれません。
そうなるくらいなら、最初からライブラリに頼らないで実装する。
そういう考え方もありそうです。
ですが、まったくライブラリを使わないで、全部1から作るというのもかなり大変です。
Button
コンポーネントくらいなら簡単に作れますが、Modal
やSelect
といったコンポーネントになってくると、アクセシビリティを妥協せずに、挙動もミスなく作りきるのは、かなりの労力を必要とします。
この選択肢を取るならば、要所要所はreact-modal
やreact-select
などを使うのが妥当な折衷案ということになりそうです。
UIライブラリに依存しないために
とはいえ、とにかく速いサービスのローンチが求められるスタートアップでは、悠長にコンポーネント群を整備している時間などありません。
そして、初速の開発スピードを優先したければ、やはりUIライブラリを使う方が得策です。
もしUIライブラリを使う決断をした場合には、UIライブラリは栄枯必衰という事実にきちんと向き合うべきです。
今はベストな選択も、5年後もそうであるとは言い切れません。
UIライブラリが技術的負債とならないようにするためには、できるだけライブラリに依存しないようにする工夫(=乗り換えやすくしておく工夫)が必要です。
その方法としては、例えば、
import { Button } from "@mui/material"
const HogePage = () => {
return <Button />
}
のように、直接、ライブラリからimportするのではなくて、
import { Button as MuiButton } from "@mui/material"
export const Button = styled(MuiButton)``
import { Button } from "./components/ui/Button"
const HogePage = () => {
return <Button />
}
というように、敢えて一手間かませる、というやり方がありそうです。
そうすることによって、いつでもスタイルを変更することができ、ライブラリの使用をやめたり場合にも、
import { styled } from "@emotion/react"
export const Button = styled.button`
display: inline-flex;
padding: 4px 8px;
border-radius: 4px;
...
`
として、uiディレクトリ内の変更だけで済むので、移行しやすくなります。
多少面倒ではありますが、この一手間は将来的なリターンが大きく、有力なのではないかと思います。
ちなみに、ここ最近は実務で脱SemanticUI
を目指しているのですが、この方向性でSemanticUI
をラッピングしてから、段階的な移行を目指す手段をとっています。
まとめ
以上です!
使用経験のあるライブラリとそうでないライブラリの両方について書いたため、だいぶ主観的になってしまいました。その辺りは、コメントなどで、補っていただけますと幸いです🙏 (そういえばAntDesign
について忘れていたので、どなたかぜひ)