IEでHTML5やCSS3を使う場合、いくつか補助プログラムを読み込んだり、制作上の注意点があります。これは、きちんとHTML5やCSS3の仕様を身につけていないと「動作しない」などのトラブルに見舞われることがあります。
この記事では、「なぜ、そうする必要があるのか」をキチンと書いて、仕様・仕組みを理解した上で使いこなすことができるようになる事を目標に書きました。
記事の内容
IE8で、HTML5のSectionsタグを使えるようにする「html5shiv.js」
「Sectionsタグ」とは以下のタグです。これはHTML5で定義されていますが、IE8では使えないもの(HTML5で追加した分)があります。これを使えるようにするのが「html5shiv.js」です。
section (HTML5から追加)
nav (HTML5から追加)
article (HTML5から追加)
aside (HTML5から追加)
h1-h6
header (HTML5から追加)
footer (HTML5から追加)
address
導入は以下のように「IE9より下のバージョンの場合はというバージョンベクタ」を使って読み込みます。ファイルはCDNで用意されていますので、それを使えば良いでしょう。
<!-- IE8対応(HTML5のSectionsタグ) --> <!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.js"></script><![endif]-->
これを使うことで、新しい「Sectionsタグ」がタグとして認識されます。それにより、CSSでの装飾がIE8でも効果が出るようになります。
IE8で、CSS3のセレクタを使えるようにする「selectivizr.js」
「CSS3の新しいセレクタ」はIE8では対応していません。これは、よく使う「:last-child」が含まれるので、ぜひ対応しておきたいものです。そして、これを使えるようにするのが「selectivizr.js」です。
導入は以下のように「IE6以上かつIE8以下のバージョンの場合はというバージョンベクタ」を使って読み込みますが、推奨記述がそうなっていたので、それを踏襲しています。ファイルはCDNで用意されていませんので、自分でダウンロードする必要があります。
<!-- IE8対応(CSS3のセレクターに対応、CSSより前に読み込む) jQueryはv1の使用が必須 --> <!--[if (gte IE 6)&(lte IE 8)]> <script type="text/javascript" src="js/selectivizr-min.js"></script> <![endif]-->
【selectivizr.js の問題点】
・CSS指定は外部ファイル(*.css)で使う
・CSSを読み込む前に「selectivizr.js」をロードする
・jQueryと併用する
・jQueryはIEをサポートしている「1.X.X」のバージョンを使う
・これを使っても「css3-mediaqueries.js」を適用してMediaQuery内に書いた「:last-child」などは動作しない
HTML5のテンプレートで、jQueryの読み込みで以下のような記述方法をしている場合は、きちんと両方とも「1.X.X」のバージョンを使うように指定してください。
<!-- jQuery(メイン読み込み) ================================================== --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
「selectivizr.js」を使うことで、IE8でもCSSやjQueryでCSS3の新しいセレクタを使うことができるようになります(全部ではありません)。
IE8で、rgba(透明度指定)を使えるようにする「IE独自フィルター」
IE8以下では、透明度の指定できる「rgba」を使うことができません。
また、確実で楽な方法もありません。
これは、IE独自フィルターを使う方法が一番確実です。指定はCSSで行います。
ただし、背景色でしか使えません。つまり、borderでは使えません。
【IE8でrgbaに対応する場合の問題点】
・背景色だけしか使えない(borderでは不可)
.og { filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#55ffffff,EndColorStr=#55ffffff); background:rgba(255,255,255,.4); }
一例ですが、class「.og」を作り、それにIE用の「filter」を指定します。
単色(非グラデーション)の場合は、「StartColorStr=#55ffffff」や「EndColorStr=#55ffffff」のように、同じ配色で大丈夫です。
「#55ffffff」の赤字が透明度です。00~FFの間で指定します。00に近いほど透明度が高くなります。下6桁は色コードです。
複雑なグラデーションを使う場合は、以下のサイトでジェネレートすると良いでしょう。
「Preview」の”IE”にチェックし、「Color format」は”rgba”、”IE9 Support”にもチェックします。
使うには、HTMLのhead内に以下のスタイルを定義しておきます。
<!--[if gte IE 9]> <style type="text/css"> .gradient { filter: none!important; } </style> <![endif]-->
その上で、生成したCSSを使う場合に「class=”*** gradient”」という指定の仕方を行います。
IE9の場合だけは、rgbaとIE用のfilterが同時指定されると、どっちも有効になってしまい、角丸を付けた時に「filter」のほうが残って、4隅に色が残ってしまうからです。
.c00 { background-color:rgba(94,94,94,.2); border-color:rgb(94,94,94);/*IE8以下用*/ border-color:rgba(94,94,94,.4); filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#555e5e5e,EndColorStr=#555e5e5e); }
IE8でも動作するCSSグラデーションを生成できるWebサービスはこちらです。
IEでblur(ブラー効果-ぼかし)を使う
こんなものはフォトショップでという方は、そのほうが良いと思います。巷で流行っているようですが非常に使いづらい命令です。
CSSに以下のclassを作ります。
IE9以下は「IE独自フィルター(filter)」で対応することになります。
.blur /* IE用filterはIE9以下で動作、IE10+では機能削除でblurには非対応 「background-image」とは併用可能だが、「background(背景色)」だと分からない 親要素の背景画像はボヤけない */ { filter:blur(1px); -o-filter:blur(1px); -ms-filter:blur(1px);/*IE10+は機能しないので実質不要*/ -moz-filter:blur(1px); -webkit-filter:blur(1px); filter:url(#blur);filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='1'); }
大問題はIE10以上では使えないことです。
【blur()の問題点】
・IE10で使えない(IEフィルターも使えない)
左がIE10、右がChromeです。
IE9以下は「filter」で対応できます。
左がIE9(filter使用)、右がChromeです。
IE10以上では「IE独自フィルター(filter)」は機能削除になりました。つまり、実質的にIE10ではブラー効果は使えません。上記のベンダープレフィックスは実際には無用です。
「IE10以上では使えない」というのは、実質使えない効果ということになります。この時点で不採用です。
あと、他のどのブラウザでも指定した要素はボヤけるので、子孫要素のテキストもボヤけるという面倒臭さもあります。これは、「potision」などを使って、兄弟要素にテキストを記述する方法で回避しますが、本記事と無関係なので解説は省きます。
さらに、背景画像とは併記可能ですが、背景色と併記しても見た目わからないので意味がありません。
ちなみに、親要素の背景はボヤけませんので、背景画像をボヤかしたい場合は、blurを指定した要素の背景に画像を指定することになります。以下の図のようなものはボヤけません。
ブラー効果(blur)がIE10 or 11でサポートしていないので、ブラー効果は不採用で決まりということになります。
ブラー効果で親要素の背景がボケて見えるようにする方法
では、IE10以上は置いといて、こちらのサンプルプログラムではどのようにして、親要素(HTMLタグの背景)の背景画像をぼやかしているのでしょうか。
これは、ブラー効果の背景は「HTML全体の背景」ではないのです。
以下に方法を記述しますが、「IE8以下は非対応」です。なぜ、「非対応」かというと、背景画像に対して「background-size:cover」を指定する必要があるのですが、これがIE9から対応だからです。
前述のように、blurがIE10+で動作しないのでは、実質的にIE9でしか使えない方法です。やはり、ブラー効果(blur)はデザイン的に不採用でなければなりません。
ということで、以下はChromeくらいでしか動作しませんので、ご注意ください。
CSSには「inherit」という指定があります(IE8+)。これは、本来は「backgorund-color」や「background-image」が親要素の内容を「継承しない」になっているのを「継承する」に変更することができます。(次で紹介する「PIE.htc」との併用はできません)
.blur { background: inherit; filter:blur(1px); -o-filter:blur(1px); -ms-filter:blur(1px);/*IE10+は機能しないので実質不要*/ -moz-filter:blur(1px); -webkit-filter:blur(1px); filter:url(#blur);filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='1'); }
一番上に「background: inherit;」が追加されました。
こうすることで、親要素の背景にある画像が、このブラー効果を行う要素にも継承されることになります。
しかし、これだけだと「ブラー効果のある要素の背景は、親要素の背景とズレて見える」ことになります。(以下図)
これは、当然ですが、ブラー効果のある要素の背景と、その親要素の背景は別々にレンダリングされているからです。
そこで、背景に少し工夫をします。
.bg { background-image:url("../img/sample250x250.png"); background-attachment:fixed; background-repeat:no-repeat; background-size:cover; }
「background-attachment:fixed」で、背景画像の位置を固定して、スクロールしても動かなくします。
そうすると、ブラーのかかった要素と親要素の背景がちょうど同期した位置になります。
あとは、背景に一枚だけ並ぶようにして(background-repeat:no-repeat)、それをブラウザサイズに合わせて表示させます(background-size:cover)。
なお、「background-size:cover」がIE9以上でしか使えないという問題がありますが、なかにはjQueryプラグインでIE8に対応させる「jquery.backgroundSize.js」というものや、IE8ハック的なものを紹介しているブログがあります。しかし、縦スクロールの長いページでは使えないなどの不具合があって、実用的にはいまいちです。
結局、このブラー効果というのは、2013年末の時点では、まだ時期尚早ということになると思います。
なお、別の方法で、jQueryプラグインの「blur.js」というのもありますが、これもIE8は非対応でした。
IE8で角丸やbox-shadowを適用する方法(PIE.htc)と注意点
結論から述べますと、IE8対応を考えるなら、角丸とbox-shadowは使わない(フラットデザイン)にすべきだと思います。理由は以下に記述します。
まず、box-shadowはIE9以上で対応しています。ベンダープレフィックスも必要ありません。
以下は、ボックスシャドウで外側に白い影と内側にも黒い影を指定したものです。ただし、記述に注意しないとIE11以下(現時点で全IE)では表示されなくなってしまいます。
box-shadow: 0 1px 0 rgba(255,255,255,1) inset, 0 -2px 10px rgba(0,0,0,.1); -webkit-box-shadow: 0 1px 0 rgba(255,255,255,1) inset, 0 -2px 10px rgba(0,0,0,.1); /* Safari,Google Chrome用 */ -moz-box-shadow: 0 1px 0 rgba(255,255,255,1) inset, 0 -2px 10px rgba(0,0,0,.1); /* Firefox用 */
(1) ベンダープレフィックスのない「box-shadow」を一番先に書く
ベンダープレフィックスのない形式を最後に書いたものを多くみますが、一番最初でないと動作しないことがあります。
さて、IE8では角丸(border-radius)も使えません。これはIE9以上で対応になりました。指定としては、以下のように4角もしくは上2角・下2角というものを用意しておけば困ることはありません。ベンダープレフィックスは2つあれば良いでしょう。「!important」はつけといた方が良い場合が多いです。同じサイズの要素(wrapperとか)がある要素で使う場合は重なり具合で見えない場合があるからです。
/* 基本CSS(角丸装飾「.main」と同じ要素に指定。) IE8は非対応 */ .rd,.radius { border-radius:5px!important } .rd-t,.radius-top { border-radius:5px 5px 0 0!important } .rd-b,.radius-bottom { border-radius:0 0 5px 5px!important }
ただし、IE9では透明度を指定した「rgba」が背景色の際に、IE8用でfilterを併記していると、両方有効になってしまい、4角になにかがウッスラと出てしまいます。IE10ではこの現象は出ませんし、単色の背景色ならこの現象は出ません。対処方法は、前述の「IE独自フィルター」を参照してください。
IE8で角丸を実現するには「PIE.htc」を使うという方法しかありません。(前述の、IE8でのfilterによるブラー効果は使えなくなります)
しかし、有名な「.htc」ファイルを使う方法は、サーバが対応していない場合や、パスの通し方がバージョン途中で変わっているなどもあって、動作しない場合が結構あります。
おすすめはJavascriptバージョンです。
<!-- IE8対応(CSS3のbox-shadowとborder-radiusに対応) --> <!--[if (gte IE 6)&(lte IE 8)]> <script type="text/javascript" src="css/pie/PIE.js"></script> <![endif]-->
読み込みは、同じくバージョンベクタで読み込みます。IE6以上、IE8以下にしておきました。
あとは、読み込むだけではダメで、もうひとつJavascriptを実行するファイルを作成します。
私は、jQueryのスクリプトやプラグインを実行するために通常使っている「main.js」をHTMLから読み込んでいるのですが、今回はそれに追記しました。
//ページ読み込みが終わった時に処理を実行する //================================================== $(window).load(function(){ //処理を以下に記述 // PIE.js の実行 //================================================== $(function() { if (window.PIE) { $('.pie').each(function() { PIE.attach(this); }); } }) //ここまで });
そして、HTMLの方で「border-radius」や「box-shadow」を適用するタグに、class「pie」を適用します。
<div class="bs og02 rd pie"> <div>bs og02 radius pie</div> </div>
こうすることで、classに「pie」と指定したタグに「PIE」が適用されます。ここでは、class「bs」(box-shadow)と「rd」(border-radius)が指定された「div」タグに、同じくclassで「pie」を指定しています。
あとは、CSSにCSS3の命令を記述しておけば良いのですが、PIEでは「-pie-」というベンダープレフィックスを使わないと動作しない場合など、いくつか動作しない原因があります。
たとえば、以下のような複数背景画像の場合は、「background-image」ではなく「background」である必要があるのと、ベンダープレフィックスをつけた「-pie-background」でなければならないなどです。IE8で複数背景画像がPIEで動作しない場合は、これを疑ってください。
background-image:url('img/main-mask1.png'),url('img/main00.jpg'); -pie-background:url('img/main-mask1.png'),url('img/main00.jpg');
ただし、多くの制約と問題点があります。
たとえば、「background-color: #XXXXXX!important」のようにimportantを付けた背景色のパーツはPIEで角丸にならないなどです。たくさんあるので、以下にまとめました。
【PIE.htc の問題点】
・jQueryはv1の使用が必須
・角丸のついた要素を表示・非表示するJavascriptで制御すると表示位置がズレる
・背景色がないと角丸が表現されない。
・背景色にimportantを指定すると角丸にならない→例:「background-color: #XXXXXX!important
・rgbaの背景色では角丸にならない。
・背景色が無い場合でも、pieでbox-shadowをつけた要素には、pieのradiusは表示される
・ただし、box-shadowは背景色がないと一番背後にあるbox-shadowに見せかけている色が見えてしまう
・つまり、実質的に透明度指定(rgba)された背景色は使えない
・同じボックスサイズの外枠がある場合、radiusが下に隠れる場合もある
・その場合、「zoom:1;position:relative;」で角丸が上になるようにする方法もある
・しかし、IE10以上でPIEに依存しないで表示していた角丸が消える。
・複数背景画像を使う場合は「background」文しか使えない上にベンダープレフィックスで「-pie-background」にする必要があるが、それでも動作する場合としない場合がある。
・検証する場合は「Ctrl+F5」で強制リロードした方が良い
最悪なのは、最近では背景色に透明度を使う場合があるのですが、それ使うとbox-shadowの仕組みが透けて見えてしまうということになります。つまり、背景色は非透明でないとダメなのです。
また、角丸も背景色がないと表示されませんが、透明度指定した背景色では角丸になりません。
こういった時に、Javascript版だとHTML上に「.pie」を指定しないという回避策を取ることができます。背景が透明色のところで、角丸やbox-shadowがあるところでは、個別にPIEを使わないという指定ができるメリットがあるわけです。
あと、巷のブログなどで書かれている「zoom:1;position:relative;」を使うと、IE10以上では角丸が消える不具合もあります。
box-shadowをボーダの代わりに使うようなデザインではPIEは使えませんね。
IE8で、MediaQueryを使えるようにする「css3-mediaqueries.js」
これは、Googleの「css3-mediaqueries.js」を使うことで使用可能になりますが、これも問題があります。
<!-- IE8対応(MediaQuery) =========================================================== --> <!-- css3-mediaqueries.js 「selectivizr.js」より先に読む必要あり CSS3セレクターの「last-child:」を「MediaQuery」で使うと効果ない模様 --> <!--[if lt IE 9]> <script src="//css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]-->
HTMLのヘッダー部分に上記を読み込ませるだけで対応できますが、下記の注意点があります。
- 「selectivizr.js」より先に読み込む必要がある。
- MediaQueryが書かれたCSSファイルはひとつだけにしなければならない。
- MediaQueryが読み込まれる際に、何度もリサイズイベントが発生する。
- resize()を使ったプログラムとの併用は動作しない場合がある。
こういった問題はあるものの、IE8の「MediaQuery」使用は非常に便利です。よって、Javascriptなどでリサイズイベントを使うスクリプトは組まないという設計が重要になります。(そうでなくとも、経験的には、リサイズイベントを使うようなスクリプトは開発しない方が良いと思います)
Font-Awesomeとの相性
IE8に限らないのですが、IE系でFont-Awesomeを疑似要素の「:before」「:after」を使って利用する場合にIE10でも表示できない場合があります。発生条件は不明なのですが
.menu ul li a:not(:only-child):before { content: '\f196'; font-family: 'FontAwesome'; }
こういった使い方でIE8ではアイコンは表示できません(「selectivizr.js」を使ってもダメ)
ただ、以下はIE8でも動作します。
.menu ul li a[href^="/index."]:before { content: '\f015'; font-family: 'FontAwesome'; }
「:before」「:after」はIE8でも使えるのですが、「:not()」や「:only-child」はIE8では使えません。それを「selectivizr.js」で強引に対応させてもダメということになります。
参考:擬似要素(before,after)と「content:」を使う場合の注意点
総括
最近では、IEの仕様が標準化になったり、IEが標準化に近づいたりして垣根は小さくなっています。しかし、アップデートをしない管理者がいることで、まだまだ最新版ではないIEを使っている場合があります。
そういったユーザーでも「見られるべきだ」というご意見と「デザインには凝りたい」という希望を持ったクライアントが多かったことから、Web屋というのは時間を無駄に浪費してきました。これは、生産性を著しく低下させてきたと言っても大げさではないと経験上思います。
最新記事はトップページで!
京都発・地方が盛り上がるグルメや観光に撮影ロケ地の話題を提供!