はじめに
前にブログで書いた記事なのですが、せっかくなのでQiitaにも投稿します。
実際に緊急で対応した経験なんですが、レスポンシブでもないし、スマホサイトがあるわけでもないPCサイトをスマホで見るときに困ったことがありました。なのでviewportの指定とメディアクエリの組み合わせをいろいろ検証してみたのでそのまとめです。
viewportでどんなことに困ったのか
以前、PCサイトをスマホでみると表示が変だから対応してくれないかと依頼をうけまして。
割と昔に作られたであろうWEBサイトだったのですが、viewportの指定はされていました。
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
上記のようにviewportが入っているのにもかかわらずコンテンツがバカでかく表示されてしまう。
経緯を聞いてみると、昔作ったサイトがあるけど、スマホ対応する予算がないし念のためスマホサイトでもそれなりに見えるようにってことでvieportの指定を入れて入れてあったようなんですが、どうもうまく表示されなかったようなんです。
viewportを見てみても別段変なとこもないし、jsで無理くり画面幅いじっているのかなとかいろいろ疑ってみたのですが解決の糸口が見当たらずにいました。
んで、Google先生に聞いてみようってことで調べてみると、viewportの指定がよくなかったみたいですね。下記のようにするといいらしい。
<meta name="viewport" content="width=960">
ほうほう。なるほど。とりあえず急ぎの対応だったのでvieportの書き換えをしてみるとばっちり!
今回のようなケースって結構レアケースだとは思うんですが、改めてviewportの指定って大事だなってことでviewportについて深く勉強しておこうと思います。
まずはviewportの指定でできるもの
width
ピクセル指定
device-width
初期値は980px。viewportの横幅の指定です。
指定出来る値は200px〜10000px,device-width。
height
ピクセル指定
device-height
初期値は「横幅とのアスペスト比から計算される値」。
指定できる値は200px〜10000px,device-height。
initial-scale 初期のズーム倍率
device-width
を指定した場合は、初期のズーム倍率が1
になる。(initial-scale
で変更することも可能)
ていうか、initial-scale=1
とした時点で、width=device-width
であると暗黙的に決定される.その逆も同様
minimum-scale 最小倍率
minimum-scale
とinitial-scale
を組み合わせると縮小ができなくなります。
最小縮小比率の設定
デフォルトは0.25
で指定可能範囲は0より大きく、10までの値。
maximum-scale 最大倍率
最小拡大比率の設定。
デフォルトは1.6
で指定可能範囲は0
より大きく、10
までの値。
user-scalable ズームの操作
ユーザーがズームできるかどうかの設定。
初期値はyes
。数字指定も可能。yes=1,no=0。
target-densitydpi=device-dpi
Androidに向けて、Webサイトがどの画面密度に合わせて設計されているかを指定する属性
viewportの指定とメディアクエリの組み合わせをいろいろ実験検証してみる
前提条件と最低限必要なhtmlとcss
PC閲覧の場合はコンテンツの幅960px
SP閲覧の場合はコンテンツの幅をディスプレイのサイズにしたい
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" media="all" href="reset.css" />
<link rel="stylesheet" media="all" href="style.css" />
</head>
<body>
<header>
Header
</header>
<div class="wrap">
<article>
Content
</article>
<aside>
Sideber
</aside>
</div>
<footer>
Footer
</footer>
</body>
</html>
CSS
body {
font-family: sans-serif;
color: white;
}
header {
line-height: 15em;
text-align: center;
background: #333;
width:960px;
margin:0 auto;
}
.wrap{
width:960px;
overflow: hidden;
margin:0 auto;
}
article {
line-height: 20em;
text-align: center;
background: #666;
width:640px;
float:left;
}
aside {
line-height: 20em;
text-align: center;
background: #999;
width:280px;
float:right;
}
footer {
line-height: 15em;
text-align: center;
background: #BBB;
width:960px;
margin:0 auto;
}
@media ( max-width : 1024px ) {
header {
width:100%;
}
.wrap{
width:100%;
}
article {
width:100%;
float:none;
}
aside {
width:100%;
float:none;
}
footer {
width:100%;
}
}
※メディアクエリについては1024pxからPC向けになるようにしています。
あとは、メディアクエリやviewportをコメントアウトなりをして実験をしていきます。学生のころの理科の実験みたいで楽しいですね。
画像も載せるの一緒に確認してみてくださいね。
検証端末
- iPhone 4s iOS7
- iPhone 6 iOS8
- Android 4.0.4
1,メディアクエリなし、viewportなし
拡大可能
- コンテンツの幅より小さいサイズには縮小はできない。
- 拡大した状態でリロードすると大きくなったまんま
- 画面の両端に若干隙間ができている
- PCサイトをそのまんま小さく表示されている状態
- 文字が小さくかなり読みにくい
※コンテンツの幅が今回は960pxですが、800pxなど960pxよりも小さい場合は画面の両端にかなりおおきな余白がでてしまいます。
なので、どの画面でも同じように、デバイスの幅にぴったりにするためにはviewportの指定は必須になりますね。
2,メディアクエリあり、viewportなし
メディアクエリは正常に動作している(今回の場合だとfloat解除)
- 文字が小さくかなり読みにくい
- 1のパターンがfloat解除されただけ
- コンテンツの幅が960pxで取られているからだと思う
3,メディアクエリなし、viewportあり
case1
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
iPhoneではコンテンツがバカでかくなってしまっている状態で表示され、それ以上の縮小ができない
Androidでは拡大、縮小ができた。パターン1と同じような感じで表示されてしまった。
このパターンからiPhoneとAndroidで違いが出てきてしまった
case2
<meta name="viewport" content="width=960,initial-scale=1.0,minimum-scale=1.0">
iPhoneではコンテンツがバカでかくなってしまっている状態で表示され、それ以上の縮小ができない
Androidでは拡大、縮小ができた。パターン1と同じような感じで表示されてしまった。
iPhoneとAndroidで違いが出てきてしまった
casa2と同じ結果
case3
<meta name="viewport" content="width=960">
1,メディアクエリなし、viewportなしとほぼほの同じ表示でした。
拡大できる
- 拡大した状態でリロードすると大きくなったまんま
- PCサイトをそのまんま小さく表示されている状態
- 文字が小さくかなり読みにくい
ちょっと補足すると、iPhone6では「画面の両端に若干隙間」ができていましたが、iPhone4s Androidでは画面の両端に隙間がありませんでした。
4,メディアクエリあり、viewportあり
case1
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
- 狙い通りの見た目
- 拡大できる
- レスポンシブで作るのであればこれが正解だと思う
case2
<meta name="viewport" content="width=960px,initial-scale=1.0,minimum-scale=1.0">
上記と同じように見えますが、コンテンツがバカでかくなってしまっています。イメージだとわかりづらいですね・・・。
拡大できる
case3
<meta name="viewport" content="width=960">
- 拡大縮小はできる
- 拡大した状態でリロードすると大きくなったまんま
- メデイアクエリのfloat解除はできているが、幅が960pxなので、文字が小さい
ところでuser-scalableはいるの?
user-scalable=noを使う理由(メリット)
- アプリっぽく見せることができる
- Android 2.3でfixedを有効にすることができる
- タップの反応を早めることができる
- ダブルタップだと認識されるのは、タップされてもう一度タップされるまでの間隔が300ms以内
user-scalable=noを使う上での弊害(デメリット)
- 文字が小さい場合や、画像が小さい場合に読みにくいと思う人もいる
あくまで個人的な意見になってしまいますが、拡大縮小はできなくてもいいのかなとは思いました。自分が拡大するときって文字が小さい、画像が小さくてみにくい時かなと。
zozoやamazonや楽天も拡大はできないようになっていました。やっぱりアプリっぽい印象になりますね。文字の大きさ、画像のみやすさを考慮してレスポンシブも含めスマホサイトを制作する必要があるってことですね。
まとめ!viewportの最適な方法はこれ!!
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
- デバイスごとにサイズを切り替える
- 縮小はさせないようにする
googleでもこの設定を推奨しているみたいみたいですね。
ちなみに、PCサイトしかなくスマホサイトが無い場合はPCサイトをスマホで閲覧することになります。その場合は
<meta name="viewport" content="width=960">
viewportを入れないって方法もなくはないですが、コンテンツの幅が960px以下だと画面両端に余白がでてしまいデバイスに合わせることができていません。viewportの指定はしたほうがいいですね。