n秒づつ遅らせてクラスを追加する
delayはアニメーションのみ
このような要件を実装するためによく使われるのは、以下のようにdelayを利用したロジックです。
[ex].200ミリ秒づつ遅らせてフェードインする
var $targets = $('.fade'); var delay = 200; $targets.each(function(i){ $(this).delay(i*delay).fadeIn(); });
ところが、delayというのはfadeIn/Outやanimateなどのアニメーションのためのメソッドのみに効くようで、 たとえば次のように、CSS3のプロパティを用いたクラスによるアニメーション制御には時差が生まれません。
一斉に同じタイミングでフェードインします。
※fadeクラスにinクラスが追加されると、opacityとtransitionの組み合わせによりフェードインアニメーションします。
var $targets = $('.fade'); var delay = 200; $targets.each(function(i){ $(this).delay(i*delay).addClass('in'); });
.fade{ opacity: 0; } .fade.in{ opacity: 1; transition: opacity 250ms; }
queueメソッドを利用する
そもそもdelayとはエンキューするよう命令するメソッドで、どうやらanimateやfadeIn/Outなどコールバック関数を持てるメソッドは内部的にエンキュー/デキューを行っているようです。
では、そうではないメソッドの場合はどうすればよいでしょうか。
内部的にエンキューする機能がないならば、明示的にエンキュー/デキューすればよいのです。
jQueryにはエンキュー/デキューするメソッドが用意されているため、こちらを利用すればねらいどおりの挙動を実現することができます。
queueメソッドにはイテレータ(下記例ではnextという引数で受け取っています)があり、こちらを実行することで、順次デキューできるようです。
var $targets = $('.fade'); var delay = 200; $targets.each(function(i){ var $this = $(this); $this.delay(i *delay).queue(function(next) { $this.addClass('in'); next(); }); });
こうすることで、クラスによる制御の場合でも、n秒づつ遅らせてアニメーションさせることが可能になります。
画面外に絶対配置した要素が表示されてしまう
iOS9におけるSafariなど一部のスマホブラウザでは、画面外に配置した要素が、表示されてしまうバグがあります
こちらの例では、右側にあるモーダルウィンドウは本来画面外にあり、ボタン押下時に画面中央に表示されるという仕組みになっているはずでした。
※ちなみにモーダルウィンドウは絶対座標(position:absoluteを指定)により配置されています。
ところがブラウザのバグにより、モーダルウィンドウの部分まで描画領域が確保されてしまい、表示崩れが起きてしまいました。
そのような場合は、画面外を表示しないような明示的にスタイルを指定すれば解決します。
html, body{ position: relative; width: 100%; overflow-x: hidden; }
これで、意図した表示になります。
メイリオで斜体を実装
メイリオには斜体がありません。
正確に申しますと、英数字は斜体にできるのですが、日本語の文字(漢字カナ)はfont-styleにitalicをしても斜体が効きません。
日本語でメイリオ、かつ斜体を実装するには、以下の方法で対応が可能です。
以前10px以下のテキストを表示する裏技を紹介しましたが、それと同様に、GPUアクセラレーションを用いて文字をゆがませることで疑似的に実装します。
.italic{ font-family: Meiryo, "メイリオ", sans-serif; -webkit-transform: skewX(-15deg); -moz-transform: skewX(-15deg); -o-transform: skewX(-15deg); transform: skewX(-15deg); -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=-0.26794919243112214, M21=0, M22=1, SizingMethod='auto expand')"; }
その後、下記の方法で斜体を実現できることがわかりました。
@font-face { font-family: Meiryo; src: local('Meiryo'), local('メイリオ'); } .italic{ font-family: Meiryo, "メイリオ", sans-serif; font-style: italic; }
出典はこちら。
transition + transform アニメーションが動かない
Safari(Windows版)の場合
本来ベンダープレフィックスはプロパティ名にのみ付けますが、Windows版Safariの場合はプロパティの値にもつけましょう。
-webkit-transition: transform 250ms linear; -webkit-transition: -webkit-transform 250ms linear; -moz-transition: transform 250ms linear; -ms-transition: transform 250ms linear; -o-transition: transform 250ms linear; transition: transform 250ms linear;
IE9の場合
IE9はtransitionに対応していないため、jQueryアニメーションなどで代用します。
各ブラウザでの対応状況は下記表のとおり。
IEで「いいね」ボタンが文字化けする
Helveticaが原因
IEでfacebookの「いいね」ボタンを実装すると、文字化けしてしまいました。
どうやら、デフォルトでHelveticaがフォント指定されているらしく、そのため文字化けを起こしてしまったようです。
IEとHelveticaとの相性の悪さは有名で、今回のように文字化けしてしまったり、フォントそのものが表示されないなど様々なものが報告されています。
今回もそのような例のひとつであるとのことですが、パラメータにて別のフォントを指定することが可能であるようです。
下記記事に各種実装方法における解決策が紹介されていましたので、抜粋しておきます。
/* iframe */ <iframe style="border: none; overflow: hidden; width: 110px; height: 21px;" src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2FXXXXX.XX.XX%2F&send=false&layout=button_count&width=110&show_faces=false&font=arial&colorscheme=light&action=like&height=21&appId=XXXXXXXXXXXXXX" frameborder="0" scrolling="no">
/* XFBML */ <fb:like href="//www.XXXXX.jp/" send="false" layout="button_count" width="110" show_faces="false" font="arial" data-mce-href="//www.XXXXX.jp/">
/* HTML5 */ <div class="fb-like" data-width="105" data-layout="button_count" data-show-faces="true" data-send="false" data-font="arial" data-href="//www.facebook.com/pages/XXXXXXX/XXXXXXXXXXXX">>
Likeboxも同じ要領で対応できるそうです。
IEで埋込みYouTubeが最前面に表示される
Flash特有の属性値を指定
スクロールに追従する固定ヘッダーを実装していたところ、IEでのみYouTubeを埋め込んだiframeがヘッダーより前面に表示されてしまうという現象が起きました。
本来は左図のようにヘッダーが最前面に表示されるべきところ、右図ではYouTubeが最前面になってしまっています。
これはレガシーなIEでのみ起こる現象ではなく、最新版のIEでも発生してしまいます。
z-indexを用いて重なり順を明示的に指定してみたのですが、効果はありませんでした。
調べたところ、wmodeというパラメータを指定すれば解決するそうです。
YouTubeをiframeで埋め込んだ際、iframe内にはFlashコンテンツが生成されるそうです。
Flashコンテンツには重なり順を指定するwmodeというパラメータがあり、デフォルトでは重なり順を無視して最前面に表示される「wmode=window」が設定されているとか。
これを「wmode=transparent」にすることで、背面に表示することが可能になります。
Flashの場合はembet要素の属性値として指定しますが、iframeによるYouTube埋込みの場合は、GETパラメータにこの値を指定します。
<iframe src="//www.youtube.com/embed/?wmode=transparent"></iframe>
これで、意図した表示に戻すことができました。
wmodeとは
僕自身はあまりFlashには馴染みがなかったので、wmodeという属性値について調べてみました。
- window
- SWF コンテンツは、Web ページ上で専用の長方形のウィンドウに再生されます。window を指定した場合、SWF コンテンツと HTML レイヤーは相互に影響し合うことはなく、Flash アプリケーションが常に最前面のアイテムになります。
- direct
- パスレンダリングを使用します。スクリーンバッファへの格納がバイパスされ、SWF コンテンツを直接画面に描画します。
- コンテンツ再生のパフォーマンスを重視する場合にこの値を指定してください。Stage Video や Stage 3D などを使用するハードウェアアクセラレーションが有効になります。
- opaque
- SWF コンテンツが、その他の HTML 要素と同一レイヤーに配置されます。
- SWF は不透明で、下層レイヤーにあるすべてのページ要素が非表示になります。
- window やdirect を指定した場合と比較して、再生パフォーマンスが低下します。
- transparent
- SWF コンテンツが、その他の HTML 要素と同一レイヤーに配置されます。SWF ファイルの背景色(ステージカラー)は透明になります。
- 透明領域の背面にある HTML 要素は表示され、透明度によってブレンドされます。
- window や direct を指定した場合と比較して再生パフォーマンスは低下します。
- gpu
- インターネット接続のテレビやモバイルデバイスなどにおける追加のハードウェアアクセラレーションを使用します。
- その他の値を指定した場合とは対照的に、表示データリストグラフィックにおけるピクセルの正確性は保証されません。
- その他の点については direct を指定した場合と同様です。
純然たるFlashコンテンツの場合、このwmodeによっては日本語の文字入力領域を設定しても入力ができないなど問題点があるそうですが、昨今ではさほど気にしなくてもよいでしょう。
Gmailで画像を非表示にできない
display:noneは無効
何かとクセの多いHTMLメールコーディングですが、Gmailは特に癖が多く、先日は画像の非表示ができないというバグに直面しました。
調べたところ、どうやらdisplay:noneは無効になってしまうとのことです。
こちらの記事よると、次のスタイルを指定することで非表示にできるとのこと。
<img alt="XXX" src="XXX" style="width:0px; min-height:0px;">
ただし、この方法だとOutlookでは表示されてしまうので、次の指定も追加します。
<img alt="XXX" src="XXX" style="width:0px; min-height:0px; display:none; mso-hide:all;">
mso-XXXとは、Outlook専用のハックのようなものです。
OutlookのレンダリングがWord(Microsoft Office Word) を利用していることが由来だとか。
WordドキュメントをHTML出力した際につけられるプロパティらしく、ほかにもmso-para-marginなど様々なものがあるとか。
余談
横道にそれてしまいますが、Outlookのみに有効な条件付きコメントが存在するそうです。
<!--[if gte mso 9]> <style type="text/css"> /* Outlook用のスタイルを記述. */ </style> <![endif]-->
確実に有効とは言い切れないそうですが、覚えておいて損はないでしょう。