antislop-layoutmobile
アンチスロップ:AIコーディングエージェントのためのルール。モバイルレイアウトスキル
アンチスロップシステムの一部。
antislop.md(コア)と一緒に読んでください。このスキルは、レスポンシブレイアウトの懸念事項、すなわちレイアウトが電話からデスクトップまで画面サイズに応じてどのように再構成されなければならないかを深く掘り下げます。ブレークポイント、スケール、グリッド、オーバーフロー、タップターゲット、ナビゲーションについて扱います。コアルールを番号で参照し、重複や再番号付けは決して行いません。このスキルは、あらゆる画面幅で機能する必要があるレイアウトを構築または編集するタスクがある場合に読み込んでください。
このスキルの使い方
antislop.mdと一緒に、タスクがモバイルまたはレスポンシブレイアウト作業である場合は常に読み込んでください。コアはメカニズム(目的テスト、3つの階層、デリバリーゲート)を保持し、このスキルはモバイルレイアウトの深みを保持します。- 各エントリは同じ形式を持ちます:Tell(パターン)、Why(それがスロップとみなされる理由)、Fix(代わりに行うべきこと)、そして支配的なコアルールがR-XXとして引用されます。
- このスキルの背後にある原則:モバイルレイアウトはデスクトップレイアウトを小さくしたものではなく、別のレイアウトです。 それは再構成されなければなりません:意図を持って再スタック、再スケール、再オーダーされます。以下の各パターンは、レイアウトが再構成に失敗する方法です。
- コアのデリバリーゲートは引き続きゲートです。このファイルの最後にある「レイアウトモバイルスキルチェックリスト」は、それと併せて実行するモバイル固有の補足です。
ブレークポイント
デスクトップのみのレイアウト
- Tell: すべての画面に対して1つのレイアウト状態しかなく、モバイルビューはデスクトップレイアウトを電話に押し込めたものです。
- Why: R-03は、後付けではなく、完璧なモバイルレイアウトを要求します。単に縮小するだけのページにはモバイルデザインがまったくありません:並んでいたカードは重なり、広いキャンバス向けのテキストは狭いキャンバスに押し込められます。
- Fix: コンテンツが機能しなくなるブレークポイントで、真のモバイル状態を定義します。モバイルレイアウトは再構成します:カラムは積み重なり、サイズは小さくなり、コンテンツが必要とする場所で順序が変わります。モバイルビューが単にデスクトップビューを小さい幅にしただけの場合、レイアウトは完成していません。
デバイスリストによって駆動されるブレークポイント
- Tell: 「それがiPhoneのサイズだから」という理由で選ばれた電話幅(375px、414px、768px)にちなんで名付けられたブレークポイント。コンテンツがそこで壊れるからではありません。
- Why: デバイスの幅は毎年、モデルごとに変わります。ブレークポイントはレイアウトが機能しなくなるポイントです。それをデバイスリストに強制的に一致させると、レイアウトはコンテンツ(R-03)ではなく仕様書に従うことになります。
- Fix: コンテンツが実際に壊れる場所にブレークポイントを配置します:カラムが読みにくくなったとき、カードの行が狭くなりすぎたとき。ビューポートを狭めて、どこでスナップするかを見てテストし、そこにブレークポイントを設定します。
モバイルが最後にスタイルされる
- Tell: モバイルルールが後付けのオーバーライドとして付け加えられる:長いデスクトップスタイルシートの最後に、1つか2つのことを修正する小さなメディアクエリがある。
- Why: オーバーライドパッチはモバイルデザインではありません。報告された症状を修正し、次の症状を残し、ベーススタイルはワイドスクリーン(R-03)に合わせたままです。
- Fix: モバイルをオーバーライドではなく、設計された状態として扱います。狭いビューポートに独自の意図的なサイズとスタッキングを与え、パッチを当てた箇所だけでなく、レイアウト全体をそこで確認します(R-35)。
2状態レイアウト
- Tell: 正確に2つの状態を持つレイアウト:1つのブレークポイントより下では単一の積み重ねられたカラム、その上では幅広のマルチカラムグリッド。その間には何も定義されていません。タブレットや小型ラップトップの幅は、最も近い状態のいずれかを継承します:ばかげて広く引き伸ばされた電話のスタックか、意図されたキャンバスのごく一部に詰め込まれたデスクトップグリッド。
- Why: ページは幅の連続的な範囲であり、R-03は選択された2つのブレークポイントだけでなく、そのすべてで機能することを要求します。2つの状態では、範囲の中間帯域(およそ600~1024px、タブレットや小型ラップトップが存在する場所)全体が偶然の産物になります:意図を持って積み重ねられることも、フィットするグリッドに配置されることもないコンテンツ。レイアウトは、その2つのサンプルポイントでのみ設計されたように見え、その間のどこでも壊れているように見えます。
- Fix: コンテンツが機能しなくなる幅で実際の状態を定義し、コンテンツが必要とするだけの状態にします。典型的な再構成は3つの状態であり、2つではありません:単一カラム、次に単一スタックとしてカードが広くなりすぎたときの2カラムグリッド、そしてそれが本当にフィットする場合のみの完全なマルチカラムグリッド。2つの幅をチェックして完了と呼ぶのではなく、ビューポートを範囲全体にドラッグして確認します(R-35)。
スケールとサイジング
デスクトップサイズのすべて
- Tell: パディング、ギャップ、ヒーローの高さ、カードサイズがデスクトップからモバイルに変更されずに引き継がれ、すべてのセクションが電話で拡大されて見える。
- Why: 1440pxのキャンバス用にサイズ設定された要素は、375pxのキャンバスを支配します。デスクトップでは自信を持って見えるものが、モバイルでは大きすぎるように見えます:何も収まらず、何も呼吸できず、ページは手元にある画面ではない画面用にデザインされたように感じられます(R-03)。スペーシングとタイプはデザインリズム(R-05)に従うべきであり、そのリズムはモバイルではより小さなレジスターを持ちます。
- Fix: モバイルに独自のサイズステップを与えます:より小さなタイプスケール、よりタイトなセクションパディング、より小さなギャップ。タップターゲットは最小サイズ(タップターゲットを参照)に保ちますが、他のすべてはブレークポイントで意図を持って縮小します。
固定ピクセルタイプ
- Tell: デスクトップとモバイルの間で決して変わらない固定pxのフォントサイズ。そのため、見出しと本文テキストは電話で大きすぎるままです。
- Why: ビューポートに応答しないタイプは、1つの画面用にサイズ設定されたタイプです。R-03はモバイルレイアウトが機能することを要求し、R-06は読みやすさを向上させるタイポグラフィを要求します。電話の幅全体にまたがる見出しや、広い行用に調整された本文サイズは、両方を破ります。
- Fix: 流体タイプ(
clamp())を使用してサイズがビューポートに合わせて拡大縮小されるようにするか、ブレークポイントでより小さなタイプステップを設定します。デスクトッププレビューだけでなく、狭い幅で結果を確認します(R-35)。
100vhセクション
- Tell: ヒーローとセクションの高さが
100vhに設定されており、セクションが電話の画面全体を埋め尽くし、他のすべてをスクロールしないと見えない場所に押しやる。 - Why: デスクトップモニター用に設計されたフルビューポートセクションは、電話では巨大なスラブになり、
100vhにはブラウザクロームが含まれるため、モバイルブラウザでは表示領域からはみ出します。これはレイアウトを紹介する代わりに支配します(R-03)。 - Fix: セクションのサイズをコンテンツに合わせて(
auto)するか、実際に全高セクションが意図されている場合は動的ビューポート単位(dvh)を使用します。スクロールしないと見えない場所は、ビューポート単位の偶然であってはなりません。
巨大な空のパディング
- Tell: デスクトップスケールのセクションパディング(96px、128px)がモバイルで保持され、電話上のセクション間に背の高い空のギャップを作成する。
- Why: 大きなキャンバス用に調整されたパディングは、小さなキャンバスでは無駄な垂直スペースに変わります。ページは空虚さの中をスクロールし、R-05が求めるリズムはすべてのセクション間の空白になります。
- Fix: ブレークポイントでのセクションパディングをモバイルレジスター(およそ半分以下)に減らし、ページが砂漠のようなスペースではなく、自然な密度でスクロールすることを確認します。
グリッドとスタッキング
折りたたまれないカラム
- Tell: マルチカラムグリッドがモバイルでその並んだカラムを保持し、カラムが縮み、テキストが不格好に折り返され、要素が衝突する。
- Why: グリッドは、どれだけの幅が利用可能かについての約束です。ビューポートが狭くなり、グリッドが再スタックしない場合、すべてのカラムは細切れになり、テキストは読めなくなり、カードは重なります(R-03)。これが衝突の失敗です:デスクトップの並びがモバイルの山積みになります。
- Fix: ブレークポイントでグリッドを単一の再構成カラムに折りたたみます。並びは積み重なりになり、各アイテムは再び全幅を取得します。狭い幅で再確認します(R-35)。
固定幅グリッド
- Tell:
grid-template-columnsが固定pxで設定されている、または再構成できないグリッドエリアがあり、ビューポートが縮小するとグリッドが rigid のままになる。 - Why: 固定pxのトラックはビューポートを気にしません。その幅を維持し、オーバーフローまたは衝突を強制します。レイアウトは1つのキャンバス用に構築され、形状を変更できません(R-03)。
- Fix: トラックのサイズを
minmax()、auto-fit、auto-fillで設定して、カラムがコンテンツに合わせて縮小および折り返されるようにし、ブレークポイントで折りたたまれるグリッドエリアを定義します。グリッドはデフォルトでfluidであるべきであり、固定サイズが意図的である場合にのみrigidにします。
強制12カラム
- Tell: 1つか2つのカラムを必要とするモバイルコンテンツに12カラムグリッドが強制され、スパンが恣意的に見え、計算がレイアウトと戦う。
- Why: 12カラムシステムは、多くのカラムのコンテンツを持つ広いキャンバス用です。それを電話に強制すると、すべての要素はユーザーが決して見ることのない invisible なグリッドの一部になり、コンテンツはグリッドに合わせてフィットされ、グリッドがコンテンツに合わせられることはありません(R-03)。
- Fix: カラムをコンテンツに従わせます。モバイルでは、コンテンツは通常1カラム、またはせいぜい2カラムを望みます。12カラムのスパンは、レイアウトに実際にその数のものが並んでいる場合にのみ意味をなします。
オーバーフロー
水平スクロールリーク
- Tell: テーブル、コードブロック、画像、長い改行のない文字列など、一部の要素がビューポートよりも幅広いため、ページが横にスクロールする。
- Why: 水平スクロールはモバイルでの壊れた約束です。ユーザーはページがどこで終わるかを見ることができず、レイアウトは明らかに画面からはみ出します(R-03)。これは最も一般的なオーバーフロースロップです。なぜなら、問題のある要素はデスクトッププレビューでは画面外にあり、電話で開くまで気づかれないからです。
- Fix: ビューポートより幅広い要素(リフローレイアウトまたはスクロールコンテナを必要とするテーブル、折り返すコードブロック、
max-width: 100%の画像)を見つけ、それを包含または再構成します。最も狭いターゲットでページ全体に水平スクロールがゼロであることを確認します(R-35)。
オーバーフロー非表示クリッピング
- Tell:
overflow: hiddenがコンテナに設定され、狭い幅でコンテンツをクリップし、テキストやコントロールをフィットさせる代わりに隠す。 - Why: クリッピングは失敗を隠すことです。レイアウトがコンテンツを収容できないためにコンテナがそのコンテンツを切り落とす場合、ユーザーは情報とインタラクションを失います(R-03)。これに関するズームとテキストサイズ変更の観点は
antislop-humanでカバーされています。 - Fix: クリッピングする代わりにコンテンツを再構成させます:コンテナを成長させ、そのコンテンツを折り返すか、ブレークポイントで折りたたみます。クリップは、それがデザインの意図である場合(サムネイルなど)にのみ行い、コンテンツを隠す場合には決して行いません。
固定幅の子要素
- Tell: 固定px幅または
min-widthを持つflexまたはgridの子要素が、狭い画面で親からはみ出す。 - Why: 絶対pxでサイズ設定された子要素は、その親がどれだけの余地を持っているかを気にしません。モバイルでは親が縮小し、子要素は幅広のままなので、コンテナとページからオーバーフローします(R-03)。
- Fix: 子要素のサイズを相対単位で設定し、折り返しを許可します(
flex-wrap、fluid幅、グリッド子要素のmin-width: 0)。子要素はそのコンテナとともに縮小できるようにするべきであり、デスクトップサイズを保持するべきではありません。
タップターゲット
サイズ不足のターゲット
- Tell: ボタン、リンク、コントロールが約44 x 44 pxより小さく、デスクトップではカーソルで簡単にクリックできるが、親指ではクリックしにくい。
- Why: デスクトップカーソルはピクセル精度を持ちますが、親指はそうではありません。16pxで問題ないターゲットは、電話ではフラストレーションの訓練になり、UIがモバイルで使用可能であるという約束を破ります(R-03)。
- Fix: インタラクティブターゲットに44 x 44 pxの最小タッチ領域を与え、視覚的に小さい場合でもパディングまたはより大きなヒットボックスを使用します。電話幅でコントロールのセット全体を確認します(R-35)。
近すぎるターゲット
- Tell: 44pxのターゲットが隙間なく詰め込まれており、親指のタップが間違ったターゲットに当たる。
- Why: ターゲットサイズはターゲット間隔との組み合わせでのみ重要です。接触している2つの大きなコントロールは、1つの大きなコントロールのように動作します:ユーザーはどちらかを確実に選択できません(R-03)。
- Fix: 隣接するインタラクティブターゲットの間に明確なギャップを残し、少なくとも数px、理想的には指の押下領域が重ならないように十分な間隔を空けます。スペーシングはタップ可能性のもう半分です。
ホバー専用インタラクション
- Tell: ホバー時にのみ存在するメニュー、表示切り替え、ツールチップ。そのため、タッチユーザーはそれらを開くことができない。
- Why: タッチスクリーンにはホバーがありません。ホバーにのみ応答するインタラクションは、モバイルユーザーにとっては単に存在せず、それに依存するコントロールは行き止まりです(R-03)。
- Fix: すべてのホバー専用インタラクションにタップの同等物を与えます:ホバー時に開くメニューはタップでも開き、表示切り替えはクリックでも表示され、インタラクティブ要素はタップが登録されるように可視の
:activeフィードバックを示します。タッチのみでUIを使用してテストします(R-35)。
モバイルナビゲーション
デスクトップのままのナビ
- Tell: リンクの行を持つデスクトップトップバーがモバイルで並んだまま保持され、リンクが混雑し、2行に折り返されるか、ビューポートからはみ出す。
- Why: デスクトップナビは広いキャンバス用にサイズ設定されています。電話で行のままにすると、窮屈なリンクの混乱になり、モバイルユーザーが最初に目にするものです(R-03)。ナビゲーションは再構成が最も重要な場所です:ユーザーはどこかに行く前に、どこへ行くかを見つけなければなりません。
- Fix: ブレークポイントでナビをモバイルパターンに折りたたみます:少数の主要な目的地にはボトムナビ、残りにはメニュー。リンクは行から再構成され、主要な目的地は親指1回のタップ距離に留まります。狭い幅で機能することを確認します(R-35)。
ベアハンバーガー
- Tell: すべてがラベルやヒントのないハンバーガーアイコンの背後に隠されており、ユーザーがメニューの存在に気付かなかったり、何が開くのかわからない。
- Why: ベアハンバーガーは、ユーザーがすでにアイコンの意味とその背後にメニューが隠れていることを知っていることを前提としています。それはモバイルユーザーが持っていない知識である可能性があり、モバイルでは隠されたメニューがアプリを操作する唯一の方法を保持している可能性があります(R-03)。
- Fix: メニューを発見可能に保ちます:ハンバーガーにラベルを付けます(「メニュー」)、または主要な目的地を可視に保ち、二次的なものだけを隠します。メニューが何か重要なものに到達する唯一の方法である場合、その到達可能性は明らかでなければなりません。
コンテンツを食べるボトムナビ
- Tell: コンテンツの上に固定されたボトムナビバーがあり、最後のリストアイテム、最終ボタン、またはユーザーが完了しようとしていたフォームを覆い隠す。
- Why: 固定ボトムバーはモバイルでは貴重な垂直方向のスペースを占有します。それがコンテンツを覆う場合、ユーザーは画面の下部にあるものと対話したり、見たりすることができなくなります。これは、コンテンツがナビゲーションのために犠牲にされる場合のナビゲーション優先のレイアウトの失敗です(R-03)。
- Fix: ボトムナビがコンテンツを覆わないようにします:スクロール時にコンテンツの後ろに隠れるか、十分なパディングを追加してコンテンツがその下に入り込まないようにします。ページの最後のインタラクティブ要素は、ナビゲーションによって隠されることなく、完全に可視でアクセス可能でなければなりません。
レイアウトモバイルスキルチェックリスト
このチェックリストをデリバリーゲートと一緒に使用して、モバイルレイアウトの仕上がりを検証します。すべてのチェックに合格するまで、レイアウトは完了しません。
- レイアウトは、狭いビューポートで単に縮小するのではなく、再構成します(カラムが積み重なり、サイズが小さくなる)。
- ブレークポイントはコンテンツのブレークポイントに配置されており、デバイスのリストには配置されていません。
- モバイルスタイルはオーバーライドパッチではなく、設計された状態です。
- 2つ以上のレイアウト状態が定義されており、範囲内のすべての幅が機能します(典型的には3状態:単一カラム、2カラムグリッド、マルチカラムグリッド)。
- モバイルのパディング、ギャップ、タイプサイズは、デスクトップのレジスターとは別に、独自のスケールステップを持っています。
- タイプは流体であり(
clamp())、またはブレークポイントで独自のサイズを持っています。 - セクションの高さはコンテンツによって決まり、
100vhによって強制されていません(意図的な場合を除く)。 - マルチカラムグリッドはモバイルブレークポイントで単一カラムに折りたたまれます。
- グリッドトラックは固定pxではなくfluidです(
minmax())。 - カラム数はモバイルのコンテンツに従い、12カラムシステムを強制しません。
- 水平スクロールは最も狭いターゲット幅でゼロです。
- コンテンツを隠すために
overflow: hiddenは使用されていません。 - 子要素はその親とともに縮小でき、固定幅を保持しません。
- すべてのタップターゲットは少なくとも44 x 44 pxです。
- タップターゲットは、誤タップを防ぐために十分な間隔が空けられています。
- ホバー専用のインタラクションはありません。すべてにタップの同等物があります。
- ナビゲーションはモバイルパターンに折りたたまれています(ボトムナビまたはラベル付きメニュー)。
- 固定ナビゲーション要素はコンテンツを覆い隠しません。
- レイアウトは、ビューポートをターゲット範囲全体(最も狭い電話から最も広いデスクトップまで)にドラッグすることによって検証されています。