一気に教えるプログラマーのためのレスポンシブHTMLコーディング
レスポンシブデザインのHTMLコーディングに悪戦苦闘しているデザイナーは多いと思う。絵的な意味でのデザインと、あまりにかけ離れたロジカルな処理が必要だからだ。
そこでプログラマーにお鉢が回ってくることがあるのだが、今一つCSSがわからず苦戦することが多いと思う。
プログラマーだからこそ扱いやすいレスポンシブ
そんな状況に陥っても、あわてる必要はない。ほんの少しのコツをつかめば、レスポンシブデザインなんて恐れるに足りないのだ。
まず正しくは【レスポンシブ】だ
よく「レスポンシブ ( responsive ) 」と「レスポンシブル (responsible) 」の混同を見かけるが、レスポンシブが正解だ。
レスポンシブ ( responsive ) 形容詞 反応する
レスポンシブル ( responsible ) 形容詞 責任のある
レスポンシブル・デザインだと、だいぶ意味が違ってしまうようだから要注意だ。
そしてここで扱うのは、レスポンシブなウェブのデザインだから、レスポンシブ・ウェブ・デザイン、略してRWDだ。
WEBの現場でRWDと言われたら、後輪駆動じゃなくてレスポンシブ・ウェブ・デザインだから気を付けよう。
レスポンシブってなんだ?
レスポンシブ・ウェブ・デザインという言葉は、現場でとっても厄介な誤解を生むことがある。本来は単に、複数の画面サイズに一つのHTMLで対応する、という意味合いしか持たない。【レスポンシブ・ウェブ・デザイン】
しかしその言葉から、『スマホサイズにすると画像やテキストのブロックが縦に並ぶ』とか、『スマホとPCではグロナビのデザインが変わる』とかも含めた、今風のギミックが当然に含まれていると思われていることがある。
こうした認識の違いを生みやすいのが RWD なのだ。
納品したものを見たクライアントから『え、これだけ?』と思われてしまうと、無用なトラブルを生むことになる。、気持ちのいいことではないので、事前に『どういった機能を含む RWD を期待されているか』の要件定義はしっかりしておこう。
早速レスポンシブ・ウェブ・デザインだ!
早速実践に入る。一気にいってみよう。
ただし、注意してほしいことがある。これは、筆者が独学で学んだ方法なので、正しいやり方とは限らない事、また、どこかに大きな落とし穴がある可能性があることは、先に承知しておいてほしい。
できれば、ここでコツをつかんだ後、書籍や体系立てて解説しているWEBサイトなどで、改めて正しい方法を学んで知識の補完をして、正確な知識を手に入れてもらいたい。
それから、一歩一歩正確に理解してから進もうとせず、わからないことは『そんなものか』ととらえて次の項目に進み、一通り読み進んでみていただきたい。一度に理解せず、何度か往復しながら、少しずつ塗り重ねて慣れるように理解してもらいたい。
(それから、まだこのページは作成中だ。先は長そうだが、出来るだけ早く完成させるようにするから、少し待ってほしい。)
ステップ1 画像の拡大と縮小など
準備
とりあえずこんなページを準備してみる。ゴールはこんなもんじゃないがとりあえずここから始めよう。
<!DOCTYPE html>
<head>
</head>
<body>
<div id="wrapper">
<div id="content_wrapper">
<div class="content">
文字ですよ
</div>
<div class="content">
<img src="./img/img_001_400x400.png" width="400" height="400">
</div>
</div><!-- content_wrapper -->
</div><!-- wrapper -->
</body>
</html>
見本のHTMLはこちら
意味が解らない人も、これぐらいなら解るという人も、とりあえず上のページを開いてブラウザの横幅を狭くしたり広くしたりしてみてほしい。
何も起きなかったと思う。まだ、レスポンシブの要素は入っていない。
拡大縮小、の前に
拡大縮小の前に、まず下のHTMLを見てほしい。
<!DOCTYPE html>
<head>
<style type="text/css">
#wrapper { /* 一番大きな囲みに */
border: solid 1px #000000; /* 黒い枠線と */
background-color: #888888; /* グレーの背景をつける */
}
#content_wrapper { /* つぎに大きな囲みに */
border: solid 1px #ff0000; /* 赤い枠線と */
background-color: #ffaaaa; /* うす赤い背景をつける */
}
.content { /* コンテンツ枠に */
border: solid 1px #0000ff; /* 青い枠線と */
background-color: #eeeeff; /* うす青い背景をつける */
}
</style>
</head>
<body>
<div id="wrapper">
<div id="content_wrapper">
<div class="content">
文字ですよ
</div>
<div class="content">
<img src="./img/img_001_400x400.png" width="400" height="400">
</div>
</div><!-- content_wrapper -->
</div><!-- wrapper -->
</body>
</html>
見本のHTMLはこちら
これは先ほどのHTMLとまったく同じものに、CSSというものを使ってレイアウトに色を付けただけのものだ。
<style type="text/css"> ここから </style> ここまでに書かれているものだな。
本来は外部ファイルに記載して、HTMLでそのファイルを読み込ませるのが一般的だが、ここではわかりやすくHTMLの中に記載している。これを、「スタイルをインラインに設定する」というような言い方をすることもある。
拡大縮小の前に、なんで色付けだけしたものを見せるかというと、「何を」拡大縮小させたいかを明確にするためだ。
「何を」って、WEBに決まってるだろ!と思う人は、先ほどと同じようにブラウザの横幅を広げたり縮めたりしてみてほしい。
どうだろう。ブラウザの横幅に合わせて、実は枠そのものは大きくなったり小さくなったりしているのがわかるのではないかと思う。
しかし、文字や画像はそのままの大きさだ。だから、ブラウザが小さくなると枠からはみ出てしまう。
なので、まずはこれをどうにかしてみよう。
画像を拡大縮小
画像を拡大、縮小する記載を追加してみた。
HTMLのメイン画像が入っている div に id [ main_image ] を追加
<div id="main_image" class="content">
<img src="./img/img_001_400x400.png" width="400" height="400">
</div>
CSSに main_image に入っている画像に対する設定を追加
#main_image img {
width : 100%; /* 画像を枠の100%の横幅にする */
}
たったこれだけだ。
見本のHTMLはこちら
どうだろう。ブラウザの横幅に合わせて、拡大、縮小指定のではないだろうか。
違うって?それはおそらく次の二つだろう。
- 縦のサイズが変わらないため、画像の比率が崩れている。比率は保ちたい。
- 元のサイズより大きく表示され、画像が荒くなる。最大は元の画像サイズにしたい。
それからもう一つ、画像サイズは横幅400px。ということはl、width: 100%; であれば 400pxで表示されるんじゃないの?という疑問もあるだろう。当然だ。
順番に解決していくが、まずは縦のサイズから解決してみよう。
縦のサイズは auto で
画像を拡大縮小
横幅の拡縮に高さを自動で合わせるのは簡単だ。
画像を拡大、縮小する記載を追加してみた。
#main_image img {
width : 100%; /* 画像を枠の100%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
これで縦横比が元の比率で保たれた。
元のサイズ以上大きくしない
次の課題。画像は元サイズ以上に大きく表示されると、荒れてしまいとてもみっともなくなる。
こうならないようにしたい。
こうしたくなるところだが…
#main_image img {
width : 100%; /* 画像を枠の100%の横幅にする */
height: auto; /* 高さは自動で設定する */
max-width : 400px; /* サイズの上限を設定する */
}
こうする。
#main_image {
max-width : 400px; /* サイズの上限を設定する */
}
#main_image img {
width : 100%; /* 画像を枠の100%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
上限を元画像のサイズに設定した。これでそれ以上大きく表示されることは無い。
なぜ画像である img に直接指定せずにひとつ上の枠である div に指定をするか。これは後ほど説明する「レイアウト」をどう考えるか、などいくつか理由があるのだが、ここではそういうもんだと思っておいてほしい。
・『画像が外枠に対して横幅100%で連動すること、また高さもそれに連動すること』は、画像要素に指定する
・しかし『最大サイズなどレイアウトに影響すること』は、枠である div に指定する
何に対して width が 100%だ?
すでにコメントに書いてるが、CSSの width を割合で指定する場合、その元となるサイズは元画像のサイズではなく、その要素が入っている枠のサイズだ。
この場合、[wrapper] > [content_wrapper] > [content] という枠の中にメイン画像が入っているため、この [content]というdivの横幅に対して画像の横幅 100% ということだ。
ブラウザの横幅が狭められれば、それに連動して html のコンテンツの大枠である body のサイズが狭められる。その body のさらに内側にある wrapper が狭められ、さらにその内側の content_wrapper が狭められ、そして content が狭められるため、その content のサイズに対して 100%に指定された画像のサイズが縮小される。 height : auto に設定されているため、高さも自動的に調整されるのだ。
もちろん必ずしも 100% である必要はない。試しに 80% にしてみてもらいたい。
#main_image {
max-width : 400px; /* サイズの上限を設定する */
}
#main_image img {
width : 80%; /* 画像を枠の80%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
ウィンドウ横幅への連動の仕方は同じだが、常に20%のマージンが出ている。ついでにこれをセンター配置にするとこんな書き方になる。
#main_image {
max-width : 400px; /* サイズの上限を設定する */
}
#main_image img {
width : 80%; /* 画像を枠の80%の横幅にする */
height: auto; /* 高さは自動で設定する */
margin : 0 auto; /* 上下のマージンをゼロ、左右を自動に設定する */
}
見本のHTMLはこちら
これで中央寄せに…ならないのだ。
正解を3とおり。
ひとつは上の要素に text-align : centerを設定すること。
#main_image {
max-width : 400px; /* サイズの上限を設定する */
text-align: center; /* ブロック内のテキスト(要素)の配置を設定する */
}
#main_image img {
width : 80%; /* 画像を枠の80%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
ただ私はこれをお勧めはしない。本来テキストの配置を設定するものであるし、またレスポンシブデザインを進めていく上で、扱いにくさを残してしまうからだ。
次は画像のマージンを autoではなく %などで設定すること。
#main_image {
max-width : 400px; /* サイズの上限を設定する */
text-align: center; /* ブロック内のテキスト(要素)の配置を設定する */
}
#main_image img {
width : 80%; /* 画像を枠の80%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
これであればちゃんと中央に配置されてくれる。
ではなぜ auto ではだめなのか。そこは、おそらく深いわけがあるのではないかと思う。。
画像の中央寄せはこれを正解にしたい
#main_image {
width : 80%; /* 画像の枠をさらに上位の枠の80%の横幅にする */
max-width : 400px; /* サイズの上限を設定する */
margin: 0 auto; /* 上下のマージンをゼロに、左右のマージンを自動に */
}
#main_image img {
width : 100%; /* 画像を枠の100%の横幅にする */
height: auto; /* 高さは自動で設定する */
}
見本のHTMLはこちら
いろいろな方法がある中で、私の結論としてはこれが最も扱いやすい方法だと考える。
画像に対してはあくまで『外枠に対して横幅100%、たて自動』という設定だけする。
サイズや配置は画像を囲う div で行う。
ところで、width というのは『元の画像に対するサイズじゃないの?』という人がいたら再確認してほしい。『【html】と【css】』は『【情報】と【デザイン】』の分離だということ。
- HTMLにはコンテンツ
- CSSにはレイアウト・デザイン
CSSはあくまでレイアウトやデザインを設定するパートなのだ。だから、そこには画像などコンテンツの情報、つまり画像のサイズなどは入り込まないのが原則。
だからさっき便宜上、画像のサイズを上限として設定したが、あくまでたまたまの話だ。これが 300px であろうと 500px であろうと自由。というより、レイアウトの設計によってこのサイズを決めるべきであって、画像のサイズによって決めるべきではないのだ。
画像サイズがあって、レイアウトを設定する、というのは、発想が逆なのだ。
脱線してみる
大切なところだから、少し脱線する。ただこれを読むとかえって頭が混乱する可能性があるから、とりあえずは読み飛ばしてもらって構わない。
WEBデザインと制作の手順としては、一般的にはこんな感じが主流だ。
- ターゲットとなるデバイスの画面サイズを決定する
- Illustratorのキャンバスなどをそのサイズに設定してデザインする
- そのサイズにぴったり合わせたサイズの画像等をコンテンツとして書き出す
こうして書き出された画像を、htmlという言語で正確に配置していくというのがコーディングという作業になるだろう。
しかしこの手法は、はたしていつまで通じるだろうか。フルハイビジョンサイズに満たないディスプレイから、4Kやレティナディスプレイまで、画面上のピクセル数は4倍を超える差がある。
そのうえ新たな課題はレスポンシブだ。そのうえ、スマホやタブレットでは、ユーザーが自由に拡大/縮小しながらコンテンツを閲覧する使い方が一般的だ。好きなだけ画像も拡大して表示することができる。
つまり、こう考えることができる。
ユーザーは必ずしも、制作者が意図する100%のサイズで見るわけではないということ。こちが100%美しいと思う状態で見れくれるとは限らない事。
であるのならば、こう対処することもできる。
初めから縦横2倍で表示されることを考慮して、本来のサイズより縦横2倍のサイズの画像を用意しておけば、高解像度のディスプレイで閲覧するユーザーにも、最善の状態のWEBサイトを提供することができる。
こうなってくると、もはや 【 設計サイズ = 埋め込まれる素材のサイズ 】という固定概念自体が怪しくなる。
言い方を変えると、だからこそのレスポンシブデザインで、その設計に『元画像のサイズ』という情報を持ち込むことがナンセンスなのだ。
とはいえ、現実には仕様や要件としてピクセル数は設定されるし、ネットワーク経由で提供するためにページ容量、画像容量の制約もある。だからもちろん、ピクセル数というものに縛られるのだが、原則的にはそんな考え方だということを頭に入れておいたほうが、CSSとは付き合いやすくなると思う。
ステップ2 実践 複数の画像を配置する
では少し実践めいたものを。WEBページのよくある構成である、indexページの上部に大きななヘッダ画像、その下にグローバルナビゲーションを配置、というものをレスポンシブにしてみたい。
それらしいソースはこんな感じだ。
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#wrapper { /* 一番大きな囲みに */
background-color: #888888; /* グレーの背景をつける */
}
#content_wrapper { /* つぎに大きな囲みに */
background-color: #ffaaaa; /* うす赤い背景をつける */
}
/* --------------- メイン画像 ---------------- */
#main_image {
width : 100%;
margin : 0 auto;
}
/* --------------- グローバルナビゲーション ---------------- */
#g_navi {
width : 100%; /* グロナビの横幅を ウィンドウの100%にする。*/
}
</style>
</head>
<body>
<div id="wrapper">
<div id="content_wrapper">
<div id="main_image">
<img src="./img/img_002_800x100.png" width="800" height="100">
</div>
<div id="g_navi">
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
</div><!-- g_navi -->
</div><!-- content_wrapper -->
</div><!-- wrapper -->
</body>
</html>
見本のHTMLはこちら
まずいくつかのお約束
自由自在に設定するため、まずいくつかの設定を加える。
追加するのはこれ。
* {
margin : 0; /* すべての要素のマージン初期値を 0 に */
padding : 0; /* すべての要素のパディング初期値を 0 に */
}
img {
border: none;
}
各要素の margin 、 padding をそれぞれゼロにする。
見本のHTMLはこちら
これで画像どうしもぴったりくっつく…はずが、そうならない。もう一つするべきことがあるのだ。
img の個所をこうする。
img {
border: none;
vertical-align:bottom;
}
見本のHTMLはこちら
どういうことかというと、画像の底辺はデフォルトで vertical-align:baseline になっていて、これはアルファベットのの【abc】などの底辺と揃う位置だ。『行』で確保される底辺でそろえる必要がある。逆に言うと、こうしておかないと画像の底辺の下に baseline から bottom までの差分を確保されてしまい、隙間があくことになる。
拡大縮小と中央配置
とりあえずメイン画像を中央配置にして、拡大縮小をさせるとこうなる。
#main_image {
width : 100%;
max-width : 800px;
margin : 0 auto;
}
#main_image img {
width : 100%;
height : auto;
}
見本のHTMLはこちら
次にメニューを拡大縮小してみよう
まず足りない例。
#g_navi {
width : 100%; /* グロナビの横幅を ウィンドウの100%にする。*/
}
#g_navi .button {
width : 25%; /* 各ボタンを横幅の25% にする。 */
}
#g_navi .button img {
width : 100%;
height : auto;
}
見本のHTMLはこちら
ボタンのサイズは連動するようになった。あとはこれを横にそろえればいい。
横に並べるのならば、使うのは float だ。
#g_navi .button {
width : 25%; /* 各ボタンを横幅の25% にする。 */
float :left; /* 指定要素を左に寄せる */
}
こうなった。
見本のHTMLはこちら
画面幅を縮めるとこうなる。
サイズを縮めると期待通りだと思うが、広げるとメイン画像の幅を超えてしまう。
これをどうにかしよう。
#g_navi {
width : 100%; /* グロナビの横幅を ウィンドウの100%にする。*/
max-width : 800px;
margin : 0 auto;
}
これで一応はそれらしい感じになった。
改めて確認してみてほしい。メイン画像と合わせるために、グローバルナビゲーションにも max-width: 800px を設定した。しかし、グロナビのボタンと 800pxという値とは何の関係もない。
前に書いたことを思い出してもらいたい。画像のサイズと、それを入れておく枠のサイズは関係が無い、ということ。サイズの設定は画像に依存して行うわけではなく、レイアウトの設定のために行う、ということ。
見本のHTMLはこちら
画面幅を縮めるとこうなる。
float を閉じて完了
ここまでで期待通りかもしれないが、最後に忘れてはならない事がある。
例えばこの後にコンテンツが続く場合。
<div id="g_navi">
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
</div><!-- g_navi -->
<div class="content">
文字列です。
</div>
見本のHTMLはこちら
いわゆるレイアウトの崩れ、というものの一つの原因に、floatの閉じ忘れというものがある。
floatの設定された要素に続く要素はその並びに従うので、文字列もそれに続いてしまう。そうならないために clear を設定した div を置いて解除するのだ。
.clear {
clear: both;
}
:
<div id="g_navi">
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="button"><img src="./img/button_160x80.png" width="320" height="80"></div>
<div class="clear"></div>
</div><!-- g_navi -->
<div class="content">
文字列です。
</div>
見本のHTMLはこちら
ウィンドウサイズによってレイアウトを変える
いよいよ、それらしいことを一つしてみよう。スマホとそれ以外のサイズでメニューのレイアウトを変えてみる。
HTMLは一切触らず、CSSだけで対応可能だ。
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
#g_navi .button {
width : 50%; /* 各ボタンを横幅の50% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
@media screen and ( min-width: 641px ) { /* ウィンドウサイズが 641px 以上の場合有効 */
#g_navi .button {
width : 25%; /* 各ボタンを横幅の25% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
見本のHTMLはこちら
画面幅を縮めるとこうなる。
ウィンドウサイズによる設定は @media screen and ( max-width: 640px ) { } この中に書く。これは画面のサイズが最大 640px であれば、というもの。つまりは一般的にはスマートフォンの縦画面のサイズということになる。
@media screen and ( min-width: 641px ) これは、画面のサイズが 641px 以上であれば、というもの。PCやタブレットだ。
さらにたとえば、スマートフォン、タブレット、PCなど分けたい場合は下記の様な書き方もできる。
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
}
@media screen and ( min-width: 641px ) and ( max-width: 720px ) { /* ウィンドウサイズが 641-720px */
}
@media screen and ( min-width: 721px ) { /* ウィンドウサイズが 721px 以上の場合 */
}
ボタンサイズを横幅320pxとした理由
PCサイズで考えた場合、横幅800を4分割するボタンのサイズは、横200pxで十分だ。しかし、スマホサイズになると横幅640pxを2分割するため、横幅320pxなければ画像が拡大され不鮮明になってしまう。そのため、もともと320pxの画像が使用されているのだ。
レスポンシブウェブデザインにおいては、画像サイズが必ずしも一つのデザインに依存しないことが、改めてわかっていただけると思う。
VIEWPORT を METAタグ に加える
前の例を試しに、スマホなどで見ていもらえると、おそらく期待はずれな結果になると思う。PCと同じく、メニューボタンは横に4つ並んでいるだろう。
これはHTML側に足りない記述があるからだ。
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=0.5,user-scalable=yes,initial-scale=0.5" />
見本のHTMLはこちら
内容はともあれ、上記のタグを設定すればスマホでも期待通りの動作をするはずだ。
viewportの記述については、様々ややこしいことがあるので、ここではひとまずこれだけにしておく。
コードを整理する
制作を進めていくと、思いのほかソースコードがごちゃごちゃになったり、無駄な記述が多くなったりすることがある。
そのまま放置して進めてしまうと、多くの場合無駄や不整合を重ね、非常にメンテナンス性の悪い成果物が上がってしまう。
制作中はできるだけ作業を進めることに時間を使いたくはなるものだが、要所要所でソースコードの整理をしたほうが、結果的に効率が上がり、なおかつ有効な資産として仕上がるものだ。
ここで一旦ソースコードの整理をしてみよう。
大切なのは、やたらめったら省略や簡略化をして記述量を減らすことではない。記述内容が意味合いとして適切かどうかを判断して、より適切な方法があればそれに置き換えることだ。
例えば、メイン画像のサイズを max-width:800pxとしている。これはその次のグローバルナビゲーションの最大幅 max-width: 800px からもわかるように、メイン画像の最大幅というより、Wコンテンツエリアの最大幅だ。
であるならば、記述を下記のように直すのが意味合いとして正しい。
これを
/* 抜粋 */
#content_wrapper { /* つぎに大きな囲みに */
background-color: #ffaaaa; /* うす赤い背景をつける */
}
#main_image {
width : 100%;
max-width : 800px;
margin : 0 auto;
}
#g_navi {
width : 100%;
max-width : 800px;
margin : 0 auto;
}
こうする
/* 抜粋 */
#content_wrapper { /* コンテンツの囲み */
background-color: #ffaaaa; /* うす赤い背景をつける */
max-width : 800px; /* 最大幅を設定 */
margin : 0 auto; /* マージンを設定 */
}
#main_image {
width : 100%;
}
#g_navi {
width : 100%;
}
/* コンテンツエリアのクラスについても下記を加える */
.content {
width : 100%;
}
見本のHTMLはこちら
余白部分は最も外側の枠である wrapper に設定したグレーが現れた。その中央にメイン画像とグロナビが表示され、その下で浮いていた文字列も、これでレイアウトに収まった感じになった。
PCとスマホで表示する画像やテキストコンテンツを変える
さらにRWDっぽいギミックを入れ込んでみる。
画像やテキストなどのコンテンツを、ブラウザサイズによって表示分けしてみる。
まずはこんなHTMLを用意する。
<!-- メイン画像部分 -->
<div id="main_image">
<div>
<img src="./img/img_002_800x100.png" width="800" height="100">
</div>
<div>
<img src="./img/img_003_640x240.png" width="640" height="240">
</div>
</div>
<!-- テキスト部分 -->
<div class="content">
<div>
パソコン用の文字列です。
</div>
<div>
スマホ用の文字列です。
</div>
</div>
見本のHTMLはこちら
メイン画像、テキストコンテンツとも、PC用とスマホ用のものが表示されている。
これをブラウザサイズによって、表示する、しないを切り替えて一方だけを表示するようにする。
PC用、スマホ用のクラスを設定する
PC、スマホのコンテンツに対応するクラスを設定すると、下記のようになる。
<!-- メイン画像部分 -->
<div id="main_image">
<div class="pc_part">
<img src="./img/img_002_800x100.png" width="800" height="100">
</div>
<div class="sp_part">
<img src="./img/img_003_640x240.png" width="640" height="240">
</div>
</div>
<!-- テキスト部分 -->
<div class="content">
<div class="pc_part">
パソコン用の文字列です。
</div>
<div class="sp_part">
スマホ用の文字列です。
</div>
</div>
クラスごとの【非表示】を設定する
次に、グローバルナビゲーションの表示レイアウト変更の時にも使用した media query を使用して、それぞれのクラスに対して、どのような場合に【非表示】にするかを設定する。
/* --------------- 非表示設定 ---------------- */
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
.pc_part {
display : none;
}
}
@media screen and ( min-width: 641px ) { /* ウィンドウサイズが 641px 以上の場合有効 */
.sp_part {
display : none;
}
}
見本のHTMLはこちら
画面幅を縮めるとこうなる。
まるで画面が切り替わるように表示が変わることがわかると思う。
コンテンツ容量と、media query の使い方について補足したい。
コンテンツ容量について
先の例のように複数のコンテンツをHTMLに記述して、CSSの非表示設定で表示分けをした場合、非表示であってもその読み込まれる。単純にPCとスマホで倍のコンテンツが読み込まれることになる。
こうなると本末転倒で、作り手としても複数レイアウトを難儀しながら一つのファイルに収め、それを使用するユーザーも、実際に表示されるコンテンツの倍の通信コストが掛かることになり、誰にとってもデメリットしかなくなってしまう。
であるのなら、素直にURLを分けるか、PHP等サーバサイドで出力を変えてあげるほうがユーザーにとっても親切だし、作り手にとっても負担が少ない。
確かにレスポンシブデザインであり、トリッキーなほど今はうけがいいかもしれないが、そこは用途やコスト、ユーザーにとってのメリットデメリットなどを冷静に検討し、RWDはあくまで一つの選択肢としたほうがよいだろう。
ただ、新しい手法ほど喜ばれる業界ではあるのは確かなので、クライアントに求められれば採用することになると思うが、こうしたデメリットについては十分に説明をしておこう。
media query は、いくつ設定できるか
時々、media query は cssの中で1セットしか使用できないと勘違いしている人がいるが、そんなことは無い。
プログラマなら解ると思うが、 if 分の様な一般的な制御構文だと思えばいいだろう。このソースでは2セット出てきているが、では、先ほどのソースコードの整理をするような過程において、これを1か所にまとめるべきかどうか、という課題が出てくる。
/* --------------- 非表示設定 ---------------- */
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
.pc_part {
display : none;
}
}
@media screen and ( min-width: 641px ) { /* ウィンドウサイズが 641px 以上の場合有効 */
.sp_part {
display : none;
}
}
/* --------------- グローバルナビゲーション ---------------- */
#g_navi {
width : 100%; /* グロナビの横幅を ウィンドウの100%にする。*/
}
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
#g_navi .button {
width : 50%; /* 各ボタンを横幅の50% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
@media screen and ( min-width: 641px ) { /* ウィンドウサイズが 641px 以上の場合有効 */
#g_navi .button {
width : 25%; /* 各ボタンを横幅の25% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
これについては、まとめるべきではないと考える。
なぜなら、最初の1セット【非表示設定】は、サイト全体に対して影響する設定であり、次の1セット【グローバルナビゲーション】はグロナビという一つのコンテンツに対して影響する設定だからだ。
仮にまとめるとこうなる。
/* --------------- 非表示設定 ---------------- */
@media screen and ( max-width: 640px ) { /* ウィンドウサイズが 640px 以下の場合有効 */
.pc_part {
display : none;
}
#g_navi .button {
width : 50%; /* 各ボタンを横幅の50% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
@media screen and ( min-width: 641px ) { /* ウィンドウサイズが 641px 以上の場合有効 */
.sp_part {
display : none;
}
#g_navi .button {
width : 25%; /* 各ボタンを横幅の25% にする。 */
float :left; /* 指定要素を左に寄せる */
}
}
/* --------------- グローバルナビゲーション ---------------- */
#g_navi {
width : 100%; /* グロナビの横幅を ウィンドウの100%にする。*/
}
確かに、ソースコードは若干短くなるのだが、グローバルナビゲーションに対するスタイルの記述が分かれてしまうことになる。
そうすると、仮にコンテンツを差し替えるときにCSSの記述を直さなければならない場合に、複数の個所に散らばった記述を探さなければならなくなるのだ。
これはメンテナンス性を悪化させる事になる。
大切なのはわずかなソースコードの容量を減らすことではなく、自分以外の人も含む誰が見てもわかりやすい資産を残すことだ。
--- ここから先は作成中 ---
参考にさせて頂いたWEB
marginとpaddingについて http://kojika17.com/2012/08/margin-of-css.html
画像に隙間が出来る http://webtech-walker.com/archive/2007/03/01143619.html
行ボックスの詳しい説明 http://www.htmq.com/style/vertical-align.shtml
floatの詳しい説明 http://www.htmq.com/style/float.shtml