未知の端末に対応するレスポンシブデザイン

#はじめに#
##多様化する環境##
iPhone6とiPhone6 plus、iPad proの登場によりiOSデバイスの画面サイズが一気に増えました。
次は4インチのiPhoneが追加されるという噂もあります。
Androidではそれ以上に多様な解像度の端末が発売され今後も増えていくことが予想されます。
Windowsタブレットの小型化も見逃せません。
さらに今後はTVやタブレット、カーナビなど様々なデバイスがWebにアクセスしてくるようになります。

以前のように特定の画面サイズをターゲットにしてWebサイトのデザインを行うのは難しくなっています。
現在ではあらゆる解像度や画面サイズで最適なWebデザインを行う必要があります。
##最適とは##
最適というのは、小さな端末でも見やすく、大きな端末では、大きさを活かしてもっと見やすく表示できることを言います。
より大きなスマートフォンを持っている人はより多くの情報を見たいから携帯性を犠牲にしてそのデバイスを持ったわけなのでそれを活かして上げる必要があります。

多解像度への解決策として、最も解像度が低いiPhone3GS向けにデザインしてそれより大きな画面のデバイスは拡大したり、余白を付けて表示させるというのは最適なデザインとはいえません。（残念なことにこの手法はPC向けのWebサイトで広く使われています）

もちろん世の中に出回っているすべての端末に対して個別に最適化を行うことは出来ません。
そこで、あらゆる解像度、あらゆる画面サイズにおいても柔軟にレイアウトを変化させるレスポンシブデザインが注目されています。

#レスポンシブデザインはモバイルファーストで設計する#
レスポンシブデザインでサイトを作る手法としてPC用Webサイトを元にモバイルに向けて機能を削っていく方法と、モバイル用のWebサイトを元にPCに向けて機能を追加していく方法の2つがあります。
もし、新規で開発するなら後者をおすすめします。複雑なサイトから機能を削っていくより、単純なサイトに機能を足していくほうが楽だからです。

#考え方#

##コンテンツについて##
###コンテンツ量を絞り込む###
より画面が小さく、より利用時間の短いモバイルではページを見る時間も限られます。
そこでまずは伝えるべきコンテンツを絞りこみましょう。

###ページ数を抑える###
主にガラケー向けサイトではページを細かく分割する方法が取られました。
これは当時のメモリーが少ない端末に最適化された方法でした。

ところが、最近のスマートフォンではPCで見ているページをスマートフォンで見たり、逆にスマートフォンで見ていたページをPCで見るような端末間でURLを共有する機能を持ったブラウザが増えています。
PCでは1ページで表示されるものがスマートフォンでは複数ページにまたがる場合、PCと携帯でページ数が異なると厄介な問題が発生します。
今では一昔前のPCと同程度のメモリーとブロードバンドと言うにふさわしい帯域が確保されているため、無理にページを分ける必要はなくなりました。

###端末ごとにコンテンツを変えない###
UserAgentや画面解像度に応じて変化を起こして良いのはナビゲーションの手法やレイアウトだけです。
主要なコンテンツやページ数を分けたりしてはいけません。

PCでコンテンツを途中まで見て、続きをスマートフォンで見ようとした時にコンテンツがなくなっていては困ります。
端末に応じた最適なUIを提供しながら、ユーザーには「同じものを見ている」という感覚を持たせなければいけません。

##HTMLについて
###見た目に関するタグは使用しない。
HTML上で見た目を直接指示するタグ（FONTタグなど）は使用しないようにします。
HTML5上では見た目を指定するタグのほとんどが非推奨になっているのでw3c validatorを使って正しいHTML5になっていることを確認するのが簡単です。

###コンテンツに優先順位を付けて優先度が高い順に記載する。
従来はHTML内のコンテンツはしばしばレイアウトの順番に依存していました。
例えば逆Lレイアウトだとこんな順番でHTMLに書かれることが多かったです。
![ヘッダ、サイドメニュー、コンテンツの順](https://qiita-image-store.s3.amazonaws.com/0/17830/2b826041-d1da-7288-b4a6-28d7f67e5b7d.png)
しかし、この方法では本来一番伝えたいはずのコンテンツがHTML上一番最後になってしまいます。
そこで、以下のように順番を入れ替えます。
![ヘッダ、コンテンツ、サイドメニューの順](https://qiita-image-store.s3.amazonaws.com/0/17830/aa73cfb7-3621-ee65-fb73-0b40be3ecd5f.png)

ヘッダに表示する内容によってはコンテンツ、サイドメニュー、ヘッダの順になるかもしれません。
いずれにしても大事なのは画面上の見た目ではなく、「どの順番で見せたいか」というコンテンツの意味に依存しているということです。

##見た目について##
###同じブランドイメージを維持する###
スマートフォンでアクセスした時にスマートフォンのネイティブアプリのように見せかけるサイトが有りますが、もしそのサイトがPCからもアクセスしうるならユーザーの「同じものを見ている」という感覚を阻害するのでPCとスマートフォンが同一の印象をもたせられているか確認してください。
###固定幅のデザインをしない###
コンテンツの幅を800pxに固定し残りを余白にするサイトがありますが、これでは特定解像度に依存してしまい多様な端末に最適なデザインを提供しづらくなってしまいます。

そこで、コンテンツの幅は固定せずに画面幅に応じてレイアウトを行います。
隙間の幅を固定してコンテンツの大きさを可変にするレイアウトを心がけます。
実際にデザインを組んでみると隙間がしっかりデザインされているサイトはコンテンツが間延びしてもしっかり綺麗に見えます。

###レイアウトを可能な限り流用する。###
レスポンシブなデザインは従来の固定幅のデザインに比べて作業工数が増大してしまいます。
ページごとのレイアウトはトップページとサブページの2種類のみにするなどレイアウトのパターンを減らすことで、レスポンシブでありながら工数の増加を最低限に抑えることが出来ます。

##機能面について##
###機能を盛り込み過ぎない###
機能は盛りこむほどトラブルの種になります。
何気ない気持ちで追加した機能が別の端末で問題を引き起こすことがあります。

###マウスでもタッチパネルでもアクセスできるようにする###
タッチパネルにはマウスと違った機能が求められます。
マウスオーバーしてマウスカーソルのアイコンが変わったりしないため、リンクはより具体的に示してやる必要があります。また、リンクなどの部分は大きめにして他のリンクと距離を開ける必要があります。
UserAgentをみてAndroidやiOSではタッチパネルに最適なデザインを提供するという手法が取られていましたが、タッチ可能なPCも増えている中ではあらゆる端末でタッチパネルでもアクセスできるように作ってやるほうが良いでしょう。
#HTMLの雛形を作る#
それではレスポンシブなWebサイトを作るためにHTML5のひな形をつくっていきます。
よくあるHTML5の作り方だとこんな感じ。

```html
<!DOCTYPE html>
<html>
    <head>
        <title>TITLE</title>
            <link rel="stylesheet" href="style.css" />
            <meta charset="UTF-8" />    
        </head>
    <body>
        <h1>TITLE</h1>
        CONTENT
    </body>
</html>
```

##文字が小さく表示される問題##
これをスマートフォンで開くととても文字が小さく表示されていまいます。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/7e3a5ad2-1350-a195-be38-c311439d741e.jpeg)
[ブラウザで見る](http://firespeed.org/lab/responsive/page101.html)

画面のピクセル数を表示するとこのようになります。
Nexus5の場合
![幅1000pxの画像が全て表示される](https://qiita-image-store.s3.amazonaws.com/0/17830/111e7aeb-f147-118f-cdee-127ee7b822a1.png)
iOSの場合
![幅1000pxの画像が980pxだけ表示される](https://qiita-image-store.s3.amazonaws.com/0/17830/208dcf3e-db86-aa7c-c65b-94529a496ccb.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page102.html)
Nexus5やiPhone5などのスマートフォンにおいてWebページをデフォルトで表示した場合、画面幅は980pxと想定して表示されます。
元のページ幅が980px以上ある場合、Nexus5ではページ幅にあわせて更に縮小されます。
一方、iOSでは元のページ幅にかかわらず980pxで表示されます。

幅1200pxの画像があった場合、Nexus5は次のように表示されます。
![幅1200pxの画像がすべて表示される](https://qiita-image-store.s3.amazonaws.com/0/17830/1b5cc320-aee3-defa-e4d3-e29fee18904c.png)
iOSでは次のとおりです。
![幅900pxのまで表示される](https://qiita-image-store.s3.amazonaws.com/0/17830/98dee735-415e-35b6-507f-ee5d78314161.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page103.html)

この振る舞いはiPhone登場当初の状況に基づきます。
当時は当然スマートフォン対応サイトというものが存在せず、ほとんどのサイトは幅800px程度の画面を持つPC向けにデザインされていました。
当時のiPhoneはディスプレイの横解像度が320pxしかなかったので、そのままではページの左上（ほとんどのWebサイトでページの左上にはロゴマーク等があるだけで、主要なコンテンツはなかった）だけが表示されてしまいます。
そこでiPhoneは幅980pxであるかのように振る舞い、それを320pxに収まるように縮小して表示することでページの全体を表示させ、興味があるコンテンツをユーザーが拡大して表示するという仕様になりました。
そのため、文字などがとても小さく表示されてしまいます。
スマートフォン対応サイトにおいては、この挙動が邪魔になるので明示的に縮小表示を行わないように指定する必要があります。
##view-portを指定する。##
縮小表示を行わないようにするにはview-portを指定します。
view-portとはディスプレイの幅が何ピクセルかのように振る舞うかという値です。前述のとおりデフォルトの値は980pxです。

これを以下のように明示的にdevice-widthと指定することでデバイスに応じたサイズとして振る舞う（つまり縮小処理を行わない）ようになります。

```html
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
```

device-widthで指定した値は実際の物理的なディスプレイサイズではなく、ピクセルサイズを考慮した推定解像度となるのに注意してください。
より高密度なディスプレイでは、低密度のディスプレイと見た目上の大きさを合わせるためにピクセル数をより少ないものとして振る舞いそれを拡大表示します。
例えば、Nexus5の場合、実際のディスプレイは幅1080pxですが、1/3である360pxとして振る舞い、それを3倍して表示します。
iPhone5の場合、幅640pxでx2なので640px/2=320px。
iPhone6の場合、幅750pxでx2なので750px/2=375pxです。
![Nexus5で幅1000pxの画像を表示しても縮小されず360pxまで表示されるようになった](https://qiita-image-store.s3.amazonaws.com/0/17830/4186d415-c0eb-783b-46d8-516960df17be.png)
<img  alt="iPhone5で幅1000pxの画像を表示しても縮小されず320pxまで表示されるようになった" src="https://qiita-image-store.s3.amazonaws.com/0/17830/32c4dbcb-3f7d-58c4-aef3-569fe7a12168.png">

そのあとに指定してあるscaleはユーザーによる拡大縮小をどのように取り扱うかを指定します。
`initial-scale`はページを開いた時の初期値、`minimum-scale`はどこまで縮小を許すか、`maximum-scale`はどこまで拡大を許すかです。
ここの指定はポリシーに応じますが、私はinitialは1、minimumについては幅がデバイスのサイズと一致させている関係上縮小を許さないように1、maximumはユーザーがコンテンツの一部をより詳しく見たいというニーズに適合させるため未指定（無制限）とするようにしています。
この場合、画面表示時はページが拡大縮小されずに表示され、そこから拡大はどこまでも許すが縮小は出来ないという挙動になります。

###余談その１ iPhone6(s) Plusの解像度###
iPhone6(s) Plusはハードウェア的にはNexus5と同じ幅1080pxなので360pxで表示されるべきなのでしょうが、実際には414pxが表示されます。
これは、iPhone6 Plus特有の挙動でOS自体が1242x2208pxのように振る舞い、それを1080x1920pxに縮小して表示することで対応しているために発生する問題です。
なぜこのような仕様になったのかは謎ですがこれはiPhone6 Plusのハードウェアに依存する問題でWebにかぎらずネイティブアプリにしてもiPhone6 Plus上ではピクセル通りの描画を行うことが出来ません。
作り手としては1242x2208pxでデザインする必要があり、ピクセルがボケるのはディスプレイの品質が悪いのだと諦めるしかありません。
<img width="414" alt="iPhone6s Plusで開くと414pxが表示される。" src="https://qiita-image-store.s3.amazonaws.com/0/17830/c53d5e7b-89aa-359e-14d9-e1c9acdc188f.png">

###余談その２ view-portに320を指定してはいけない###
ちょっと昔のスマートフォン対応サイトの作り方ではview-portに320を指定するというものがありました。

```html
<!DOCTYPE html>
<html>
        <head><title>TITLE</title>
                <link rel="stylesheet" href="style.css" />
                <meta name="viewport" content="width=320, initial-scale=1, minimum-scale=1">
                <meta charset="UTF-8" />        
        </head>
    <body>
        <h1>TITLE</h1>
        CONTENT  
        <img src="major.png" width="1200" height="1200" />
    </body>
</html>
```

これは初代iPhoneに合わせたサイズに指定するというもので、iPhone上では`width=device-width`っぽく振る舞います。
しかし、これではタブレットなどのより画面が大きなディスプレイにおいてスマートフォンのレイアウトのまま画面が拡大されて文字が異常に大きく表示され見づらくなってしまうという問題がありました。
最近のAndroid版ChromeやiPhone6、iPhone6plusの場合は320を指定してあっても無視して`device-width`のように表示するようですが、紛らわしいので`device-width`を指定するべきでしょう。
#CSSのひな形をつくる#
`width=device-width`を指定してもスマートフォンにはまだ問題があります。
スマートフォンでは画面を回転させた時に画面の縮尺が変わってしまうものがあります。
これはよこはばを合わせてデザインすることに応じたものなのでしょうが、実際には画面の回転に応じて文字サイズが変わってしまったりしてあまり見やすくない事があります。
そこでスタイルシートに以下のように設定します。

```css
body{
        -webkit-text-size-adjust: 100%;
}
```

これを指定することで画面を回転させてもページの拡大率が変わらなくなります。

#完成したひな形#
ということで出来上がったひな形は以下のとおり
##HTML##

```html
<!DOCTYPE html>
<html>
        <head>
                <title>TITLE</title>
                <link rel="stylesheet" href="style.css" />
                <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
                <meta charset="UTF-8" />        
        </head>
    <body>
        <h1>TITLE</h1>
        CONTENT  
    </body>
</html>
```

##CSS##

```css
body{
        -webkit-text-size-adjust: 100%;
}
```

これがレスポンシブなモバイルサイトを作る基礎となります。

#サイトを作る#
それではひな形をつかって実際にWebサイトを作ってみましょう。
##全体的な構図##
ページの基本的なレイアウトはよくあるヘッダ、ナビゲーション、複数の記事、フッターからなるページとします。
記事はそれぞれタイトルと画像を持ち、大画面上では逆L型レイアウト＋フッタからなる逆コの字型レイアウト、小さな画面では縦に一列に並ぶレイアウトで表示します。
今回はモバイルファーストなので縦一列のレイアウトから作っていきます。

##優先度を付ける##
ユーザーに見て欲しい順番に優先度をつけます。
今回はヘッダ、各記事、ナビゲーション、フッターの順番で見て欲しいと想定し、その順番でHTMLを書きます。
HTMLに流し込む

##HTMLを作る##
HTMLは以下のようになりました。
コンテンツの内容は[Android Wear長期レビュー](http://firespeed.org/diary.php?diary=kenz-1774)からの流用です
HTMLについての細かな内容については後ほど解説します。

```html
<!DOCTYPE html>
<html>
  <head>
    <title>AndroidWear長期レビュー</title>
    <link rel="stylesheet" href="page301.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" alt="画像１" />
        <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" alt="画像１" />
        <p>SmartWatch2もバージョンアップにてカスタマイズ出来るようになりましたが、<wbr>
        AndroidWearでは標準でホーム画面をカスタマイズできます。<br>
        カスタマイズの範囲も大きいし、<wbr>いざとなれば自分でゼロから作ることも出来ます。<br>この差は大きい。</p>
      </section>
      <section>
        <h3>通知が早い</h3>
        <img class="article_image" src="image1.png" alt="画像１" />
        <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>
```

この状態でとりあえず、表示してみると以下のようになります。
PC
![kenz1779-301-pc.png](https://qiita-image-store.s3.amazonaws.com/0/17830/39558169-47f0-fb53-c904-9492b39786bd.png)
Nexus5
![kenz1779-301-nexus5.png](https://qiita-image-store.s3.amazonaws.com/0/17830/979f3657-d652-bb2e-958a-ebee74e71848.png)
Nexus7
![kenz1779-301-nexus7.png](https://qiita-image-store.s3.amazonaws.com/0/17830/443f943b-5f8e-aff5-9f62-9c5163ebc3ed.png)
iPhone5
<img alt="kenz1779-301-iphone.png" src="https://qiita-image-store.s3.amazonaws.com/0/17830/f818b495-fb8b-b3f9-7313-50ccb1716f81.png">
[ブラウザで見る](http://firespeed.org/lab/responsive/page301.html)
それぞれ表示されている文字数が違ったり、見た目がとてもシンプルだったりしますが、PCでもスマートフォンでもタブレットでも画面解像度やOSがバラバラなのに、すべての端末で「きちんと見る」事ができていることに注目してください。文字が小さすぎたり、大きすぎることもないし、タイトルやリンクもそれと認識可能です。

これはそもそもスタイルが適用されていないHTMLはレスポンシブであるということに基づきます。
HTMLに視覚的な要素がなければ、文書構造に基づきそれぞれのブラウザが適切にデバイスへ最適化された状態でレンダリングしようとします。

このデザインを元にCSSで装飾を行っていきます。
##CSSを作る##
ヘッダのデザイン

ヘッダは文字サイズを本文の1.5倍とし背景色を付け文字色を設定します。
本文には薄いグレーの背景色をグラデーションしておきます。
背景色を設定するときは必ず文字色もセットで設定する癖をつけておくといいです。

今回のデザインはMaterial Designに則ってはいませんが、配色は[MaterialDesignのColor](http://www.google.com/design/spec/style/color.html)で提案されている配色を流用しました。
###帯のデザイン###
CSSに以下のように設定します。

```css
@charset "UTF-8";
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);
}
header{
        background-color:#009688;
        color:#fff;
}
h1{
        font-size:150%;
}
a{
        text-decoration:none;
}
```

ヘッダに背景色が設定されました。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/d0614d51-8d50-8bfc-798c-af7f2cc65ed6.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page302.html)

###余白の設定###
ヘッダの帯の部分に色を付けることが出来ましたが、余白がついてしまっています。
これは　ブラウザ標準のスタイルシートのh1やbodyにmarginが設定されているためです。
取り除くためには2つの方法があります。
#### 1. bodyのmarginに固定値を入れてh1にその値のマイナスを入れる。####
この方法ではヘッダ部分だけマージンがなくなりそれ以外はマージンがついた状態になります。

```css
body{
        margin:8px;
}
h1{
        margin:-8px;
}
```

#### 2. h1とbodyのmarginをゼロにする。####
この方法ではすべてのコンテンツのマージンがなくなり画面端にくっつくため、必要に応じて個別にマージンを指定する必要があります。
今回はこの方法を使用します。

```css
body{
        margin:0;
}
h1{
        margin:0;
}
header{
        padding:0.5em;
}
```

帯の周りの枠がなくなり画面にピッタリと表示されるようになりました。
タイトルの余白はpaddingで再現しています。

![](https://qiita-image-store.s3.amazonaws.com/0/17830/852cd3f5-6e32-783a-69df-c9282ef8838a.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page303.html)

###ヘッダに影をつける###
ヘッダが浮いて見えるように影をつけておきます

```css
header{
        box-shadow: 0 2px 5px rgba(0,0,0,0.3);
}
```

些細な点ですがデザインがよりリッチになりました。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/f7db1003-2785-966f-c7e8-bf57d372f260.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page304.html)

###余談その3 モバイルにmarginは必要か？###
これは難しい問題です。画面の限られたモバイル端末に置いては僅かなマージンすらコンテンツ領域に活用すべきかもしれません。一方でマージンのないコンテンツは見やすさの点で劣ります。
これについては明確な答えはないのですがコンテンツの内容や想定するユーザーによって異なってくると思います。
コンテンツの量が少なければ余白が大きくても問題有りませんし、文書を区切る余白は長文を見やすくするためにも必要です。
一方で写真や動画などは少しでも大きく見せたほうがうれしいでしょう。

###記事のデザイン###

####記事全体のタイトル####
全体のタイトル部分は各記事のタイトルほど目立たせなくていいのでマージンと文字サイズ、文字色だけ設定します。

```css
h2{
        color: rgba(0,0,0,0.5);
        margin: 1em;
        font-weight:100;
        font-size: 100%;
}
```

###各記事のタイトル###
各記事のタイトルには文字を大きくしつつ色もつけます。
レイアウトに制約のあるスマートフォンサイトでは極端なジャンプ率が使いづらいため色や罫線などを使い適切に装飾する必要があります。

```css
h3{
        font-size:130%;
        font-weight:100;
        color:#009688;
        margin:0;
        padding:1em 0 1.5em 0.5em;
}
```

###記事を区切る###
各記事の区切りが明確にわかるように、それぞれの記事が別の用紙に描かれているように表現します。
各記事の背景色を白にして、marginで隙間を付け、影を落とします。
さらに各記事の最後に大きめのpaddingをつけることで記事間に区切りを入れています。

```css
article section{
        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;
}
```

###画像の配置###
画像は中央寄せします。
親要素でtext-align:centerを指定するかdisplay:blockにしてmarginをautoに設定すると画像を中央寄せできます。
画像サイズが記事の枠を超えた場合に自動的に縮小されるようmax-width:100%を指定しておきます。
この指定をすると画面幅が狭い端末では自動的に画像が縮小されます。

```css
.article_image{
        display:block;
        margin:auto;
        max-width:100%;
}
```

###文書部分の余白を設定###
記事の文書部分に余白を設定します。
縦方向は上と下のmarginが足されるため左右のmarginの半分の値としています。

```css
article section p{
        padding:0.5em 1em;
}
```

![](https://qiita-image-store.s3.amazonaws.com/0/17830/55a88086-11f0-bd9c-3d79-856685842905.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page305.html)

鍵となるのは横方向はめいいっぱい使うこと、しかし消してはみ出さないこと
縦方向はある程度長くても大丈夫　ということです。

###画像が荒れている問題###
スマートフォンで画像をよく見るとなんだか荒れています。
これはスマートフォンがページを2倍や3倍に拡大している事に問題があります。
![その結果ピクセルが目立ち画像が荒れます。](https://qiita-image-store.s3.amazonaws.com/0/17830/ce806373-b79f-85a3-3184-949119bd59f8.png)

これの解決策は3つの方法があります。

#### 1. widthやheightを指定しそこに6倍の画像を表示する。####
例えば先ほどの画像は300x200pxなのでその6倍1800x1200の画像(image2.png)を用意して設定してみます。

```html
<img class="article_image" src="image2.png" width="300" height="200" alt="画像２" />
```

[ブラウザで見る](http://firespeed.org/lab/responsive/page306.html)

この方法、たった１つのファイルを元に、x3なら1/2、x2なら1/3、x1.5なら1/4、等倍なら1/6に縮小することでどの密度でもくっきり見せることが出来るというメリットが有ります。

しかし、問題点も大きいです。
まず、6倍の画像が用意できるかという問題。
幅800、高さ600pxの画像の場合は、それぞれを6倍すると4800x3600pxになり1728万画素にもなります。

そして、ファイルサイズの問題。
画像サイズが36倍にもなるのでx1端末の場合94%は無駄なデータになってしまいますし、現状最も細かく画像を表示するx3端末でさえ75%もデータを無駄にしてしまいます。
現実的には縦横2倍程度の画像を用意して、多少のデータの無駄さやx3でのぼやけを許容するというのが現実的な対策かと思います。

#### 2. srcsetを使う ####
srcsetを使うことで画面密度ごとに複数の画像をセットできます。
以下のように元の画像、元の画像を縦横2倍にした画像、元の画像を縦横3倍にした画像の3つのファイルを用意します。
今回はわかりやすいようにそれぞれの画像を変えていますが実際にはx3の画像をもとに2/3倍した画像、1/3倍した画像を用意します
![](https://qiita-image-store.s3.amazonaws.com/0/17830/e438c605-d947-327b-18fc-30d5c2a4b665.png)![](https://qiita-image-store.s3.amazonaws.com/0/17830/8ec132ec-98d0-6d6f-52a2-a5a0cff5580d.png)![](https://qiita-image-store.s3.amazonaws.com/0/17830/ee5894c5-479c-3006-68ef-b8a668055caa.png)

imgタグのsrcsetを使用して以下のように設定します

```html
<img src="1x.png" srcset="1x.png 1x,2x.png 2x, 3x.png 3x">
```

こうすると、ブラウザが自動的にどのサイズの画像を取ってきたらいいかを判別して画面に描画します。
Nexus5
![x3が使われる](https://qiita-image-store.s3.amazonaws.com/0/17830/8f8deae3-50ab-a481-7f85-1e0ff177bbe3.png)
iPhone5
<img alt="x2が使われる" src="https://qiita-image-store.s3.amazonaws.com/0/17830/35bc1f3d-b88d-c5ef-1a9d-d32c58b9f2cf.png">
一般的なPC
![x1が使われる](https://qiita-image-store.s3.amazonaws.com/0/17830/39408e24-cd93-3082-c6df-a556aaa66f9a.png)

[ブラウザで見る](http://firespeed.org/lab/responsive/page307.html)

#### 3. SVGを使う####

ベクター画像であるSVGを使うことであらゆる画面密度に対応させることが出来ます。
ベクター画像が用意できることという敷居の高い問題がありますが、複数の画面密度を1つのファイルでまかないながらデータ容量も控えめになりますし、将来的に出てくるであろうx4やx5端末にも対応できる。　画面をズームしても対応可能など様々なメリットがあります。
SVGを使える場面は限られていますが、アイコンや会社のロゴのように簡単にベクターデータが手に入る場合は導入を検討してみるといいかと思います。
FirespeedではRSSのフィードアイコンがSVGで作られています。
[ブラウザで見る](http://firespeed.org/lab/responsive/page308.html)

関連：[InkScape入門 ハニカムビーを描く](http://firespeed.org/diary.php?diary=kenz-1377)
※注意 SVGでテキストを使うときはユーザーにフォントが入っていないと文字フォントが変わる可能性があるのでご注意ください。
文字のパス化によって回避することも出来ますが、その場合はフォントの著作権を確認して下さい。

今回は2番めのsrcsetを使います。

```html
     <img class="article_image" src="image1.png" srcset="image1.png 1x,image1@2x.png 2x,image1@3x.png 3x" width="300" alt="画像１" />
```

[ブラウザで見る](http://firespeed.org/lab/responsive/page309.html)
####余談その４ imageにmax-widthを設定する効果と弊害。####
画像ファイルには必ずwidthとheightを指定するというのは長い間常識でした。
しかし、max-widthを指定するときはheightを指定してはいけません。
この場合、幅が縮小されても高さはそのままを維持してしまい、画像が左右に圧縮されたように描画されてしまいます。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/7b61bd99-7370-372d-c84c-869f011dcef0.png)
Heithを指定しなかった場合、比率を保ったまま縮小されます。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/a98fb9b0-ae87-de31-a9c8-c378d88977cf.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page310.html)
もともと、widthとheightを指定しないといけない理由は画像が読み込めていない間にもレイアウトを完了させたいためです。
画像の比率を維持したまま縮小するためには、画像の読み込み終わった後で再レイアウトを行う必要があるため、widthやheightを指定する意味もなくなってしまいます。
もちろんこれにより画像読み込み後にページの再レイアウトが発生してしまうためレンダリングが遅くなってしまいます。
明らかにページの枠を超えないという場合や、ページの枠を超えても構わないからページの描画を早くしたいという場合は、max-widthは指定せずに従来通りhtmlのwidthとheightを指定します。

###リンクの設定###
タッチパネルにおいてはマウスほど精密な操作がしづらいためリンクを大きめにしておくと親切です。
今回のサイトのように記事の中で複数のリンクが連続するような場合は特に小さすぎるリンクが押しづらくなります。

リンクを大きくするにはaタグをinline-blockとしてpaddingを設定します。
marginはコンテンツの外として認識されるのでタップできず、paddingはコンテンツの中として認識されるのでリンクの対象となります。
今回はできるだけタップの面積を稼ぎつつレイアウトへの影響を最小にしたいのでmarginは指定せずpaddingのみを指定します。
![kenz1781-margin.png](https://qiita-image-store.s3.amazonaws.com/0/17830/ea43c4be-0b40-06ca-1eae-9035179187a8.png)

paddingを設定することでリンクの前後に空間が空き、リンクが含まれる行は行間がより開くようになります。
デザイン上は大きな制約を受けてしまいますが、ユーザーのことを考えると操作しづらくなるよりはマシかと思います。

```css
article a{
        display:inline-blodk;
        padding:0.5em;
}
```

![リンクの周囲にクリッカブルな領域ができる](https://qiita-image-store.s3.amazonaws.com/0/17830/df983b77-2ea4-1e79-0c5e-e1804d7b38a8.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page311.html)

###メニューのデザイン###

メニュー全体を記事と同様に影をつけていきます。
このように同じ意味の装飾を付けたい場合、個別にcssを定義するより前に定義した部分に適用したい項目を追加したほうが後々の修正で一貫性をもたせやすいので便利です。

```css
article section, nav ul{ /*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;
}
```

####リストの装飾を削除する####
リンクリストのデフォルトcssで定義されている余白やリストスタイルを無効化します。
デフォルトCSSの指定全てを削除して独自のレイアウトを設定するリセットCSSというテクニックがありますが、ブラウザ本来の持つレスポンシブさを犠牲にしてしまうので、今回のように必要な一部だけをリセットする手法のほうがいいかと思います。

```css
nav ul{
        padding:0;
}
nav li{
        list-style:none;
        margin:0;
}
```

####リンクの文字色を設定する####
記事ではリンクであることがわかりやすいようにデフォルトのリンク文字色を継承していましたが、メニューの場合サイトのデザインとの兼ね合いもあります。
そこで今回はリンクの色をヘッダの背景色と同様の緑にしてみます。
この色は記事のヘッダとかぶるため、現在のページを太字＋反転表示にしリンクが押せるということを直感的に伝わるようにしてみました。

```css
nav .active p{
        background-color:#4db6ac;       
        color:white;
        font-weight:bold;
}
nav a{
        display:block;
        background-color:#fff;
        color:#009688;
}
```

####リンクを大きくする####
記事と同様にリンクのpaddingを付けて押しやすくします。

```css
nav .active p, nav a{
        border-bottom:1px solid #eee;   
        margin:0;
        padding:1em;

}
```

![kenz1781-401.png](https://qiita-image-store.s3.amazonaws.com/0/17830/1f513d2d-7ad0-973b-11ac-ec958b2a0af8.png)

####押下時のリアクションをつける####
リンクが押された時にリンクが反応して押下可能であることを示します。
PCやAndroidではhoverを使うことができるので、hoverを使用しリンクが押されたらリンク全体が上に浮き上がったように見えるエフェクトを追加します。
リンクのpositionをrelativeにしてtopの値を変更することでボタンを若干浮かび上がったようにし、box-shadowを設定してより浮いている感じを演出します。

```css
nav a{
        position:relative;
        top:0px;
}
nav a:hover{
        top:-2px;
        box-shadow: 0 3px 8px rgba(0,0,0,0.4);
}
```

このままでは浮かび上がりが急になってギクシャクして見えるのでエフェクトにアニメーションを適用します。
アニメーションを適用するにはtransition-durationを設定します。

```css
nav a{
        transition-duration:0.4s;
}
nav a:hover{
        transition-duration:0.2s;
}
```

transition-durationはその値になるまでの時間を表します。
この場合、a:hover（浮かび上がるアニメーション）を0.2秒とし、a（落ちるアニメーション）を0.4秒としています。
アニメーションを適用する時にはアニメーションを目立たせたいがために動きを大きくしたり時間を長くしすぎないように注意することが大切です。
ユーザーにとっては動きが大きなアニメーションは追いかけるのが大変で、動きがゆっくりしたアニメーションには緩慢さを感じさせます。
特に、ユーザーの積極的に行った活動に対しては素早いレスポンスを返すことが気持ちのいいアニメーションとなります。
一方、ユーザーが消極的に行った活動に対しては多少ゆっくりにしても問題有りません。
そこで、今回はユーザーがボタンを選ぶ（積極的）時は0.2秒、ユーザーがボタンから離れる（消極的）時は0.4秒としました。

iOSデバイスの場合はhoverが使用できないので、-webkit-tap-highlight-colorを使用します。
-webkit-tap-highlight-colorを設定すると、カーソルがあたった時にその上に表示されるカーソルの色を設定できます。
カーソルの色は要素の上に重ねて表示されるため必ず半透明にする必要があります。

```css
nav a{
-webkit-tap-highlight-color:rgba(178,223,219,0.4);
}
```

[ブラウザで見る](http://firespeed.org/lab/responsive/page312.html)

###フッターのデザイン###
フッター部分は濃い背景色に白文字でセンタリングとします。
また、コンテンツ本文との間に隙間をつけておきます。

```css
footer{
        text-align:center;
        background-color:#004d40
        padding:1em;
        margin-top:4em;

}
```

![](https://qiita-image-store.s3.amazonaws.com/0/17830/87269dfa-d860-afea-e584-30570962b6f2.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page312.html)

#出来上がったページをチェックする#

それでは、出来上がったページをチェックしてみましょう。
##HTML5の文法##
まずはhtml5の[validation](http://validator.w3.org/)でHTML5の基本的な文法に間違いがないかチェックします。
エラーはないようです。
###HTML###

```html
<!DOCTYPE html>
<html>
  <head>
    <title>AndroidWear長期レビュー</title>
    <link rel="stylesheet" href="page313.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="画像１" />
        <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="画像１" />
        <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="画像１" />
        <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の文法##
[css validator](http://jigsaw.w3.org/css-validator/)でCSSの文法もチェックします。
ベンダープレフィックスを使っているため警告が出ていますがそれ以外にエラーはないようです。

###CSS###

```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;
        
}
```

##PageSpeed Insights##
GoogleのPageSpeed Insightsを使用することでモバイルのアクセシビリティやパフォーマンスのアドバイスを受けることが出来ます。
パフォーマンスで警告が出たのは以下の3つ

### 1. スクロールせずに見えるコンテンツのレンダリングブロック JavaScript/CSS を排除する###
これはCSSを別ファイルに設定しているために起きる警告です。
ページのレイアウトはHTMLファイルの他CSSを読み込まないとレイアウトできません。
スタイルシートをインラインに組み込むことでこの警告をなくすことが出来ます。
ただし、これはCSSのキャッシュが使えなくなる事を意味して複数ページを移動するたびにスタイルシートを読まないといけなくて逆に遅くなるとか、Webサーバー側での対応をしないと管理が大変になるなどの問題もあります。
とりあえず、今回は放置しますが、どうしても消したい場合はstyleタグ内にCSSをコピペすれば消えます。

### 2. 表示可能コンテンツの優先順位を決定する###
これは上記にも書いたmax-widthを使っている問題です。
今回はパフォーマンスよりレイアウトを優先したので仕方が有りません。

### 3. 圧縮を有効にする###
コンテンツを圧縮することで転送データの量を減らすことが出来ますが今回の内容とはずれるので省略します。
気になる方はgzipなどを調べてみてください。

アクセシビリティに関しては満点でした。
##実機でチェックする##
もちろん実際に携帯でも動きをチェックする必要があります。
機械的なチェックでは見えてこない問題点が見えてくることがあります。
今回はリンクにアニメーションが設定されているため、その挙動もチェックしておく必要があります。

#多解像度時代のデザイン手法#
##ディスプレイのサイズをコンテンツで吸収する##
完成したモバイル版の全体像を見て行きましょう。
レイアウトに関わる主要な指定は以下のとおりです。

![](https://qiita-image-store.s3.amazonaws.com/0/17830/fc01e7d6-3e58-b178-a316-bd60fb79a5c0.png)
![](https://qiita-image-store.s3.amazonaws.com/0/17830/00e804b8-02da-9509-92b1-ce115a7da467.png)
![](https://qiita-image-store.s3.amazonaws.com/0/17830/2f19e028-de02-833f-524f-b7a7965c52e2.png)
余白や隙間のサイズを固定で指定して、コンテンツのサイズを指定していないことがわかると思います。
これによりあらゆるディスプレイに最適化出来るだけでなく、コンテンツの量が増減したりユーザーがフォント設定を変えた場合でもレイアウトが破綻しなくなります。

クラッシクなWebではしばしばデザインが紙面上で唯一のサイズに最適化する形で行われ、コンテンツのサイズをきっちり指定し、余った部分を余白として可変サイズにしていました。
余白を固定しコンテンツを可変とするスタイルはその逆の手法と言えます。
そのため新しいデザインでは、紙よりもむしろユーザーの実体験に近い実機上で行うべきでしょう。

##実機上でデザインする##
Chromeデベロッパーツールを使うことで実機を使ってデザインを行うことが出来ます。
ChromeでWebページの項目を右クリックして「要素を検証」を選ぶことでデベロッパーツールが起動します。
デベロッパーツールを使うとHTML上で指定した項目にどのようなCSSがあたり、どのようにレイアウトされているかを見ることが出来、CSSの値をブラウザ内で変更してリアルタイムにその結果を見ることも出来ます。
参考： [Chrome DevToolsでCSSデザイン](http://firespeed.org/diary.php?diary=kenz-1589)

#PCに最適化する#
大画面ではより大画面を活用した機能を追加することでユーザーのリソースをより適切に活用できます。

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

##media queryを使う##

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

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

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


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

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

というHTMLに

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

と指定した場合、pタグの設定より#redの方がより細かく指定されているため、fooは赤字になります。
[ブラウザで見る](http://firespeed.org/lab/responsive/page401.html)

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

```html
<p>bar</p>
```

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

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

[ブラウザで見る](http://firespeed.org/lab/responsive/page402.html)
画面サイズを60em以上にしても文字色はblueのままです。
media queryを使用する場合は、上書きしたい定義より下に書くように注意が必要です。

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

PCで以下のページを開いてウィンドウ幅を増減させてみてください。
画面幅がある程度を超えたところで文字色が赤に変わることがわかると思います。
[ブラウザで見る](http://firespeed.org/lab/responsive/page403.html)

##記事を右側にずらす##

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

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

記事が右にずれました。
しかしページから記事がはみ出して横方向のスクロールバーが表示されてしまいました。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/8c75e54c-1344-0d5b-3a14-7d3060538ecd.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page404.html)

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

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

![](https://qiita-image-store.s3.amazonaws.com/0/17830/da707a78-f113-3b63-6113-171f208a046e.png)

記事が画面内に入りました。
[ブラウザで見る](http://firespeed.org/lab/responsive/page405.html)

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

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

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

幅が設定されました。しかし、高さの指定はされていないため元のレイアウトの高さと同様記事の下に表示されてしまいます。
![kenz1782-img406.png](https://qiita-image-store.s3.amazonaws.com/0/17830/bcbbf18c-2850-1037-9504-f73f4596b0db.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page406.html)

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

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

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

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

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

メニューが左上に移動しました。
余白がなく左端に張り付いています。しかし、ヘッダーとの間に空白があってイマイチ落ち着きません。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/f0274feb-c5d7-49a9-f8b7-8d3c9d23407e.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page407.html)

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

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

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

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

メニューという文字が消えメニューがヘッダに張り付いて表示されるようになりました。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/6fe8c9bb-4f1b-b7c2-28f6-07dd85cf6700.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page408.html)

###領域外をグリーンにする###

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

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

[ブラウザで見る](http://firespeed.org/lab/responsive/page409.html)

##画像を右に寄せる##

記事内の画像を右に寄せてテキストが回りこむようにします。
###floatで右に寄せる###
画像を右に寄せるには`.article_image`に対して`float:right`を設定します。

```css
@media screen and (min-width: 60em) {
.article_image{
        float:right;
        margin:1em;
}
}
```
floatの要素は親要素にレイアウトを反映させないため記事に対して画像が大きいとはみ出してしまいます。
![](https://qiita-image-store.s3.amazonaws.com/0/17830/6fb28b95-2b4e-00d9-f43f-0bac6074f323.png)


そこで、`section`ごとに最後の`p`の後ろにダミーの項目を作り`clear:right`をします。
ダミーの項目は`clear:right`によって、`margin:right`の項目の下側に配置され、`section`全体の高さもダミー項目を含む場所まで伸びるようになります。

ダミー項目は

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

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

```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`させています。

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

![](https://qiita-image-store.s3.amazonaws.com/0/17830/b10aa9e8-3698-cb63-7c9f-01a01a4a447a.png)
[ブラウザで見る](http://firespeed.org/lab/responsive/page411.html)

#動作チェック#

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

```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="画像１" />
        <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="画像１" />
        <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="画像１" />
        <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##

```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`を%指定することにより、メニューと記事のどちらもサイズに合わせて可変にすることも出来ます。

```css
@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; 
        }
}
```

[ブラウザで見る](http://firespeed.org/lab/responsive/page412.html)

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

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

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

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

##JavaScriptがないけれど使っちゃダメなのか##
今回はJavaScriptを一切使っていません。これも主な理由は説明を少なくしたかったからです。

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

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

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

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

この記事は[Firespeedの記事](http://firespeed.org/diary.php?diary=kenz-1779)を元に細部の調整を行ったものです。