「HTML 5.1」の新機能を理解する
2016年11月1日付けでW3CはHTML 5.1を勧告した。これは2014年10月28日付けで勧告されたHTML5をバージョンアップするものだ。本稿ではその主な追加機能などをざっくりと見ていくことにしよう(なお、本稿ではメジャーバージョンのみを付加する場合には「HTML5」と、マイナーバージョンを含める場合には「HTML 5.1」などと表記する。これはW3Cでの仕様における表記とも合致している)。
●そもそもHTML5とは
新機能の話をする前に「HTML5とは」について少し考えておきたい。1つは誰が仕様を策定しているか。もう1つはHTML5の位置付けだ。
○仕様を策定するのは誰か?
前者に関していえば、現在、HTMLはWHATWG(Web Hypertext Application Technology Working Group)とW3Cという2つの組織によって仕様策定が行われている。前者が策定しているのは「HTML Living Standard」と呼ばれるもので、後者が策定しているのが「HTML5」「HTML 5.1」と名前に「5」が含まれているものだ。
WHATWGが策定するHTML Living Standardは、さまざまなユーザーからのフィードバックを受け取りながら継続的にアップデートされていく。いわば動的な仕様であり、Web技術が日々進化していくのに合わせて、HTMLの仕様もそれに沿ったものにしていこうというものだ。
これに対して、W3Cが策定するHTML 5.xはHTML Living Standardを基にしたスナップショットのようなものといえる。ただし、両者が策定するHTML仕様はほぼ同じでありながら、微妙に異なる点が双方に存在するなど、扱いが難しいところもある。最新の仕様に追従するならHTML Living Standardを見ていくのが最適かもしれない。
ちなみに、HTML 5.1の勧告はHTML5の勧告から2年が経過してからのものとなったが、次バージョンであるHTML 5.2は2017年11月の勧告が予定されており、現在はHTML 5.2のワーキングドラフトが公開されている。
○HTML5の位置付け
ここでいう「HTML5の位置付け」とはつまり「HTML5が何を目的として策定されたものか」である。
上で見たように、(W3Cが策定する)HTML 5.x仕様自体はHTML Living Standardのスナップショットともいえるものであり、一方でHTML Living Standard自体は日々アップデートが続けられる。このことから、HTML5仕様のマイナーバージョンアップには「何かを目的としてこのようなバージョンアップが行われたもの」というよりも「期間を区切って、その期間内で組み込まれたり、変更されたり、取り除かれたりした機能をとりまとめたもの」という意味合いがこれからは強くなっていくだろう(もちろん、そこには何らかの意図や目的があるはずだが、それらの意図や目的とバージョンアップはリンクしないということだ)。
なお、こうした流れはWeb標準技術のように進化の速い技術分野ではこれから一般的になっていくだろう(例えば、ECMAScriptの仕様策定も期間を区切って、新バージョンに含める機能/含めない機能が決まるようになっている)。
では(キーフレーズとしての)HTML5は何を目的として作られたか。HTML Living Standardが意図しているのは「従来のHTML関連の仕様に含まれていた問題点を解消すると同時に、より適切にWebアプリに対応できること」だ。一方、W3CのHTML 5.1仕様の冒頭には「このバージョンでも、Webアプリ開発者の助けとなるように新たな機能が追加され、広く行われているWeb開発手法に関するリサーチを基にして新たな属性が追加され、相互運用性を高めるべく、ユーザーエージェントが従うべき規則に特に注意が払われている」(意訳*1)という記述がある。
両者に共通することをまとめると「ブラウザでのWebページ表示がこれまで通りに行えるようにする」とともに「Webアプリ開発に適した新たなHTML仕様を策定しよう」ということだ。これまでの遺産との互換性を維持する一方で、進化を続けるWebの世界、特にアプリとしてはWebの開発に適した言語とすることがいわゆる「HTML5」の目的といえる。
Webアプリ開発のためにHTML5仕様で追加されたAPIについては「HTML5 Differences from HTML4」の「5.1 New APIs」などを参照されたい(「Webアプリ開発で役立つ多くのAPIが導入されている」とある)。
*1 この部分はHTML 5.1仕様では「new features continue to be introduced to ……」のようになっている。「continue to be」の意味が一瞬分からないのだが、HTML5仕様でこの部分を見ると「new features are introduced to ……」となっている。つまり、「HTML5では新機能が追加されたけど、HTML 5.1でも引き続いて新機能が追加されたよ」ということだ(「差分をチェックするのは大事」ということだ)。
加えて、もう1つ重要な要素がある。それは「ドキュメントやWebアプリのマークアップをよりよいものとする」ことだ。この観点から、CSSなどで対処が可能なプレゼンテーション要素が仕様からは除外され、同時に「要素のカテゴリとコンテンツモデル」(ある要素がどんなカテゴリに分類されるもので、そこにどんな要素を含められるかを規定)という概念や「文書の構造を記述するための新たな要素」(<section>要素など)が導入されたといえる。
HTML5の位置付けについて見たところで、次ページではHTML 5.1で追加された機能についてざっくりと見ていこう。
●HTML 5.1の新機能
HTML 5.1仕様の「Changes」ページには、HTML 5.1における変更点がまとめられている。また、各ブラウザでの実装状況は「HTML 5.1 Implementation report」で確認が可能だ。ただし、実際の実装状況とは異なるかもしれないので注意は必要だ。例えば、このページでは「Add oncopy」「Add oncut」「Add onpaste」がEdgeでは未実装となっているが、筆者の環境ではEdgeでもこれらのイベントは使用可能となっていた。また、前者のページにはなくとも後者のページには含まれている新機能や変更点(またはその逆)もある。
追加された機能を幾つか列挙しておこう。
・レスポンシブなイメージ選択
・<summary>要素と<details>要素の追加
・コンテキストメニューの追加
・<input>要素での週/月/ローカルな日付と時間の入力が可能に
・oncopy/oncut/onpasteイベントの追加
・requestAnimationFrame APIによるアニメーション効果
・etc
以下ではこれらのうち、幾つかを例示する。コンテキストメニューや<input>要素での週の入力については「Dev Basics/Keyword HTML 5.1」でも取り上げているので、興味のある方はご覧いただきたい。リンク先ではレスポンシブなイメージ選択も取り上げているが、さすがにこれを無視するわけにはいかないので、以下ではまずこれを見てみよう。
○レスポンシブなイメージ選択
<picture>要素とsrcset属性では、ピクセル密度やビューポートサイズなどに応じて複数のイメージから適したものを選択できるようになった。
ピクセル密度に応じてイメージを選択するには、以下のようなコードを記述する。
<picture>
<source srcset="./image@1x.png 1x, ./image@2x.png 2x">
<img src="./image@1x.png" alt="sample image">
</picture>
この例では<picture>要素内に<source>要素と<img>要素を配置し、<source>要素のsrcset属性で複数のファイルを指定している。各ファイル名の後ろにある「x1」「x2」がピクセル密度を表している(これをピクセル密度記述子と呼ぶ)。よって、この場合は通常のピクセル密度であればimage@1x.pngファイルが、ピクセル密度が2倍であればimage@2x.pngファイルが画面に表示される。
また、これは以下のようにも記述できる。これは<picture>要素を使わずに、<img>要素のsrcset属性を使用したものだ。
<img alt="python" src="./image@1x.png"
srcset="./image@1x.png 1x, ./image@2x.png 2x">
最近のスマートデバイスではピクセル密度が、PCの標準的なディスプレイと比べて高いのが一般的であり、高精細なディスプレイに対しては高精細な画像を表示するのがよい。その一方で、このような記述を行うことで、レスポンシブな対応ができるようになる(HTMLコードは同一で、レイアウトや画像ファイルをPC/スマートデバイスで切り替えることで、個々のデバイスに適合した表示を得られるようになる)。
ビューポートのサイズに応じてイメージを選択するには、例えば以下のようなコードを記述する。
<picture>
<source media="(max-width: 500px)" srcset="./image-lt-500.png">
<source media="(max-width: 1000px)" srcset="./image-lt-1000.png">
<source srcset="./image-gt-1000.png">
<img src="./image-lt-500.png" alt="sample image">
</picture>
ここではメディアクエリを用いて、画面幅の(論理的な)ピクセル数を条件にファイルを選択している。この場合はピクセル数に応じて、image-lt-500.pngファイル(500px以下)、image-lt-1000.pngファイル(1000px以下)、image-gt-1000.png(1000pxより大きい)が表示される。
以上のコードを含んだWebページをBliskで表示した例を以下に示す。
デスクトップブラウザとスマートデバイスで表示されている画像が切り替えられていることが分かるはずだ(上の2つはピクセル密度で切り替えられ、一番下の画像はビューポート=画面の横幅を基準に切り替えられている)。
なお、上のWebページではHTML5で追加された<figure>要素を使って、以下のようなコードを記述している。
<figure>
<img alt="python" src="./image@1x.png"
srcset="./image@1x.png 1x, ./image@2x.png 2x">
<figcaption>sample figure</figcaption>
</figure>
<figcaption>要素は図版のキャプションを表すものだが、HTML 5.1では<figure>要素内であればどこに記述してもよいようになった(HTML5では<figure>要素の先頭の子要素もしくは最後の子要素として記述する必要があった)。
ピクセル解像度や画面サイズに応じて表示する画像ファイルを切り替えるのは、Webアプリが広く使われ、それらにアクセスするデバイスも多種多様である現在の状況では非常に重要な要素である。HTML5がWebアプリのための新たなHTMLだとすると、今見た追加機能はHTML5ベースのWebアプリをモバイルフレンドリーにするためのものだといえる。
○効果的なアニメ処理を行うためのrequestAnimationFrame API
requestAnimationFrame APIはJavaScriptを使用して簡単なアニメーションを行うためのAPIだ。その使い方はおおよそ次のようになる。
window.requestAnimationFrame(function(timestamp) {
// 描画を行うためのコード
});
この関数はページの再描画が行われる際に画面を更新するために使用するコールバック関数を引数に取る。コールバック関数には、requestAnimationFrame関数がコールバック関数を呼び出す瞬間の時間を表すタイムスタンプ値(timestamp)が引数として渡される。よって、アニメーションを行うには、タイムスタンプ値を使用して、差分を計算するといった用途に使えるだろう。
簡単な例を以下に示す(なお、ここではタイムスタンプ値を使わずに、count変数でアニメーションの制御を行っている)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML 5.1 sample page</title>
<script>
function moveit() {
var element = document.getElementById("target");
element.style.position = 'absolute';
var count = 0;
function move(timestamp) {
element.style.left = count + "px"
element.style.top = count / 2 + "px"
count += 10;
if (count < 200) {
window.requestAnimationFrame(move);
}
}
window.requestAnimationFrame(move);
}
</script>
</head>
<body>
<button onclick="moveit()">button</button>
<p id="target" style="font-size: large">Insider .NET</p>
</body>
</html>
ここではカウンター変数を使って、「Insider .NET」という文字の位置(element.style.left/topプロパティ)を変更することで、簡単なアニメーションを行っている。実行結果は次のようになる。位置合わせに失敗して、ボタンと文字がかぶっている部分は笑って許していただきたい。ポイントは描画を行ったら(この場合はleft/topプロパティを変更したら)、次の描画を行うためにrequestAnimationFrame関数を再度呼び出している点だ(moveit関数内でループを行い、2つのプロパティを変更していってもアニメーション効果は得られない)。
○oncopy、oncut、onpasteイベントの追加
これはコードを見てもらうのが一番簡単だろう。
<p oncopy="alert('copy')"
oncut="alert('cut')"
onpaste="alert('paste')"
contenteditable="true">Sample text</p>
Webページに表示されている要素に対して、コピー/カット/ペースト処理が行われた時点でこれらのイベントが発生する。以下に実行例を示す。なお、ここではコード例がシンプルになるように、HTML5で追加されたグローバル属性のcontenteditable属性の値をtrueにして、<p>要素の内容を書き換え可能としている。
コピー/カット/ペーストが行われた際に、何らかの処理を介入させるときにこれが便利に使えると思われる。
コンテキストメニュー/<input>要素/<summary>要素と<details>要素
上述した通り、これらについては「Dev Basics/Keyword: HTML 5.1」で取り上げているので、興味のある方はそちらを参照していただきたい。
本稿では「そもそもHTML5とは何か」「HTML 5.1で追加された機能」について概観してきた。今回紹介しきれなかった新機能や削除された機能については次回取り上げることにする。
