Asial Blog

Recruit! Asialで一緒に働きませんか?

CSS3 メディアクエリを使ってWebサイトをスマートフォン・タブレット対応しよう

カテゴリ :
バックエンド(プログラミング)
タグ :
HTML5
CSS3
CSS
皆様、ご無沙汰しております。笹亀です。
ブログを公開させていただくペースが遅くなってしまいました・・申し訳ございません。そのことが災いしたのか、先日、自分のスマートフォンを落としてしまい、液晶が派手に割れてしまいました。

さて最近、仕事をしている中でPC系だけではなく、スマートフォン系のサイトを作成をすることはもはや当たり前になってきました。そんなスマートフォンサイトでもさらにタブレットにも対応をさせたWebサイトの構築を求められることが多くなってきています。タブレットに対応させるサイトの構築方法ですが、様々なものが考えられます。
例えば動的にタブレット・スマートフォンを判定して、テンプレートを出し分けするといった対応する方法やViewPortを固定値にして作成する方法などがございます。
今回はViewPortは下記のようにデバイスのサイズにした状態でCSS3のメディアクエリというものを利用した方法をご紹介したいと思います。
  1. <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">

メディアクエリとはメディアタイプとメディア特性を必要とする一つ以上の条件式からなりたちます。メディアタイプには様々なものがあり、それぞれの条件にあったときに特定のスタイルを適応することができます。
参考:メディアクエリ

今回はスマートフォンやタブレットなどを想定した画面サイズの違いによって、適応するスタイルを変更するといったことをおこないます。簡単なサンプル用のHTMLとメディアクエリを記載したCSSを用意して説明致します。

sample.html


  1. <!DOCTYPE HTML>
  2. <html lang="ja-JP">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   
  6.   <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
  7.   <meta name="format-detection" content="telephone=no" />
  8.  
  9.   <link rel="stylesheet" href="./css/sample.css" />
  10.   <title>メディアクエリのサンプル</title>
  11. </head>
  12. <body id="top">
  13. <div id="page">
  14. <header class="global">
  15.   <div id="header_inner">
  16.     <p class="headerlogo"><img src="img/logo.png" alt="header_rogo" id="header_rogo" /></p>
  17.   </div>
  18. </header>
  19.  
  20. <section class="main">
  21.   <div class="test_1">
  22.     <h3><img src="img/sample.jpg" alt="sample" /></h3>
  23.     <div class="test_1_inner">
  24.       <ul class="list">
  25.       <li><a><p class="head">ブログAほげほげほげほげほげほげほげほげほげほげほげほげほげ</p><p class="time">2013年5月21日</p></a></li>
  26.       <li><a><p class="head">ブログB</p><p class="time">2013年5月20日</p></a></li>
  27.       <li><a><p class="head">ブログC</p><p class="time">2013年5月19日</p></a></li>
  28.       </ul>
  29.     </div>
  30.   </div><!-- //.test_1 -->
  31.   
  32.   <div class="test_2">
  33.     <div class="text_big">文字サイズ大</div>
  34.     <div class="text_middle">文字サイズ中</div>
  35.     <div class="text_small">文字サイズ小</div>
  36.     <div class="copy">Copyright&copy; Asial Corporation All rights Reserved.</div>
  37.   </div>
  38. </section>
  39. </div>
  40. </body>
  41. </html>

sample.css


  1. /** header-start **/
  2. header.global {
  3. background: #fe9700; /* Old browsers */
  4. background: -moz-linear-gradient(top, #fe9700 0%, #fed919 100%); /* FF3.6+ */
  5. background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fe9700), color-stop(100%,#fed919)); /* Chrome,Safari4+ */
  6. background: -webkit-linear-gradient(top, #fe9700 0%,#fed919 100%); /* Chrome10+,Safari5.1+ */
  7. background: -o-linear-gradient(top, #fe9700 0%,#fed919 100%); /* Opera 11.10+ */
  8. background: -ms-linear-gradient(top, #fe9700 0%,#fed919 100%); /* IE10+ */
  9. background: linear-gradient(to bottom, #fe9700 0%,#fed919 100%); /* W3C */
  10. filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fe9700', endColorstr='#fed919',GradientType=0 ); /* IE6-8 */
  11. position: relative;
  12. height: 190px;
  13. }
  14.  
  15. header.global .headerlogo {
  16.   float: left;
  17.   width: 460px;
  18. }
  19.  
  20. header.global .headerlogo #header_rogo{
  21.   width: 460px;
  22.   height: 50px;
  23. }
  24. /** header-end **/
  25.  
  26.  
  27.  
  28.  
  29. /* test_1-start */
  30. section.main .test_1 h3{
  31.   text-align: center;
  32. }
  33.  
  34. section.main .test_1 ul.list{
  35.   overflow: hidden;
  36.   border:solid 1px #ddd;
  37.   width: 620px;
  38.   margin: 0 auto 17px;
  39.   background-color: #fff;
  40.   border-radius: 10px;
  41.   -moz-border-radius: 10px;
  42.   -webkit-border-radius: 10px;
  43.   list-style-type: none;
  44.   padding-right: 40px;  
  45. }
  46.  
  47. section.main .test_1 ul.list li{
  48.   background-image:-moz-linear-gradient(top,rgb(255,255,255) 0%,rgb(229,229,229) 100%); 
  49.   background-image:-webkit-gradient(linear,left top, left bottom,,color-stop(0, rgb(255,255,255)),color-stop(1, rgb(229,229,229)));
  50.   background-image:-webkit-linear-gradient(top,rgb(255,255,255) 0%,rgb(229,229,229) 100%);
  51.   background-image:-o-linear-gradient(top,rgb(255,255,255) 0%,rgb(229,229,229) 100%);
  52.   background-image:linear-gradient(to bottom,rgb(255,255,255) 0%,rgb(229,229,229) 100%);
  53.   border-top:solid 1px #ddd;
  54.   margin-top: -1px;
  55. }
  56.  
  57. section.main .test_1 ul.list li a{
  58.   height: 100%;
  59.   color: #000;
  60.   text-decoration: none;
  61.   font-size: 27px;
  62.   display: block;
  63.   padding: 10px 15px;
  64. }
  65.  
  66. section.main .test_1 ul li a p.head{
  67.   margin-bottom:0;
  68.   width: 100%;
  69.   text-overflow:ellipsis;
  70.   white-space:nowrap;
  71.   overflow:hidden;
  72. }
  73.  
  74. /* test_1-end */
  75.  
  76. /* test_1-start */
  77. section.main .test_2{
  78.   width: 100%;
  79.   text-align: center;
  80.   background-color: #7FFFD4;
  81. }
  82.  
  83. section.main .test_2 .text_big{
  84.   font-size: 48px;
  85. }
  86.  
  87. section.main .test_2 .text_middle{
  88.   font-size: 32px;
  89. }
  90.  
  91. section.main .test_2 .text_small{
  92.   font-size: 18px;
  93. }
  94.  
  95. section.main .test_2 .copy{
  96.   font-size: 20px;
  97.   padding-top: 50px;
  98.   text-align: center;
  99.   color: #333;
  100.   font-weight: normal;
  101. }
  102.  
  103. /* test_2-end */
  104.  
  105. /* メディアクエリー部分 */
  106. @media screen and (max-width: 720px) {
  107.   /** header-start **/
  108.   header.global{
  109.     height: 95px;
  110.   }
  111.   header.global .headerlogo {
  112.     width:230px;
  113.   }
  114.   header.global .headerlogo #header_rogo{
  115.     width: 230px;
  116.     height: 25px;
  117.   }
  118.   /** header-end **/
  119.   
  120.   /* test_1-start */
  121.   section.main .test_1{
  122.     padding-top:43px;
  123.     background-size: 112px 36px, auto auto;
  124.     background-position: right 10px, 0 0;
  125.   }
  126.   section.main .test_1 h3{
  127.     width: 360px;
  128.     text-align: center;
  129.   }
  130.   section.main .test_1 h3 img{
  131.     width: 210px;
  132.     height: 140px;
  133.   }
  134.   
  135.   section.main .test_1 ul.list{
  136.     overflow: hidden;
  137.     border:solid 1px #ddd;
  138.     width: 320px;
  139.     margin: 0 auto 8px;
  140.     background-color: #fff;
  141.     border-radius: 5px;
  142.     -moz-border-radius: 5px;
  143.     -webkit-border-radius: 5px;
  144.   }
  145.   section.main .test_1 ul.list li{  
  146.  
  147.     border-top:solid 1px #ddd;
  148.     margin-top: -1px;
  149.     /* height: 43px; */
  150.   }
  151.   section.main .test_1 ul.list li a{
  152.     font-size: 13px;
  153.     padding: 4px 7px;
  154.   }
  155.   section.main .test_1 ul.list li a .time{
  156.     font-size: 6px;
  157.   }
  158.   /* test_1-end */
  159.   
  160.   /* test_2-start */
  161.   section.main .test_2 .text_big{
  162.     font-size: 24px;
  163.   }
  164.  
  165.   section.main .test_2 .text_middle{
  166.     font-size: 16px;
  167.   }
  168.  
  169.   section.main .test_2 .text_small{
  170.     font-size: 9px;
  171.   }
  172.  
  173.   section.main .test_2 .copy{
  174.     font-size: 10px;
  175.     padding-top: 25px;
  176.     text-align: center;
  177.     color: #333;
  178.     font-weight: normal;
  179.   }
  180.   /* test_2-end */
  181.  
  182. }

少しサンプルHTMLとCSSが長くなりましたが、こちらをベースにして説明をさせていただきます。メディアクエリにてスタイルを変更する際の注意点ですが、素材などのコンテンツについてスタイルを分ける中で一番解像度が大きいもの、今回の場合ですとタブレットの素材で作成するようにします。例えばタブレット用に用意した画像素材は、スマートフォンなどで表示する際にはタブレットより小さい解像度のときは比率を合わせて縮小して利用します。
  1. 例)タブレット用に準備した画像のサイズ:720x400 → スマートフォンで表示するサイズ:300x166

それではメディアクエリの説明をさせていただきます。メディアクエリはメディアタイプのその条件を指定し、条件内に記載されているスタイルが記載した条件にマッチするときにスタイルとして適応されます。下記の条件は、出力デバイスの描画域の横サイズが720ピクセル以下の場合にスタイルが適応されます。
  1. @media screen and (max-width: 720px) {
  2.  ・・・・
  3. }

複数の条件を設定することも可能で、下記のようにすると出力デバイスの描画域の横サイズが500ピクセルから800ピクセルの場合にスタイルが適応されます。
  1. @media screen and (min-width: 500px) and (max-width: 800px) {
  2.  ・・・・
  3. }

sample.cssに記載されたメディアクエリは、720ピクセル以下の場合に通常で読み込んでいるスタイルを上書きして、条件内に記載しているスタイルが適応されることになります。

横サイズ:1024px



※ロゴの画像のスタイルは条件にマッチしないため、下記のスタイルが適応されている。
  1. header.global .headerlogo #header_rogo{
  2.   width: 460px;
  3.   height: 50px;
  4. }
富士山の画像についても同様に下記のスタイルが適応されている。
  1. section.main .test_1 h3{
  2.   text-align: center;
  3. }
文字サイズを横サイズによって大きさを分けて表示する。

  1. section.main .test_1 ul.list li a{
  2.   height: 100%;
  3.   color: #000;
  4.   text-decoration: none;
  5.   font-size: 27px;
  6.   display: block;
  7.   padding: 10px 15px;
  8. }
  9. section.main .test_1 ul li a p.head{
  10.   margin-bottom:0;
  11.   width: 100%;
  12.   text-overflow:ellipsis;
  13.   white-space:nowrap;
  14.   overflow:hidden;
  15. }
  16. section.main .test_2 .text_big{
  17.   font-size: 48px;
  18. }
  19. section.main .test_2 .text_middle{
  20.   font-size: 32px;
  21. }
  22. section.main .test_2 .text_small{
  23.   font-size: 18px;
  24. }
  25. section.main .test_2 .copy{
  26.   font-size: 20px;
  27.   padding-top: 50px;
  28.   text-align: center;
  29.   color: #333;
  30.   font-weight: normal;
  31. }

横サイズ:360px



※ロゴの画像のスタイルは条件にマッチするため条件内の下記のスタイルが適応されている。
  1. header.global .headerlogo #header_rogo{
  2.   width: 230px;
  3.   height: 25px;
  4. }
富士山の画像についても同様に下記のスタイルが適応されている。
  1. section.main .test_1 h3{
  2.   width: 360px;
  3.   text-align: center;
  4. }
  5. section.main .test_1 h3 img{
  6.   width: 210px;
  7.   height: 140px;
  8. }
文字サイズを横サイズによって大きさを分けて表示する。

  1. section.main .test_1 ul.list{
  2.   overflow: hidden;
  3.   border:solid 1px #ddd;
  4.   width: 320px;
  5.   margin: 0 auto 8px;
  6.   background-color: #fff;
  7.   border-radius: 5px;
  8.   -moz-border-radius: 5px;
  9.   -webkit-border-radius: 5px;
  10. }
  11. section.main .test_1 ul.list li{
  12.   border-top:solid 1px #ddd;
  13.   margin-top: -1px;
  14. }
  15. section.main .test_1 ul.list li a{
  16.   font-size: 13px;
  17.   padding: 4px 7px;
  18. }
  19. section.main .test_1 ul.list li a .time{
  20.   font-size: 6px;
  21. }
  22. section.main .test_2 .text_big{
  23.   font-size: 24px;
  24. }
  25. section.main .test_2 .text_middle{
  26.   font-size: 16px;
  27. }
  28. section.main .test_2 .text_small{
  29.   font-size: 9px;
  30. }
  31. section.main .test_2 .copy{
  32.   font-size: 10px;
  33.   padding-top: 25px;
  34.   text-align: center;
  35.   color: #333;
  36.   font-weight: normal;
  37. }

このようにメディアクエリを使用するとスマートフォンとタブレットのように解像度が異なる端末でも、動的にテンプレートを切り替えることなくスタイルのみを切り分けるだけで対応することができます。
今回の例では2種類の切り分けのみでしたが、スマホやタブレット特有の画面の縦表示・横表示の切り替えに対応するために数種類のサイズを用意することも可能です。
  1. @media screen and (max-width: 360px) {
  2.  ・・・・
  3. }
  4. @media screen and (min-width: 361px) and (max-width: 600px) {
  5.  ・・・・
  6. }
  7. @media screen and (min-width: 601px) and (max-width: 1000px) {
  8.  ・・・・
  9. }

おまけ


1行以上の文字列を折り返して表示をしたくなくて、文字数をカウントして◯◯以上の文字の場合は「...」にするということをよくおこないます。
文字数をカウントしてJSで切ったり、VIEW側でVIEWのヘルパーを使ったりといった対応をする方もいらっしゃると思います。
CSSでも対応できます。

  1. <div class="test_1_inner">
  2.   <ul class="list">
  3.   <li><a><p class="head">Web標準のHTML5,JavaScript, CSSでスマフォアプリ未経験者でも簡単にアプリ開発ができます。</p><p class="time">2013年5月21日</p></a></li>
  4.   <li><a><p class="head">ブログB</p><p class="time">2013年5月20日</p></a></li>
  5.   <li><a><p class="head">ブログC</p><p class="time">2013年5月19日</p></a></li>
  6.   </ul>
  7. </div>
  1. section.main .test_1 ul li a p.head{
  2.   margin-bottom:0;
  3.   width: 100%;
  4.   text-overflow:ellipsis;
  5.   white-space:nowrap;
  6.   overflow:hidden;
  7. }

画像ではうまく伝わらないかと思いますので、そんな方はサンプルをブラウザで開き、ブラウザの横サイズを小さくしたり、大きくしたりしてみてください。スタイルがきりかわっているのがわかると思います。

次回は内容がガラッと変わりますが、postgresのレプリケーションについて興味があるので試しながらブログにしたいと思います。
それでは、皆様、良い、プログラミングライフを〜