スラッシュドットで 「Microsoft、「WebKitはWeb標準を破壊している」と主張」 なんてストーリーが上がってて、なんぞやと思って大本の記事を見に行ったんですけど、そしたらそれが 「Webkit しか対象にしてない Web サイトを IE10 でもきちんと動作させるためにやっといた方がいいことガイド」 っていうお役立ちコンテンツだったってことで、がんばって最後まで読んだ手前、ついでなので翻訳して掲載してみようかなと思います。
ちなみに翻訳元の記事は 「Windows Phone Developer Blog」 で書かれた内容なので、「Windows Phone 8 で動作する IE10」 っていう書き方になっている部分や、すべて Webkit と対比して書かれているなど、モバイル関連の内容に偏っている部分もありますが、Windows 版の IE10 でも参考になる点はいくつかあると思います。
で、この 「こうしとけば IE10 でも動くよ!」 っていう記事がなんで最終的に 「Microsoft が WebKit は Web 標準を破壊していると主張」 まで変化したんだっていう謎はよくわかりませんでした。ま、誤読が積み重なってってことなんでしょうね (怖い…)、元々はごく当たり前のことを書いているだけなんですけども。
でははじめます。書いてみたら思ったより長くてつかれたです…
原文
Adapting your WebKit-optimized site for Internet Explorer 10 : Windows Phone Developer Blog
Internet Explorer 10 が HTML5 を広範囲にサポートしたことで、あなたの Web サイトの機能を Windows Phone 8 上で最大限発揮させるのは以前より容易になりました。 あなたが現在、iOS や Android をサポートするために Webkit をターゲットに最適化された Web サイトを運用していたとして、そこに IE10 のサポートを加えるのはとても簡単です。
これは、あなたが最低限のコードでユーザーに対してより良いユーザー体験を与えることを意味します。また、あなたが加える必要がある修正のほとんどはあなたの Web サイトをより HTML5 準拠にします。
このガイドでは、Webkit に最適化された Web サイトを IE10 適応させるための Tips、ベストプラクティス、サンプルコードをまとめました。また、このガイドは実際に Webkit に最適化された人気サイトのいくつかを IE10 に適応させたチームの経験に基づいたものです。この記事が、あなたの Web サイトのアップデートに役立つでしょう。
- Step 1: Windows Phone 8 の IE10 を検出する
- Step 2: 標準準拠モードで動作させる
- Step 3: CSS と DOM API のアップデート
- Step 4: タッチとポインタイベントのアップデート
- Step 5: 標準以外の動作を制御する
Step 1: Windows Phone 8 の IE10 を検出する
あなたの Web サイトで ユーザーエージェントの検出を行っている場合、IE10 を検出する必要があります。我々は IE10 を検出する方法をいくつか公開していますが、例えば Windows Phone 8 上で動作する IE10 を検出するためのユーザーエージェント文字列は下記の通りです。
Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> [;<Operator>])
このプロセスの完了後、WebKit と IE10 の違いがまだ存在していて、あなたのサイトに影響を及ぼしているなら、ユーザエージェントによる検出ではなく、機能検出と、他のベストプラクティスを導入してみてください。
特に、Windows Phone 8 上の IE10 が、Flash ベースのビデオではなく HTML5 video を確実に取得するようにするのは非常に重要なことです。
一方で、すべてのサードパーティのライブラリもアップデートしてください。例えば、jQuery Mobile などで最新のブラウザに対応したものを確実に入手してください。例えば、Typekit を使用している場合、カスタムフォントキットを再度パブリッシュすることを推奨します。また、ビデオに Ooyala を使用している場合、最新版にアップデートする必要があります。
Step 2: 標準準拠モードで動作させる
次のステップは、Internet Explorer 10 が標準準拠モードでレンダリングを行っていることを再確認することです。標準準拠モードを使用することで、HTML5 や CSS3、SVG、その他の最新の標準技術を最大限に利用することができます。
これに対して 「後方互換モード」 は、下位互換性を保つことができますが、多くの Web サイトは標準準拠モードで動作するようになっているため、Web サイト側から標準準拠モードを使用するための特別な要求はされません。これを確認する最も簡単な方法は、全ページの先頭に HTML5 doctype (文書型宣言) を加えることです。
<!DOCTYPE html>
また、標準準拠モードは 「Transitional」 を指定しない限り、HTML 4.0+ と XHTML 1.0+ の正しい文書型宣言に対してもデフォルトになります。
ローカルネットワーク (または localhost) で Web サイトをテストしている場合、一時的に標準準拠モードを強制する必要があります。なぜなら、IE はこれらの Web サイトに対しては後方互換モードがデフォルトとして設定されているからです。ページの <head> タグに以下のタグを追加するか、または、同じ意味を持つ HTTP ヘッダを追加することで標準準拠モードを強制できます。
<meta http-equiv="x-ua-compatible" content="IE=edge" />
インターネット上に Web サイトを公開した後、不要になった <meta> タグは削除することができます。
下記のようなことをすると、Web サイトが正しく標準準拠モードでレンダリングされません。
- 文書型宣言が全く書かれていない場合。
- 文書型宣言として 「Transitional」 が指定されている場合。
- x-ua-compatible ヘッダで IE=9 (またはそれより古いバージョン) など、特定の IE モードを強制している場合。代替として、IE=edge を指定するか、x-ua-compatible ヘッダの使用をやめて、HTML5 の文書型宣言を使用してください。
Step 3: CSS と DOM API のアップデート
ここまでで、ソースコードのアップデートをする準備が整いました。アップデートの最初の取り組みとしてまずは WebKit をターゲットにした CSS または JavaScript の記述を、標準に準拠した (ベンダプレフィックスなし)、に変更、または Microsoft のベンダプレフィックス付きのものを加えてみましょう。
あなたのサイトでは、習慣として多くのベンダプレフィックスがすでに使われているかもしれません。その他にも、多少のリファクタリングが必要ないくつかの CSS アップデートや、ビヘイビアの実行に関して変更された点があるかもしれません。
ベンダプレフィックスなしの CSS プロパティ
まず最初にベンダプレフィックスなしの CSS プロパティについて調べてみましょう。当初、WebKit 向けベンダプレフィックス (-webkit-) 付きでサポートされはじめたプロパティの中には、Internet Explorer 10 や他のブラウザで、ベンダプレフィックスなしでのサポートが開始されているものもあります。これら、すでに -webkit- プレフィックスが不要なプロパティを使用するには、「-webkit-」 プレフィックスを削除した行を元の記述の次行に加えるだけです。また、この修正は、WebKit を使わない他のブラウザへのサポート提供に役立ちます。
例えば下記のようになります。CSS プロパティだけでなく、JavaScript から同等のプロパティを指定する際にも影響しますので注意しましょう。
Before | After |
---|---|
-webkit-border-radius: 0; | -webkit-border-radius: 0; border-radius: 0; |
a.webkitTransitionDuration = "5ms" | b.webkitTransitionDuration = b.transitionDuration = "5ms"; |
this.element.addEventListener("webkitTransitionEnd", this, false); | this.element.addEventListener("webkitTransitionEnd", this, false); this.element.addEventListener("transitionend", this, false); |
[訳者補足]
ちなみに上記で書かれている、「ベンダプレフィックス付きの記述とあわせて、最後にプレフィックス無しの記述をしておく」 っていうのは基本中の基本ですので、サポート対象ブラウザ関係なく忘れないようにしましょう。
一般的に使用される WebKit プレフィックス付き CSS プロパティと IE10 でサポートされている標準 (接頭辞なし) 形式のプロパティを挙げてみます。それぞれ、JavaScript を介してアクセスすることができる同等のスタイルプロパティを持っています。例えば、border-radius は JavaScript で object.style.borderRadius を指定してアクセスすることができます。
WebKit version | Standards-based version |
---|---|
-webkit-animation | animation |
-webkit-animation-delay | animation-delay |
-webkit-animation-direction | animation-direction |
-webkit-animation-duration | animation-duration |
-webkit-animation-fill-mode | animation-fill-mode |
-webkit-animation-iteration-count | animation-iteration-count |
-webkit-animation-name | animation-name |
-webkit-animation-play-state | animation-play-state |
-webkit-animation-timing-function | animation-timing-function |
-webkit-background-clip | background-clip |
-webkit-background-size | background-size |
-webkit-border-radius | border-radius |
-webkit-border-bottom-left-radius | border-bottom-left-radius |
-webkit-border-bottom-right-radius | border-bottom-right-radius |
-webkit-border-top-left-radius | border-top-left-radius |
-webkit-border-top-right-radius | border-top-right-radius |
-webkit-box-shadow | box-shadow |
-webkit-box-sizing | box-sizing |
-webkit-background-clip | background-clip |
@-webkit-keyframes | keyframes |
-webkit-transform | transform |
-webkit-backface-visibility | backface-visibility |
-webkit-transition | transition |
-webkit-transition-property | transition-property |
-webkit-transition-duration | transition-duration |
-webkit-transition-timing-function | transition-timing-function |
webkitrequestanimationframe | requestAnimationFrame |
その他、あまり使われる頻度は高くないと思いますが、「CSS Multi-column Layout Module」 などもベンダプレフィックス不要で使えるプロパティに含まれています。
ベンダプレフィックスが必要な CSS プロパティ
次に挙げる CSS プロパティは、現時点で W3C による仕様策定が十分に進んでいないため、IE10 においても Microsoft のベンダプレフィックス (-ms-) 付きで使用する必要があります。これらに対する対応状況の詳細についてはこちらで確認することもできます。
WebKit version | IE10 version |
---|---|
-webkit-text-size-adjust | -ms-text-size-adjust |
-webkit-user-select | -ms-user-select |
-webkit-box | -ms-flexbox |
-webkit-box-align | -ms-flex-align |
-webkit-box-pack | -ms-flex-pack |
CSS Gradients
CSS Gradients に関しては、仕様策定の過程で記述方法が更新されています。具体的にはグラデーションの形状 (例えば、linear / radial など) や色の指定方法に違いがあります。IE10 における CSS Gradients のサポートに関して詳しくは 「Gradients (Windows)」 をお読みください。例えば下記のような記述になります。
[訳者補足]
ここから先、ちょっと原文とはソースコードの記載方法を変えています。
Before
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#000000));
After
background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#000000)); background: linear-gradient(to bottom, #ffffff, #000000);
CSS Flexbox
CSS Flexbox は IE10 でサポートされました。詳しくは 「Flexible box ("Flexbox") layout (Windows)」 をご覧ください。例えば下記のような記述になります。
Before
-webkit-box-orient: vertical;
After
-webkit-box-orient: vertical; -ms-flex-direction: column;
リンクが設定された画像周辺の枠線
画像に対してリンクが設定されている場合、Internet Explorer はそれがリンクであることを示すために、デフォルトで画像の周囲に青色の枠線を描画しますが、WebKit はこれを行いません。この機能を無効にする簡単な方法は、明示的に次のような CSS を使用して、リンク付きの画像には枠線を表示しないようにできます。
a img { border: none; }
CSS border-image
IE10 は border-image をサポートしません。すでにあなたの Web サイトで使用されている場合は、レイアウトを保つためのフォールバックとして、既存の border-style プロパティを指定しておきましょう。
Before
padding: 8px 0 8px; -webkit-border-image: url(border.png) 5 5 5 5 repeat repeat; border-width: 5px;
After
border-style: solid; border-color: #fff; padding: 8px 0 8px; -webkit-border-image: url(border.png) 5 5 5 5 repeat repeat; border-width: 5px;
Step 4: タッチとポインタイベントのアップデート
Webkit と IE10 はタッチイベントの制御方法が異なります。Webkit は マウスイベントとは別にタッチイベントを実装していますが、IE10 は、「ポインタ」 イベントによってマウス、タッチ、スタイラスなど様々な入力をイベントを 1つにまとめて処理できるようになっており、この仕様は標準技術として使用できるよう、W3C のワーキンググループにて議論が行われています。ポインタイベントの実装は、少ないコードの修正で対応可能です。
ポインタ イベントリスナーの組み込み
ポインタイベント API では、標準として down、move、up の各イベントモデルが使用されます。既存のイベントリスナーにポインタイベントを加えるのは簡単です。
Before
this.element.addEventListener("touchstart", eventHandlerName, false); this.element.addEventListener("touchmove", eventHandlerName, false); this.element.addEventListener("touchend", eventHandlerName, false);
After
if (window.navigator.msPointerEnabled) { this.element.addEventListener("MSPointerDown", eventHandlerName, false); this.element.addEventListener("MSPointerMove", eventHandlerName, false); this.element.addEventListener("MSPointerUp", eventHandlerName, false); } this.element.addEventListener("touchstart", eventHandlerName, false); this.element.addEventListener("touchmove", eventHandlerName, false); this.element.addEventListener("touchend", eventHandlerName, false);
ポインタイベントを制御する
すべてのイベントが 1つのイベントリスナーに設定されている場合、イベントの種類に応じて分離して追加する必要があります。例えば下記のように。
Before
switch (event.type) { case "touchstart": this.onTouchStart(a); break; case "touchmove": this.onTouchMove(a); break; case "touchend": this.onTouchEnd(a); break; }
After
switch (event.type) { case "touchstart": case "MSPointerDown": this.onTouchStart(a); break; case "touchmove": case "MSPointerMove": this.onTouchMove(a); break; case "touchend": case "MSPointerUp": this.onTouchEnd(a); break; }
プライマリタッチポイントの検出
前述したように、ポインタイベントモデルでは、各タッチポイントごとに個別のイベントを発生させます。あなたがプライマリタッチポイントのみ (例えば、シングルタッチで行うドラッグなど) を処理したい場合、「up」「move」 イベントの前に次のようなコードを追加し、プライマリタッチ以外を除外する必要があります。
if (window.navigator.msPointerEnabled && !event.isPrimary) return;
タッチ座標を取得
ポインタイベントモデルでは、各タッチポイントごとに別々のイベントが発生し、イベントオブジェクトに座標が直接渡されているため、pageX と pageY プロパティを使用してアクセスすることができます。例えば次のように組み込むことができます。
Before
var curX = event.targetTouches[0].pageX;
After
var curX = event.pageX || event.targetTouches[0].pageX;
マウスによる入力を制御する
IE10 が採用している仕組みの 1つのメリットとして、マウス入力も同じイベント内で処理できることです。IE10 はマウスが領域内にある場合、「move」 イベントを発生させます。例えばドラッグ動作を実装する場合、ユーザーがマウスボタンを押しながらマウスを移動している間だけ、処理を実行したいと思いますが、pointerType を使用することで、その検出が可能です。
if (window.navigator.msPointerEnabled && ((event.pointerType == evt.MSPOINTER_TYPE_TOUCH && event.buttons != 1) || !a.isPrimary)) return;
タッチ動作を無効にする
IE10 のポインタイベントでは、ある領域に対してポインタイベントを有効にするかどうかを明示的に示すことができます。そのために -ms-touch-action プロパティを使用しますが、下記のように指定することで、その領域に対するタッチ動作を無効にできます。
Before
<div id="slider" style="overflow: hidden;">
After
<div id="slider" style="overflow: hidden; -ms-touch-action: none;">
IE10 では、pan-x、及び pan-y プロパティがサポートされ、水平方向、垂直方向へのジェスチャを制御できます。
Step 5: 標準以外の動作を制御する
最後のステップは、標準技術が存在しない部分の制御に関してです。WebKit と IE10 でアプローチは異なりますが、Web サイト上で共存させることができます。
リンクの強調表示を無効にする
iOS 上の Safari、Windows Phone 上の IE10 など、一部の携帯ブラウザではリンクをタップした際にハイライト処理を行いますが、タップ時の見た目を Web サイト制作者側でコントロールするため、このデフォルト処理を無効にしたい場合もあると思います。次のように制御できます。
WebKit solution
a { -webkit-tap-highlight-color: rgba(0,0,0,0); }
IE10 solution
<meta name="msapplication-tap-highlight" content="no" />
msapplication-tap-highlight が head 要素内で指定されると、それはページ内すべてのリンクに作用することに注意してください。また、この指定は、Windows Phone 上の IE10 に対してのみ有効で、Windows 上の IE10 には適用されません。
ドロップダウンリストに表示される標準スタイルを無効にする
-webkit-appearance プロパティは Webkit の標準的なインターフェースを表現するデフォルト設定を制御するための指定ですが、通常 IE10 には無関係です。しかし、select 要素に対して text-indent で選択肢のテキストを非表示にしたり (でも選択時には項目は表示される)、ドロップダウン矢印を非表示した上で背景画像を指定して見た目をカスタマイズしたい場合、IE10 で同じ効果を実現する方法は下記のようになります。
WebKit solution
CSS
select { -webkit-appearance: none; text-indent: -5000px; }
IE10 solution
CSS
select::-ms-expand { display: none; }
HTML (一番最初の選択肢を空にする)
<select> <option></option> … </select>
[訳者補足]
最初、上記の select 要素の話は 「何言ってんの?」 って感じだったんですが、実際にサンプルコード動かしてみて謎が解けました。select 要素で作るプルダウンメニューの見た目をボタンみたいにしておいて、クリックされたら動作自体はプルダウンメニューっていうのを実現するってことなんですね。Webkit なら -webkit-appearance: none; した上で text-indent で選択肢テキストを画面外にぶっ飛ばすだけで、プルダウンの矢印も一緒に消えてくれるみたいですが、IE10 だとその指定が効かないので、先頭の option 要素を空にした上で、CSS で矢印を消せばいいと。
以上、翻訳終わりです。