UIXHERO

Resizable(リサイザブル)

ユーザーがドラッグ操作でパネルの幅・高さを自由に変更できるUIコンポーネント。分割ペイン・サイドバー幅の調整・エディタースプリッターの設計・最小・最大サイズの制約・アクセシビリティを解説する。

2026年3月3日
更新: 2026年9月3日
17
by Dengen Yosho(DGYS)

ユーザーがドラッグ操作でパネル・ペインの幅や高さを自由に変更できるコンポーネント。コードエディター(VSCodeのサイドバーやターミナル分割)・ダッシュボードのパネル・チャットUI(メッセージリストとプレビューの分割)などで使われる。ユーザーが自分の作業スタイルに合わせてUIのレイアウトをカスタマイズできる「適応性の高いUI」を実現する。

この記事を読むと、水平・垂直スプリッターの設計・最小・最大サイズ制約の実装・キーボードでのリサイズ(矢印キー)・ドラッグハンドルのARIA対応・リサイズ状態の永続化が自分でできるようになります。


1. UI例(Preview / Live)

実装で見る(GunjoUI)

この部品を、デザインシステム GUNJO の実装で確かめられます。

2. 定義(Definition)

ユーザーがドラッグ操作でパネル・ペインのサイズを変更できるUIコンポーネント。2つ以上のパネルを スプリッター(ドラッグハンドル) で区切り、スプリッターを動かすことで隣接するパネルのサイズが相互に変化する。

水平スプリッター vs 垂直スプリッター

種類方向変化するものカーソル
水平スプリッター左右に動く左右のパネル幅col-resize
垂直スプリッター上下に動く上下のパネル高さrow-resize

3. 使い分け(When to use / When NOT to use)

3.1 When to use

  • コードエディター:ファイルツリー + エディター + ターミナルの分割
  • ダッシュボード:サイドパネル + メインコンテンツ + インスペクターパネル
  • チャット・メール:リスト + プレビューの左右分割
  • ユーザーが作業スタイルに合わせてレイアウトをカスタマイズしたいすべての場面

3.2 When NOT to use

  • モバイルのみのUI:タッチでのドラッグリサイズは操作が困難でが悪い
  • レイアウトが固定で良いシンプルなページ
  • コンテンツが少なくリサイズの必要がない場合

4. 設計判断の核(Decision Principles)

Resizableの核は「制約の設計」——最小・最大サイズの制約がないと、パネルを潰しすぎてコンテンツが消え、ユーザーが元に戻せなくなる。

判断の優先順位:① 最小・最大サイズ → ② キーボードでのリサイズ対応 → ③ ARIA設定 → ④ リサイズ状態の永続化

  • 必ず minWidth / minHeight を設定する:制約なしだと0pxまでパネルを縮めてコンテンツが消え、ユーザーが操作方法を見失う。最小サイズはコンテンツが最低限読める幅(80〜120px)に設定する
  • ドラッグハンドルをキーボードで操作できるようにするtabIndex={0} を付与し、onKeyDownArrowLeft/Right/Up/Down キーでの操作を実装する。Shift + Arrow で大きく動かすと操作性が向上する
  • role="separator" + aria-valuenow でARIA対応:スプリッターは role="separator" で意味を伝え、aria-valuenow(現在サイズ)・aria-valuemin(最小)・aria-valuemax(最大)を設定する。スクリーンリーダーが現在のパネルサイズを読み上げられる
  • リサイズ状態を localStorage に保存する:ユーザーがカスタマイズしたサイズはページ遷移・再読み込み後も維持されることを期待する。localStorage にキーを設定して永続化する

5. 状態設計(States)

状態表示
通常ハンドルが薄い色で表示
ホバーハンドルが強調色に変化・カーソル変更
ドラッグ中ハンドルが青くなる・user-select: none
フォーカスfocus-visible リング
最小/最大到達それ以上動かせないことをユーザーに伝える(ハンドルを非強調化)

6. バリエーション設計(Variants)

バリアント分割数使用例
2ペイン(左右)2ファイルツリー + エディター
2ペイン(上下)2エディター + ターミナル
3ペイン3ファイルツリー + エディター + インスペクター
ネスト複数VSCode風の複雑なレイアウト

7. パターン集(Good / Bad / How to fix)

7.1 Bad(典型3つ)

  • 最小サイズ制約なしでパネルを0pxまで縮められ、コンテンツが消えてしまう
  • ドラッグハンドルに tabIndex がなくキーボードでリサイズできない
  • ドラッグ中に user-select: none が設定されておらず、テキストが誤選択される

7.2 Good(対になる3つ)

  • minWidth={80} / maxWidth={400} で操作範囲を制約し、コンテンツが常に読める状態を保つ
  • tabIndex={0} + onKeyDown で矢印キーによるリサイズを実装し、キーボードユーザーも操作できる
  • onMouseDown 開始時に document.body.style.userSelect = 'none' を設定し、onMouseUp で解除する

7.3 How to fix(手順)

  1. minWidth / minHeight / maxWidth / maxHeight を設定する
  2. ハンドルに tabIndex={0} + onKeyDown で矢印キー操作を実装する
  3. role="separator" + aria-orientation + aria-valuenow + aria-valuemin + aria-valuemax を付与する
  4. localStorage.setItem('panel-width', leftWidth) でリサイズ状態を永続化する

8. ルール(Must / Better)

Must(守らないと壊れる)

Better(品質が跳ねる)


9. アクセシビリティ要件(必須)

Keyboard

  • Tab でハンドルにフォーカス
  • / (水平)・ / (垂直)で1pxずつリサイズ
  • Shift + Arrow で大きく(10〜20px)リサイズ
  • Home / End で最小・最大サイズにリセット(任意)

Screen Reader

<div
  role="separator"
  aria-orientation="vertical"
  aria-label="左右パネルの境界線(ドラッグでリサイズ)"
  aria-valuenow="200"
  aria-valuemin="80"
  aria-valuemax="400"
  tabIndex="0"
/>

10. 実装メモ(Implementation Notes)

  • shadcn/ui の ResizablePanelGroup / ResizablePanel / ResizableHandlereact-resizable-panels ライブラリのラッパー。defaultSize はパーセンテージ(0〜100)で指定し、minSize / maxSize も同様
  • react-resizable-panels ではパネルサイズを onLayout コールバックで取得でき、localStorage への保存と組み合わせてレイアウトを永続化できる
  • カスタム実装の場合、pointermove + pointerdown イベントを使うとタッチデバイスにも対応できる(mousemove + mousedown の代わり)

11. 関連リンク


12. まとめ

Resizableの設計で最重要なのは「制約の設計(最小・最大サイズ)」と「キーボード操作のサポート」です。迷ったら 4. 設計判断の核 に戻り、「minWidth / minHeight が設定されているか」「矢印キーでリサイズできるか」「role="separator" + aria-valuenow があるか」の3点を確認してください。ドラッグだけで実装したResizableはキーボードユーザーとスクリーンリーダーユーザーを完全に排除してしまいます。

更新のお知らせ

サイトに載せていない実例や、新しい記事のお知らせはこちらで出しています。

読んだ内容を、自分の画面に当てるとき

UIXHEROは、記事を書くほかに、画面の検品・判定、デザインシステムの構築、実装と改善の伴走を受けています。何を頼めばいいか決まっていない段階の相談も、同じ窓口で受けます。

UIXHEROに頼めることを見る

※ 記事の内容についての質問や、書いてほしいテーマの要望も同じ窓口で受けています

記事をシェア

メールでお知らせを受け取る

最終更新: 2026年9月3日

この記事を書いた人

Dengen Yosho(DGYS)

Dengen Yosho(DGYS)

UI/UXデザイナー兼デザインエンジニア デザイン歴25年以上 情報設計〜UIデザイン〜React/TypeScriptによる実装までを一気通貫で担当 大手企業のDXプロジェクトや決済アプリ領域で、デザインリードとして改善と構築を経験 現在はフリーランスとして、プロダクトのUI/UX改善とデザインシステム構築を支援 長年の実務の中で感じてきたのは、 「良いUI」はセンスではなく、再現可能な判断の積み重ねであるということ UIXHEROは、 心理学や行動科学の知見を、現場で使える設計言語に翻訳するための場所 関心領域は「ユーザーの行動が変わるUI」 人の認知・注意・意思決定の構造を理解し、 “なぜそのUIが機能するのか”を言語化することを目指している

あわせて読みたい

この記事に関連する記事をご紹介します

Bar Chart(棒グラフ)

カテゴリごとの量を棒の長さで比べるチャート。ゼロ基線の扱い、並び順、縦横の選び方、しきい値の見せ方という設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
18

Donut Chart(ドーナツチャート)

中央をくり抜いた円で構成比を示すチャート。中央に置く値の選び方、円グラフとの使い分け、リングの太さ、凡例の作りという設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
17

Gauge Chart(ゲージチャート)

1つの値を範囲の中に置いて示す半円のチャート。範囲の両端に意味があるかという条件、しきい値の帯の設計、色だけで良否を伝えない書き方という設計判断とアクセシビリティ要件を解説する。

2026年8月27日
16

もっと深く知りたいですか?

ここに掲載されていないトピックについても、リクエストがあれば解説記事を追加します。 わかりにくい点や、具体的な事例について知りたいことがあれば教えてください。

リクエストを送る