モバイルファーストなモーダル設計 — フルスクリーンシートの実装

2026.02.04
Share:

はじめに

モバイルアプリでモーダルを使おうとして、こんな経験はありませんか?

  • モーダルの中でスクロールしようとしたら、背景がスクロールしてしまった
  • フォームを入力中にキーボードが出てきて、入力欄が隠れた
  • 閉じるボタンが小さくて押しにくい

これらは、PC 向けのモーダルデザインをそのままモバイルに持ち込んだときに起きがちな問題です。

私は IdeaSpool を開発する中で、モバイルでのモーダル体験に何度も悩まされました。試行錯誤の末にたどり着いたのが「フルスクリーンシート」というアプローチです。

この記事では、その設計と実装のポイントを共有します。

従来のモーダルの問題点

PC では、画面中央に小さなモーダルを表示するのが一般的です。しかし、これをそのままモバイルに持ち込むと、いくつかの問題が発生します。

1. スクロールの問題

モーダル内のコンテンツが長いとき、スクロールが必要になります。しかし、モバイルブラウザでは「モーダル内のスクロール」と「背景のスクロール」の区別が難しく、ユーザーが意図しない動作をすることがあります。

2. タッチターゲットの問題

PC 向けのモーダルは、閉じるボタンが小さいことが多いです。マウスなら問題ありませんが、指でタップするには不十分なサイズであることが少なくありません。

3. キーボードとの干渉

フォーム入力時にソフトウェアキーボードが表示されると、小さなモーダルでは入力欄が隠れてしまうことがあります。

フルスクリーンシートという解決策

2026年1月24日、IdeaSpool の開発日記にこう書きました:

フルスクリーンシートはモバイルで使いやすい(Radix UI の Sheet を使用)

「フルスクリーンシート」とは、画面の下から上にスライドして、画面全体(またはほぼ全体)を覆う UI パターンです。iOS のネイティブアプリでよく見かけるデザインです。

この方式には以下のメリットがあります:

  • スクロールが自然: 画面全体がスクロール領域になるため、背景との干渉がない
  • タッチターゲットが大きい: 画面幅いっぱいを使えるため、ボタンを十分な大きさにできる
  • キーボード対応: 画面全体を使えるため、キーボードが出ても入力欄を調整しやすい

IdeaSpool での実装経験

課題の発見

IdeaSpool では、プロジェクト編集機能をモーダルで実装していました。最初は一般的な中央配置のモーダルを使っていましたが、開発日記にはこう記録しています:

モバイルでモーダル内スクロールが使いづらかった

プロジェクト編集フォームには複数の入力項目があり、モーダル内でスクロールが必要でした。しかし、小さなモーダル内でのスクロールは操作しづらく、特にフォーム入力中にキーボードが表示されると、表示領域がさらに狭くなって使いにくさが増しました。

フルスクリーンシートへの移行

開発日記から:

プロジェクト編集をフルスクリーンシートに分離

解決策として、プロジェクト編集機能を「フルスクリーンシート」に移行しました。Claude Code に依頼して Radix UI の Sheet コンポーネントを使い、画面下からスライドして全画面を覆うデザインに変更しました。

Radix UI Sheet の使い方

IdeaSpool では Radix UI(shadcn/ui 経由)を使用しています。Sheet コンポーネントの基本的な使い方はこうなります:

import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet";

export function ProjectEditSheet({ project }) {
  return (
    <Sheet>
      <SheetTrigger asChild>
        <Button variant="outline">編集</Button>
      </SheetTrigger>
      <SheetContent side="bottom" className="h-[90vh]">
        <SheetHeader>
          <SheetTitle>プロジェクトを編集</SheetTitle>
        </SheetHeader>
        <div className="overflow-y-auto flex-1">
          {/* フォーム内容 */}
        </div>
      </SheetContent>
    </Sheet>
  );
}

ポイント: side="bottom" と高さ指定

side="bottom" を指定することで、シートが画面下から上にスライドして表示されます。h-[90vh] のように高さを指定することで、フルスクリーンに近い表示になりつつ、上部に少し余白を残して「シートである」ことを視覚的に示せます。

ポイント: スクロール領域の指定

overflow-y-auto をコンテンツ領域に指定することで、内容が長い場合にスクロールできるようになります。シート自体は固定で、中のコンテンツだけがスクロールします。

デザインのポイント

1. 閉じる方法を複数用意する

モバイルでは、シートを閉じる方法を複数用意することが大切です:

  • 下にスワイプ: 最も直感的な操作
  • ×ボタン: 右上に配置
  • 背景タップ: オーバーレイ部分をタップ

Radix UI の Sheet はこれらをデフォルトでサポートしています。

2. ヘッダーを固定する

シートのヘッダー(タイトルと閉じるボタン)は固定して、コンテンツだけをスクロールさせます:

<SheetContent className="flex flex-col">
  <SheetHeader className="flex-shrink-0">
    <SheetTitle>タイトル</SheetTitle>
  </SheetHeader>
  <div className="flex-1 overflow-y-auto">
    {/* スクロールするコンテンツ */}
  </div>
</SheetContent>

3. フッターにアクションボタンを配置

保存ボタンなどのアクションボタンは、フッターに固定配置すると使いやすくなります:

<SheetContent className="flex flex-col">
  <SheetHeader>{/* ヘッダー */}</SheetHeader>
  <div className="flex-1 overflow-y-auto">{/* コンテンツ */}</div>
  <div className="flex-shrink-0 pt-4 border-t">
    <Button className="w-full">保存</Button>
  </div>
</SheetContent>

長押し選択との組み合わせ

IdeaSpool では、フルスクリーンシートと一緒に「長押し選択」機能も Claude Code で実装しました。

開発日記から:

アイデアカード長押しで選択モードに入る機能

長押しの判定時間

  • 300ms だと誤操作が多い
  • 500ms が丁度良かった

500ms の長押しでカードを選択し、選択したアイデアに対する操作をフルスクリーンシートで行う。この組み合わせにより、モバイルでの操作性が大きく向上しました。

PC とモバイルで使い分ける

フルスクリーンシートはモバイルでは最適ですが、PC の大画面では画面全体を覆う必要はありません。レスポンシブに切り替えるアプローチもあります:

// メディアクエリで表示を切り替える例
<SheetContent
  side="bottom"
  className="h-[90vh] md:h-auto md:max-h-[80vh] md:w-[500px] md:mx-auto"
>

または、PC では従来のモーダル、モバイルではフルスクリーンシートと、コンポーネント自体を切り替える方法もあります:

export function EditDialog({ project }) {
  const isMobile = useMediaQuery("(max-width: 768px)");

  if (isMobile) {
    return <ProjectEditSheet project={project} />;
  }

  return <ProjectEditModal project={project} />;
}

実装時に悩んだこと

キーボード表示時のレイアウト

開発日記には記録していませんでしたが、実装時に悩んだのがキーボード表示時のレイアウトです。

iOS Safari では、ソフトウェアキーボードが表示されると vh 単位の計算が変わります。h-[90vh] と指定していても、キーボード表示時に意図しない高さになることがあります。

解決策として、CSS の dvh(Dynamic Viewport Height)を使う方法があります:

.sheet-content {
  height: 90dvh;
}

ただし、ブラウザサポートを確認する必要があります。

スワイプで閉じる感度

シートを下にスワイプして閉じる機能は便利ですが、感度が高すぎると、コンテンツをスクロールしようとしただけで閉じてしまうことがあります。

Radix UI の Sheet はこのあたりをうまく処理してくれますが、独自実装する場合は注意が必要です。

まとめ

モバイルでのモーダル設計には、フルスクリーンシートが有効です。

ポイントをまとめると:

  • 画面下からスライド: 直感的な表示・非表示
  • 高さは90vh程度: 完全なフルスクリーンより、少し余白を残す
  • ヘッダー・フッター固定: コンテンツのみスクロール
  • 閉じる方法は複数: スワイプ、×ボタン、背景タップ

IdeaSpool での開発日記を振り返ると、こう記録しています:

フルスクリーンシートはモバイルで使いやすい

最初から完璧な設計ができたわけではありません。従来のモーダルで問題を感じ、試行錯誤の末にフルスクリーンシートに辿り着きました。

モバイルファーストの時代、UI設計もモバイルを起点に考えることが大切です。この記事が、皆さんのモーダル設計の参考になれば幸いです。

Zeronova avatar

Zeronovaゼロノバ

Product Manager / AI-Native Builder

Web/IT業界19年以上・20以上のWebサービスを担当したPdM。東証プライム上場企業の子会社代表として事業経営を経験。現在はAIを駆使して企画から実装まで完結させる個人開発を実践中。

関連プロダクト

IdeaSpool

AIが整理する思考キャプチャツール