Responsive Height Design -レスポンシブを高さの観点から、Webサイトやスマホアプリの実装で役立つテクニック
Post on:2020年11月19日
レスポンシブ対応と言うと、通常は幅、水平方向のサイズのバリエーションですが、最近では高さ、垂直方向のサイズに対するニーズも高まっています。スマホではさまざまな高さのサイズがあるだけでなく、横向きのランドスケープもあります。またデスクトップでもブラウザをスクリーンいっぱいの高さにしているとは限りません。
レスポンシブを高さの観点から考慮した、Webサイトやスマホアプリの実装で役立つCSSのテクニックを紹介します。
Responsive Height Design
by Ahmad Shadeed
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
Responsive Height Design!なぜ、このようなタイトルにしたのだろうと思うかもしれません。Responsive Web Designという言葉は、複数のデバイスのサイズ(特にビューポートの幅)をチェックすることとしてよく知られています。
わたし達制作者はいつも、幅を小さくしたり大きくしたりして水平方向のテストはしますが、高さを変えて垂直方向のテストをするという配慮はほとんどありません。ブラウザの高さを変更する必要が本当にあるのか? 私はこの記事でそれを解説したいと思います。
Webサイトの実装に取り組む際、実際のデータに依存せずに仮定を立てることはよろしくありません。水平と垂直の両方向でテストを実施することは非常に重要です。
なぜ高さに対してテストするのか
よい質問です。事例やユースケースを見る前に、どのような問題を探っていくのかをイメージできるよう解説します。
デザイナーにとって意味のない仮定は、Webサイトのデザインを台無しにする要因の一つです。例えば、ユーザーがスクリーンの幅と高さをフルに使用してWebサイトを閲覧すると仮定することは正しくありません。むしろ、最悪の事態を想定する必要があります。
左: 幅と高さをフルに使用して閲覧、右: 実際はフルにしない人もいる
この意味が分かりますか? 実際には、すべてのユーザーが期待どおりにブラウザを使用しているわけではありません。私は実際にブラウザの高さを小さくすると、見栄えが悪くなるサイトを見たことがあります。
デベロッパーツール
ビューポートの高さを変更する方法は、ブラウザのサイズを(垂直方向に)変更するだけではありません。ブラウザのデベロッパーツールを開くと、ブラウザの高さから垂直方向のスペースを占めることもあります。
デベロッパーツールを開いたところ
これにより、デザインが破綻したり、想定していなかった問題が明らかになることがあります。上図の「Viewport height」はビューポートの高さを示しています。小さなノートパソコンでは、Webページのごく一部しか表示されません。
本当の問題点は、ビューポートの高さが小さいときにユーザーエクスペリエンスを向上させることができるかということです。
はい、それは可能です。理論はもういいので、CSSで垂直方向にについて考えるテクニックを見てみましょう。
CSSで垂直方向を考慮する
デザイナーやデベロッパーの中には、デザインの幅のバリエーションだけに注目し、ビューポートの高さに対するテストの重要性を後回しにしている人もいます。
例えば、あなたはページのデザインに取り組んでいて、特定のコンポーネントが異なるビューポートの幅でどのように表示されるかを説明したとします。しかし、高さについても説明しましたか?
ビューポートの異なる高さでどのように表示されるか
上図では、ビューポートの高さに応じてレイアウトが変化するナビゲーションがあります。ナビゲーションはスクリーンいっぱいに表示されており、サイズが小さい場合はフォントのサイズとスペースが小さくなります。さらにサイズが小さい場合(iPhone 5など)は、2カラムのグリッドで表示されます。
高さのバリエーションを考えることは、しばしば脇に置かれたり完全に忘れ去られ、誰かがバグとして報告した時に初めて気がつくことになります。
CSSでは主に2つの異なるテクニックで、これに対応できます。
- 垂直のメディアクエリ
- ビューポート単位
垂直のメディアクエリ
すでに知っていると思いますが、CSSでは幅のメディアクエリを使用できます。
1 2 3 4 5 |
@media (min-width: 700px) { .element { /* do something.. */ } } |
そしてあまり見かけないかもしれませんが、ビューポートの高さをチェックする垂直のメディアクエリも使用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@media (min-height: 500px) { .element { /* do something.. */ } } /* or */ @media (orientation: landscape) { .element { /* do something.. */ } } |
ビューポート単位
ビューポート単位を使用することで、ユーザーによりよいエクスペリエンスを提供することができます。例えば、ビューポートの高さに基づいて要素間の垂直方向のスペースを調整できます。
1 2 3 |
.hero__title { margin-bottom: calc(10px + 5vh); } |
ビューポート単位で、垂直方向のスペースを調整
上図をiMac 27インチのような大型ディスプレイで見れば、それはそれで楽しいかもしれませんが、ビューポートの高さが大きすぎます。ありがたいことに、margin-bottonが大きくなりすぎないように調整するテクニックが2つあります。
- メディアクエリ
- CSSの比較関数
もちろん、1つ目の方法(メディアクエリ)の方がブラウザにサポートされています。スクリーンサイズが大きい場合に、margin-bottomに最大となる値を定義しておきます。
1 2 3 4 5 |
@media (min-width: 2200px) { .hero__title { margin-bottom: 40px; } } |
2つ目の方法は、CSSのclamp()関数を使用することです。clamp()関数を使用すると、最小マージンを10pxに、最大マージンを40pxに、その間はブラウザに任せるということができます。
1 2 3 |
.hero__title { margin-bottom: clamp(10px, 5vh, 40px); } |
CSSのビューポート単位と比較関数について詳しく記事にしたので、参考にしてください。
次のセクションでは、垂直のメディアクエリのさまざまなユースケースについて解説します。
垂直のメディアクエリの使用例
コンテンツのオーバーラップ(重複コンテンツ)
この例では、見出しとイラストのあるヒーローセクションがあります。ヒーローセクションの高さは100vhで、ビューポートの高さの100%に相当します。
コンテンツのオーバーラップ
ビューポートの高さが大きければ、見栄えはよいです。高さが小さくなると、ヒーローセクションの高さはイラストやテキストのコンテンツを表示するのに十分ではありません。その結果、ページ上の他のセクションと重なってしまいます。
ビューポートの高さが小さくなると、次のセクションと重なる
ヒーローセクションが次のセクションとどのように重なっているかに注目してください。これは垂直方向に十分なスペースがあるので起きている現象です。
HTMLとCSSを見てましょう。
1 2 3 4 5 6 |
<div class="hero"> <div class="hero__wrapper"> <div class="hero__content"><!-- content --></div> <img class="hero__thumb" src="figure.png" alt="" /> </div> </div> |
1 2 3 4 5 6 7 8 |
.hero { height: 100vh; } .hero__thumb { flex: 0 0 550px; width: 550px; } |
この問題を解決するための解決策は次のとおりです。
- イラストにwidthだけでなく、固定サイズ(widthとheight)を定義します。heightがない場合、問題は解決しません。
- ビューポートの高さが700pxを超える場合にのみ、height: 100vh;を適用します(メディアクエリの値はコンテキストに応じて異なります)。
1 2 3 4 5 6 7 8 9 10 11 |
.hero__thumb { width: 400px; height: 300px; object-fit: contain; /* 画像の圧縮表示を避けるため */ } @media (min-height: 700px) { .hero { height: 100vh; } } |
両方を組み合わせると、より強力なソリューションを実現できます。
1 2 3 4 5 6 7 8 9 10 11 |
.hero__thumb { width: 400px; height: 300px; object-fit: contain; /* 画像の圧縮表示を避けるため */ } @media (min-height: 700px) { .hero { height: 100vh; } } |
垂直のメディアクエリを使用する例を見ましたが、イラストのサイズを制限したとしても、テキストについては同じことができない可能性があるので、100vhを使用するのは危険かもしれません。テキストが長くなってしまうと、また同じ問題が発生してしまいます。
下図をご覧ください。
テキストが長いと、次のセクションと重なる
これを解決するには、heightの代わりにmin-heightを使用します。これで、コンテンツが長くなっても高さが拡大され、オーバーラップ(重複)がなくなります。
1 2 3 4 5 |
@media (min-height: 700px) { .hero { min-height: 100vh; } } |
固定ヘッダ
ヘッダをスクロール時に固定させることは悪いことではありませんが、垂直方向のスペースだけで十分に固定されていることを確認する必要があります。
スクリーンの高さが小さいと、固定ヘッダが邪魔になる
上図はランドスケープモードでの表示です。ヘッダが垂直方向にスペースを取り過ぎていることに注目してください。それはユーザーにとって本当に役立ちますか?
ほとんどの場合、答えはノーです。
わたし達デベロッパーは、垂直方向のメディアクエリを使用することで、これを改善できます。
1 2 3 4 5 |
@media (min-height: 700px) { .site-header { /* position: fixed or position: sticky */ } } |
これにより、ヘッダはランドスケープモードで固定されません。
重要度の低い要素を非表示にする
このパターンはTwitterで気がつきました。アイデアは、垂直メディアクエリとPriority+のパターンを組み合わせるというものです。
ビューポートの高さが小さい場合、重要度の低い要素を非表示に
ビューポートの高さが変更されると、重要度の低い要素(ブックマークとリスト)は削除され、「More」内に追加されます。これは垂直メディアクエリに適したユースケースです。
1 2 3 4 5 6 7 8 9 |
.nav__item--secondary { display: none; } @media (min-height: 700px) { .nav__item--secondary { display: block; } } |
そして、これが実際のTwitterの実装です。
I like the idea of reducing space based on the viewport height.
Here is how Twitter implemented this:
1- Reduce the space to 0 instead of 4px between each nav item.
2- Remove "bookmarks" and "lists" and append them to the more menu.Lovely 😍 pic.twitter.com/bjGxXRFLfS
— Ahmad Shadeed (@shadeed9) September 29, 2020
ナビゲーションの間隔を狭くする
このユースケースは上記と関連しています。垂直ナビゲーション(サイドバーも)があり、ビューポートの高さが小さい場合、ナビゲーションの各アイテム間の垂直方向のスペースを少し狭くすることができます。これにより、全体的なデザイン性を少し高めることができます。
各アイテム間の垂直方向のスペースを少し狭くする
1 2 3 4 5 6 7 8 9 10 11 |
.nav__item { padding-top: 4px; padding-bottom: 4px; } @media (min-height: 700px) { .nav__item { padding-top: 10px; padding-bottom: 10px; } } |
動作のアニメーションを用意しました。
ビューポートの高さに応じて変化するアイテム間のスペース
スペースだけでなく、さらにフォントのサイズも少し小さくすることもできます。そしてさらに垂直方向のスペースが生まれます。
ヒーローセクションの間隔を狭くする
ヒーローセクションには、快適に見えるための十分なスペースを与えるために垂直方向のスペースが必要です。このスペースをビューポートの高さに応じて狭くすることができます。
垂直方向のスペースを少し狭くする
1 2 3 4 5 6 7 8 9 10 11 |
.hero { padding-top: 24px; padding-bottom: 24px; } @media (min-height: 700px) { .hero { padding-top: 40px; padding-bottom: 40px; } } |
モーダル コンポーネント
すでに知っているかもしれませんが、モーダル コンポーネントは少なくとも水平方向の中央に配置されることが期待されています。しかし、モーダルを垂直方向の中央に配置する必要があるかもしれません。もちろん可能ですが、コンテンツが変更されるとバグがより早く発生します。
どうしてでしょうか? 解説します。
完璧なコンテンツであれば、モーダルは下記のように表示されます。もちろん、これは問題ありません。
完璧なコンテンツであれば、モーダルは中央に配置される
1 2 3 4 5 6 7 |
.modal__body { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 500px; } |
しかし、コンテンツが長くなると、事態は変わります。
モーダルはスクリーン全体に垂直に表示され、ユーザーはスクロールすることができなくなります。
コンテンツが長くなると、スクロールすることさえできなくなる
この原因は下記の通りです。
- モーダルにheightが定義されていない。
- モーダルが垂直方向の中央に配置される(バグがより早く発生します)。
CSSを修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.modal__body { position: absolute; left: 50%; top: 3rem; transform: translateX(-50%); width: 500px; min-height: 200px; max-height: 500px; overflow-y: auto; } @media (min-height: 700px) { .modal__body { top: 50%; transform: translate(-50%, -50%); } } |
min-heightとmax-heightを使用していることに注目してください。min-heightはコンテンツが短くてもモーダルの見栄えをよくするためのもので、max-heightは固定の高さを与えるのではなく、特定の値で高さを制限するためのものです。
コンテンツが長い場合は、スクロールバーが表示される
終わりに
エクスペリエンスをデザインする時は、幅と高さの両方の観点から考えることをお勧めします。ブラウザのサイズを垂直方向に変更するのは奇妙に思うかもしれませんが、必ず報われます。
この記事では、垂直方向のテストがどのように重要であり、どのようにすればいいのかを解説し、最後にいくつかの使用例とユースケースを紹介しました。お役に立てば幸いです。
クレジット
私は電子ブックを書いています
CSSのデバッグに関する電子書籍を書いていることをお知らせします。
興味がある場合は、debuggingcss.comにアクセスして、本に関する最新情報を購読してください。
コメントや提案があれば、@shadeed9までお願いします。
sponsors