iPhone6対応のモバイルファーストなレスポンシブデザイン 完結編

2014/10/5 18336hit

今回はWebページをPC向けに最適化していきます。
既に前回までのページであらゆるコンテンツに合わせてレイアウト出来るようになっているのですが、大画面ではより大画面を活用した機能を追加することでユーザーのリソースをより適切に活用できると思います。

モバイルに比べてPCでは横方向に多くの情報を表示することが出来ます。
そこで情報を横に並べることで、1画面の情報量を増やして少ないスクロールで多くの情報を見ることが出来るようにします。
具体的にはメニューを左側に、画像は右側にレイアウトしていきます。

目次

前編 概念について
中編 ひな形をつくる
後編 ページを作る
・完結編 PCに対応する

media queryを使う

CSSのmedia queryを使うことでウィンドウサイズに応じた画面レイアウトを行うことが出来ます。

画面サイズが60em以上の幅が広い画面においてのみスタイルを定義するには以下の様な指定を行います。

@media screen and (min-width: 60em) {
}

この中で指定された内容は画面サイズが最低でも60em以上ある場合のみ適用されます。

media queryを使った場合の優先順位

CSSにおいてはより細かく指定している場合のほうが優先され、同じ優先順位の場合後に記載されている内容が優先されます。

<p id="red">foo</p>

というHTMLに

#red{
color:red;
}
p{
color:blue:
}

と指定した場合、pタグの設定より#redの方がより細かく指定されているため、fooは赤字になります。
参考4-1

ところが、media queryについては優先度が変わりません。

<p>bar</p>

に以下のようなCSSを指定した場合

@media screen and (min-width: 60em) {
p{
color:red;
}
}
p{
color:blue;
}

参考4-2
そのため、画面サイズを60em以上にしても文字色はblueのままです。
media queryを使用する場合は、上書きしたい定義より下に書くように注意が必要です。

p{
color:blue;
}
@media screen and (min-width: 60em) {
p{
color:red;
}
}

PCで以下のページを開いてウィンドウ幅を増減させてみてください。
画面幅がある程度を超えたところで文字色が赤に変わることがわかると思います。
参考4-3

記事を右側にずらす

位置を動かす

まずはサイドバーの領域を開けるために記事を右にずらします。
コンテンツをずらすにはmarginを使ったり、float:rightを使うなどの方法があるのですが、今回はposition:relativeを使ってみます。
relativeは元のデザインを元に位置を移動することができます。
left:20emとすると本来の場所から右に20em動きます。

@media screen and (min-width: 60em) {
article{
position:relative;
left:20em;
}
}

記事が右にずれました。ページから記事がはみ出して横方向のスクロールバーが表示されてしまいました。

参考4-4

記事をはみ出さないようにする

はみ出した記事20em文を画面内に押さえ込みます。
articleの右側にmarginを20em分設定することですべての記事を画面内に収めます。

@media screen and (min-width: 60em) {
article{
margin-right:20em;
}
}

記事が画面内に入りました。

参考4-5

ナビゲーションを左につける

幅を設定する

開いた20em分の余白にナビゲーションが入るようにナビゲーションの幅を設定します。

@media screen and (min-width: 60em) {
nav{
width:20em;
}
}

幅が設定されました。しかし、高さの指定はされていないため元のレイアウトの高さと同様記事の下に表示されてしまいます。

参考4-6

位置を設定する

navの位置を上げるためにposition:absoluteでtopを指定します。
absoluteは要素内の位置を指定します。
親要素のうちposition:static以外が指定されている項目を起点に位置を指定します。
今回のように親要素がすべてstaticだった場合はhtmlを起点に位置を指定します。

似た値にfixedというのもあります。
こちらを指定するとウィンドウが起点となります。
そのためスクロールしてもウィンドウ上の同じ位置に残り続けます。
スクロールしてもメニューは常に表示し続けたいという時などに便利です。

@media screen and (min-width: 60em) {
nav{
position:absolute;
top:4em;
}
}

navの余白が不要なためmargin:0を設定します。

@media screen and (min-width: 60em) {
nav ul{
margin:0;
}
}

メニューが左上に移動しました。
余白がなく左端に張り付いています。しかし、ヘッダーとの間に空白があってイマイチ落ち着きません。

参考4-7

ヘッダの高さを指定する

メニューの位置と合わせるためにヘッダの高さも4emとします。
固定化された高さの項目に対して中心の高さに文字を配置するにはheightと同じ値をline-heightに適用することで可能です。(コンテンツが複数行になる場合はこの方法は使えず、もうちょっと面倒なことが必要です)
paddingを0にしておくことも忘れないで下さい。

@media screen and (min-width: 60em) {
header{
height:4em;
line-height:4em;
padding:0;
}
}

メニューが左に表示されメニューであることが一目瞭然になったのでメニューという文字は消してしまいます。
レスポンシブデザインに置いては画面サイズによってコンテンツの量を変えないというのが大原則ですが今回はユーザーが読んでいる途中とならない量のコンテンツで他の環境に移動しても一貫性をとれるので例外です。

@media screen and (min-width: 60em) {
nav h2{
display:none;
}
}

メニューという文字が消えメニューがヘッダに張り付いて表示されるようになりました。

参考4-8

領域外をグリーンにする

position:absoluteは親要素と独立してしまうため、親要素に高さが反映されません。
そのため、もし記事よりメニューの高さが大きくなってしまった場合bodyは記事までの高さとなり、フッターの下にはグラデーションが適用されていないhtmlの背景色が表示されてしまいます。
そこでhtmlにフッターの色を設定しメニューによりはみ出した部分はフッターの背景色となるように設定します。

@media screen and (min-width: 60em) {
html{
background-color:#004d40;
}
}

参考4-9

画像を右に寄せる

記事内の画像を右に寄せてテキストが回りこむようにします。

floatで右に寄せる

画像を右に寄せるには.article_imageに対してfloat:rightを設定します。

@media screen and (min-width: 60em) {
.article_image{
float:right;
margin:1em;
}
}


floatの要素は親要素にレイアウトを反映させないため記事に対して画像が大きいとはみ出してしまいます。
そこで、sectionごとに最後のpの後ろにダミーの項目を作りclear:rightをします。
ダミーの項目はclear:rightによって、margin:rightの項目の下側に配置され、section全体の高さもダミー項目を含む場所まで伸びるようになります。

ダミー項目は

<div class="clear_right"></div>

のようにHTMLに記載してもいいのですが、すべての記事に一律に設定する必要が有ること、コンテンツというよりデザインの要素が強いことからCSSで設定することにします。
設定方法は下記のようになります

@media screen and (min-width: 60em) {
article section p:last-child:after{
content: "";
display: block;
clear: right;
}
}

ちょっと特殊な設定方法です
記事(article)の中に有る各記事(section)の、一番最後(:last-child)に有る段落(p)の後ろ(:after)に空のblock要素を定義してclear:rightさせています。

本文のほうが長い場合は本文のサイズに合わせて、画像のほうが大きい場合は画像に合わせて各記事の大きさが定まるようになります。

参考4-11

動作チェック

前回の記事の手法を使ってチェックツールにかけたあと、各テストをPCとスマートフォンで行っていきます。
HTML

<!DOCTYPE html>
<html>
<head>
<title>AndroidWear長期レビュー</title>
<link rel="stylesheet" href="page411.css" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta charset="UTF-8" />
</head>
<body>
<a href="/">
<header>
<h1>AndroidWear長期レビュー</h1>
</header>
</a>
<article>
<h2>ここがいい</h2>
<section>
<h3>アプリのデザインが綺麗</h3>
<img class="article_image" src="image1.png" srcset="image1.png 1x,image1@2x.png 2x,image1@3x.png 3x" width="300" alt="画像1" />
<p>全体的な動作に関してはSmartWatch2に比べてかなり滑らかで、アニメーションの使われ方も自然でなかなか良く出来ています。<br>
SmartWatch2は、このあたりのデザインを全くやっておらずアニメーションも皆無だったのでかなり衝撃を受けました。</p>
<p>タッチパネルの精度もSmartWatch2よりかなり良くなっています。<br>
全体的に新しいものを使っているんだ という感覚が強いです。</p>
</section>
<section>
<h3>アプリを作るのが楽</h3>
<p>コレ大事だと思います。Notificationを使ったアプリ開発は標準的なAndroidアプリで<wbr>
Notificationを作ったことがある人ならすぐに作ることが出来るレベルです。<br>
CustomActivityを使ったアプリにした所でAndroidStudioの使い方さえ知っていればそんなに難しくありません。<br>
SmartWatch2のアプリ開発のややこしい仕組みと比較して圧倒的にアプリが作りやすくなっています。</p>
<p>関連:ゼロから始めるSmartWatch向けアプリ開発 <a href="http://firespeed.org/diary.php?diary%3dkenz-1685">(1)</a><a href="http://firespeed.org/diary.php?diary%3dkenz-1689">(2)</a><a href="http://firespeed.org/diary.php?diary%3dkenz-1690">(3)</a><br>
関連:<a href="http://firespeed.org/diary.php?diary%3dkenz-1712">(コード有り)30分で作る 初めてのAndroidWearアプリ開発</a></p>
</section>
<section>
<h3>ホーム画面をカスタマイズできる</h3>
<img class="article_image" src="image1.png" srcset="image1.png 1x,image1@2x.png 2x,image1@3x.png 3x" width="300" alt="画像1" />
<p>SmartWatch2もバージョンアップにてカスタマイズ出来るようになりましたが、<wbr>
AndroidWearでは標準でホーム画面をカスタマイズできます。<br>
カスタマイズの範囲も大きいし、<wbr>いざとなれば自分でゼロから作ることも出来ます。<br>この差は大きい。</p>
</section>
<section>
<h3>通知が早い</h3>
<img class="article_image" src="image1.png" srcset="image1.png 1x,image1@2x.png 2x,image1@3x.png 3x" width="300" alt="画像1" />
<p>Notificationを使ってPushで送られてくるのでメールやFacebookのメッセージなどが着信後即効で届きます。</p>
<p>SmartWatch2はポーリングなので遅い時は数分遅れてしまいます。</p>
<p>特にSmartWatch2ではスマートフォンで既に見た内容が遅れて届いたりするのがイマイチな感あります。</p>
<p>ここはFacebookやGmailが直接作ったアプリが提供されているAndroidWearとSony製のSmartWatchの大きな差にあるようです。</p>
</section>
</article>
<nav>
<h2>メニュー</h2>
<ul>
<li class="active"><p>AndroidWear長期レビュー</p></li>
<li><a href="http://firespeed.org/diary.php?diary%3dkenz-1715">ChromeCastショートレビュー</a></li>
<li><a href="http://firespeed.org/diary.php?diary%3dkenz-1670">Nexus5ショートレビュー</a></li>
<li><a href="http://firespeed.org/diary.php?diary%3dkenz-1669">ChromeBookPixel長期レビュー</a></li>
</ul>
</nav>
<footer>
<small>2014 copyright© Firespeed</small>
</footer>
</body>
</html>

CSS

body{
-webkit-text-size-adjust: 100%;
background: -webkit-gradient(linear, left top, left bottom, color-stop(1.00, #ccc), color-stop(0.00, #eee));
background: -webkit-linear-gradient(#eee, #ccc);
background: -moz-linear-gradient(#eee, #ccc);
background: -o-linear-gradient(#eee, #ccc);
background: -ms-linear-gradient(#eee, #ccc);
background: linear-gradient(#eee, #ccc);
color:rgba(0, 0, 0, 0.870588);
margin:0;
}
header{
background-color:#009688;
color:#fff;
padding:0.5em;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
}
h1{
font-size:150%;
margin:0;
}
a{
text-decoration:none;
}
h2{
color: rgba(0,0,0,0.5);
margin: 1em;
font-weight:100;
font-size: 100%;
}
h3{
font-size:130%;
font-weight:100;
color:#009688;
margin:0;
padding:1em 0 1.5em 0.5em;
}
article section, nav ul{
background-color:#fff;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
margin:0.5em 0.5em 1em 0.5em;
padding-bottom:2em;
}
article a{
display:inline-block;
padding:0.5em;
}
article section p{
padding:0.5em 1em;
}
.article_image{
display:block;
margin:auto;
max-width:100%;
}
nav ul{
padding:0;
}
nav li{
list-style:none;
margin:0;
}
nav .active p{
background-color:#4db6ac;
color:white;
font-weight:bold;
}
nav .active p, nav a{
border-bottom:1px solid #eee;
margin:0;
padding:1em;

}
nav a{
display:block;
background-color:#fff;
color:#009688;
position:relative;
transition-duration:0.4s;
top:0px;
-webkit-tap-highlight-color:rgba(178,223,219,0.4);
}
nav a:hover{
top:-2px;
transition-duration:0.2s;
box-shadow: 0 3px 8px rgba(0,0,0,0.4);
}
footer{
text-align:center;
background-color:#004d40;
color:#fff;
padding:1em;
margin-top:4em;

}
@media screen and (min-width: 60em) {
html{
background-color:#004d40;
}
header{
height:4em;
line-height:4em;
padding:0;
}
article{
position:relative;
left:20em;
margin-right:20em;
}
nav{
width:20em;
position:absolute;
top:4em;
}
nav ul{
margin:0;
}
nav h2{
display:none;
}
.article_image{
float:right;
margin:1em;
}
article section p:last-child:after{
content: "";
clear: right;
display: block;
}
}


以上でPC対応は終わりです。
今回はメニューを固定にして記事を可変にしています。
これは最も伝えたい主要なコンテンツに最大限のサイズを与えたいというのと、メニューのコンテンツ量は大きく増減しないという前提に基づいています。
例えばwidthを%指定することにより、メニューと記事のどちらもサイズに合わせて可変にすることも出来ます。

@media screen and (min-width: 60em) {
html{
background-color:#004d40;
}
header{
height:4em;
line-height:4em;
padding:0;
}
article{
float:right;
width:70%;
}
footer{
clear:right;
}
nav{
width:30%;
}
nav ul{
margin:0;
}
nav h2{
display:none;
}
.article_image{
float:right;
margin:1em;
}
article section p:last-child:after{
content: "";
clear: right;
display: block;
}
}

参考4-12

今回作ったパターンはスマートフォン向けとPC向けの2パターンだけですが、同じ要領で複数のパターンを作って、スマートフォン、タブレット、ノートパソコン、デスクトップ向けに別のパターンを適用することも出来ます。

今回のデザインの要因や注意点

デザインがシンプルすぎるのではないか

ブランドイメージを訴求したいトップページではもっと複雑なデザインが要求されることもあると思います。
しかし、レスポンシブデザイン全体で重要な機能にフォーカスするためにそれらの説明は省略しました。

今回伝えたかったのは前編で紹介した雛形のデザインと、
ユーザーの環境によってコンテンツ量を変えない、
ユーザー環境に合わせた最適なデザインとするためにコンテンツを可変に余白を固定にするという3点です。
そこにフォーカスするためにあえて多くの説明を省かせていただきました。

あの機能が紹介されていない理由は?

一般的にレスポンシブデザインのテクニックとして紹介される定番テクの多くを紹介していません。
今回はそれらの細かなテクニックの前に、レスポンシブを始めるのに必要な考え方に注力させていただきました。

JavaScriptがないけれど使っちゃダメなのか

今回はJavaScriptを一切使っていません。これも主な理由は説明を少なくしたかったからです。

HTMLデザインの考え

HTMLはできるだけシンプルに保つようにしました。
そして見た目の要因を最小にしています。
特にdivやspanの多用は後々のレイアウト修正での保守性が下がることがあるので注意です。
ただし、目的は保守性を保つためであり、divやspanを使ったほうがシンプルになる場合は躊躇せずに使ったほうがいいと思います。

旧ブラウザの互換性

影を落としたりグラデーションなど一部のスタイルは古いブラウザで正しく描画されない事があります。
それらのデザインの中にはJavaScriptなどによって再現できるものもあります。ただ私としてはそこまでしないほうがいいんじゃないかなと思います。
というのも、古いブラウザを使っている人はPCも古い可能性があります。
そういうPCではJavaScriptなどの重たい処理が負担になることがあります。
ユーザーの利用形態を考えると、古いブラウザーではそれなりに、新しいブラウザーではより良く表示できたほうがいいように思えます。

元の発想はアクセシビリティ

私がこの手のデザインを考え始めたもともとのきっかけはアクセシビリティからでした。
スクリーンリーダーを使う場合、HTMLの順番はとても大事になります。
視力の悪い人がフォントサイズを大きくした時に、正しくレイアウトが継続されることを目指したのがコンテンツのサイズを可変にし、余白を固定にする方法です。
その後Android版Webサイトの開発などでこれらの方法がスマートフォンでも有効であることに気が付きました。
計測はしていないですがSEO的にも伝えたいコンテンツが先にある方が有利になるのではないでしょうか

---
今回の連載はこれにて終了です。
偉そうに書いた割には基礎的なことばかりで申し訳ないのですがiPhone6の登場でWebデザイン界隈から悲鳴が上がっていたので解決策の一つとして提案させていただこうと思いました。

前:iPhone6対応のモバイルファーストなレスポンシブデザイン 後編 次:Android Lollipopの概要

関連キーワード

[iPhone][Android][モバイル][HTML5][IT]

コメントを投稿する

名前URI
コメント