CSSの「interactive-widget」キーワードを使用すると、スマホでキーボードを表示した時でも高さいっぱいに対応できる
Post on:2024年12月10日
スマホで高さいっぱいにしたい時に、100vh
が高さいっぱいにならず頭を悩ませていたときに、100svh
, 100lvh
の動的ビューポート単位が登場して、一時は解決したかに思いました。しかし、これらの単位だけではスマホでバーチャルキーボードなどを表示すると期待通りに機能しません。
このバーチャルキーボード表示時に頭を悩ませていた人に朗報です。CSSのinteractive-widget
キーワードを使用すると、この問題がすっきり解決します。
Control the Viewport Resize Behavior on mobile with interactive-widget
by Bramus!
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
スマホのビューポート単位は、長い間デベロッパーの頭を悩ませてきました。100vh
を使用することは、当初期待していていたものとは正確には異なります。
この問題を解決するためにCSSワーキンググループは、より多くの単位を使用できるように考案しました。その中でも特に動的ビューポート単位(dynamic viewport units)にはsvh
とlvh
があり、それぞれ小さいビューポートの高さと大きいビューポートの高さの1%
を表す便利な単位です。
左: 100vh
、右: 100lvh
ブルーの破線は、レイアウトビューポートです。
これらの単位は2024年現在、相互運用性がありますが(主にWebビューに関する相互運用性の問題がまだあります)、多くの人が抱えている大きな不満が一つあります。それはバーチャルキーボードが表示されたときに、これらの単位がそのバーチャルキーボードの存在を考慮しないことです。プロジェクトによっては、バーチャールキーボードが表示されたときにこれらの単位をサイズ変更したい場合があります。
svh
とlvh
について詳しくは、下記をご覧ください。
CSSの新しい単位「lvh」「svh」これでiOSのSafariで100vhがビューポートの高さではない仕様に対応できる
デフォルトのビューポートのサイズ変更動作
バーチャルキーボードはスマホで表示されると、コンテンツの上に重ねて表示されます。その結果、ビジュアルビューポートはサイズ変更されますが、レイアウトビューポート(固定要素を配置するためのビューポート)は変更されません。
スマホでバーチャルキーボードを表示した状態
100svh
と100lvh
の要素は、バーチャルキーボードの存在に影響を受けない。
レイアウトビューポートは変更されないため、ビューポート単位も変更されません。変更されるのは、スクリーンに表示される視覚的な部分のみを表すビジュアルビューポートのサイズのみです。
注: Chorme 108以前のAndroid版Chromeでは、バーチャルキーボードが表示されるとレイアウトビューポートのサイズが変更されていました。しかし、モバイルSafariに合わせてChromeは動作を調整し、代わりにビジュアルビューポートのサイズのみが変更されるようになりました。FirefoxもFirefox 132のリリースで同じように動作するようになりました。
また、フォーカスされた入力をスクリーンの中央に保つために、ブラウザがレイアウトビューポートを上方(または見方によっては下方)に移動させることもあります。
バーチャルキーボードが表示されているページのビジュアルビューポートの視覚化(オレンジの破線)。
右のレイアウトビューポート(ブルーの破線)はフォーカスされた入力が中央になるように移動されています。
ここで知っておくべき重要なことは、初期包括ブロック(ICB)のサイズはレイアウトビューポート(スモールレイアウトビューポート)に基づいており、ビューポート単位はICBのサイズに基づいているということです。
ICB(レッドの破線)の視覚化。
サイズは、スモールレイアウトビューポートから取得されます。
metaタグのinteractive-widgetキーワード
ビューポートのサイズと形状をコントロールするには、ビューポートのmeta
タグを使用します。おそらく、下記のmeta
タグを使用したことがあるでしょう。
1 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
content
には2つのプロパティがあり、それぞれに値が設定されています。
width
: ICBの幅のサイズを設定、device-width
はデバイスの幅に応じてサイズが決まることを示します。initial-scale
: ページが最初に読み込まれたときのズームレベルを設定、デフォルトの1
が設定されます。
ビューポートのmeta
タグで使用する新しいキーワードは、interactive-widget
です。これを使用すると、バーチャルキーボードなどのインタラクティブウィジェットが表示されたときにビューポートがどのように動作するかを設定できます。
resizes-visual
: ビジュアルビューポートのみをサイズ変更し、レイアウトビューポートのサイズ変更はしません。resizes-content
: ビジュアルビューポートとレイアウトビューポートの両方をサイズ変更します。overlays-content
: どのビューポートもサイズ変更しません。これはoverlaysContent
をtrue
に設定してVirtual Keyboard APIを使用するのと似ています。
それぞれの値がどのように異なるかは、下記をご覧ください。
resizes-content
を設定すると、高さいっぱいになります。
オレンジはビジュアルビューポート、ブルーはレイアウトビューポートです。interactive-widget
の値に応じてサイズが異なります。
interactive-widget
にresizes-content
を設定すると、レイアウトビューポートをサイズ変更できます。その結果、ICBもサイズ変更され、ビューポート単位も異なる値になります。
interactive-widget
にresizes-content
を設定した場合の影響を視覚化。
バーチャルキーボードが表示されると、ICBがサイズ変更され、ビューポート単位が調整されます。
バーチャルキーボードに対応したmetaタグの記述方法
バーチャルキーボードが表示されたときのビューポートのサイズ変更をコントロールするには、ビューポートのmeta
タグのinteractive-widget
キーワードを使用します。デフォルトでは、ビジュアルビューポートはサイズ変更されます。レイアウトビューポートもサイズ変更するには、interactive-widget
の値をresizes-content
に設定します。
1 |
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content"> |
これらのビューポートをサイズ変更しない場合は、interactive-widget
の値をoverlays-content
に設定します。interactive-widget
は、Chrome 108+, Firefox 132+でサポートされています。
sponsors