タイピングゲームを作るHTMLとCSSの力を最大限に引き出してみましょう。HTMLとCSSだけで実装されたタイピングゲームの仕組みには、さまざまな実装のヒントか隠されているのです。翔大郎フロントエンド・エンジニア次回このシリーズの記事一覧をみる記事中には先行実装の仕様を取り扱ったものがあります。仕様策定が続いていますので、最新仕様については、仕様書もご確認ください。擬似セレクタ、属性の実装状況まとめこのシリーズでは、HTML+CSSの技術を使った、さまざまな実装アイデアを解説します。JavaScriptを使わずとも、いろいろな表現が可能です。HTMLとCSSを力をどれだけ引き出せるかに重点をおきます。第1回目はJavaScriptを使わずに、HTMLとCSSのみで実装したタイピングゲームの解説をします。今回紹介するサンプルは以下のリポジトリからダウンロードまたはクローンできます。2014-01-derive-html-cssまずはサンプルを見てみましょう。GAMEボタンをクリックすると、ゲームが始まります。画面上に表示されたワードを制限時間内にタイピングしていきます。問題をクリアできると、次の問題が表示されます。時間内にすべての問題のタイピングできないと、ゲームオーバーになります。31.0.1650.63)で行っています。ブラウザの実装状況や、仕様変更によりデモが正しく動作しない可能性もあります。このゲームはJavaScriptを一切使わず、HTMLとCSSだけで実装されています。validationを行って、input要素などに入力された内容を判定し、CSSの擬似クラスで場合に応じた見た目を与えるという実装をしています。2012の記事で考案したものです*。*注:オリジナルとの違いxl1さんの作成したタイピングゲームでは問題がランダムで出題されますが、今回筆者の作成したサンプルでは使用していません。ゲームらしくなるように少し改良を加えています。仕組みの詳細タイピングゲームの仕組みで重要となる部分を、分解して解説していきます。:checked擬似クラスと間接セレクタを使用した場面切り替え以下のサンプルでは、「次の画面へ」をクリックすると、次のシーンへと遷移します。これを実装するためには:checked擬似クラスと間接セレクタを使用します。:checked疑似クラスとは、ラジオボタンやチェックボックスがチェックされたときに適用される擬似クラスです。間接セレクタとは、同じ親要素を持つ兄弟要素の弟要素に適用されるセレクタで、一般兄弟セレクタとも呼ばれます。ともにCSS3で定義されています。combinatorを参照してください。NETWORKの:checkedや、一般兄弟セレクタがおすすめです。切り替え実際のソースコードを見てみます。このサンプルで使用しているHTMLです。2</div>label要素をクリックすると、for属性で指定されたラジオボタンが選択された状態になります。ラジオボタンの状態は、:checked擬似クラスを使うことで判定することができます。label要素は表示されていますが、このラジオボタンはクリックされたかどうかの判定にのみ使用するため、画面には表示しません。pointer;}CSSでスタイルを適用しリンクのように見せているのが、実はinput要素のラジオボタンであるというのが、このサンプルのポイントのひとつです。次に遷移前の画面と、遷移後の画面の定義や、ラジオボタンがチェックされたかどうかによってCSSの出し分けをしてる部分を見てみましょう。150px;}ラジオボタンの:checked擬似クラスの状態(#flag:checked、#flag:not(:checked))と合わせて、間接セレクタによるスタイルの指定をしています。Bとすることで、AとBが兄弟関係にあるとき、Aセレクタを持つ要素より後ろにあるBセレクタを持つ要素を選択することができます。判定に使っているinput要素と、.scene_1と、.scene_2のクラス名を持つdiv要素は兄弟関係にあるので、間接セレクタで後続の2つのdiv要素を出し分けています。このように先頭にinput要素を置いておくと、後続するほとんどの要素に対しての制御を行うことができます。タイピングゲームでは、ゲームスタート画面からゲームプレイ画面に遷移する部分で、この仕組みを使用しています。サンプルでは、仕組みがわかりやすいようにリンクと同じような単純な切り替えを行いましたが、ページ間のリンクとは異なりますので、一定時間後に切り替えるなどの演出も可能です。これについては後述します。input要素の入力が正しい場合は次の問題を表示するタイプされた文字が正解だったら、次の問題を表示するという動作は、input要素に入力された文字列を判定して、さまざまなスタイルを適用することで実現しています。これを行うためにはHTML側では、入力された文字をinput要素のpattern属性とrequired属性を利用して判定を行います。CSSではその判定を受けて、:valid擬似クラス、:invalid擬似クラスを使用してスタイルを適用します。次のサンプルを見てください。このサンプルも文字列の判定と、判定に応じたスタイルを適用しています。入力された値が正しい場合は、✔を表示し、次の問題を表示します。仕組みを見てみましょう。</div></div>HTMLのinput要素には、pattern属性とrequired属性が指定されていることに注目してください。この属性は、ぞれぞれ、次のような働きをして、入力された文字の判定を行っています。pattern属性input要素に入力された値と、属性の値として指定された正規表現文字列を比較し、マッチした場合に:valid擬似クラスが有効になり、マッチしない場合には:invalid擬似クラスが有効になります。required属性input要素が未入力な時:invalid擬似クラスが有効になります。コードでは以下の部分に指定されています。required>pattern属性の値には「半角の2、あるいは全角の2」という正規表現が指定されています。これが入力された場合にのみ、:valid疑似クラスが有効になります。それ以外の文字が入力された場合は、:invaild疑似クラスが有効になります。同時にrequired属性も指定されていますので、フォーム欄が空白のときにもやはり、:invalid疑似クラスが有効になります。ページが表示された際にinput要素にカーソルが入っている状態にするため、autofocus属性も指定しています。CSS側では:valid擬似クラスが有効であるか、:invalid擬似クラスであるかで、スタイルを出し分けるようになっています。このサンプルでは、子セレクタ*、隣接セレクタ*、間接セレクタを使用して、ほかの要素に対して表示・非表示のアクションを起こしています。Bとすることで、Aセレクタを持つ要素の直接の子要素のうちのBセレクタを持つ要素を選択できます。combinatorsや、MDNの子セレクタなどを参照してください。Bとすることで、兄弟関係にある要素のうち、Aセレクタを持つ要素(兄)の直後にあるBセレクタを持つ要素(弟)を選択することができます。要素と要素の間に別の要素が入ると、直後の弟要素でなくなってしまうため、適用されなくなります。combinatorや、MDNの隣接セレクタなどを参照してください。none;}このようにHTMLとCSSが連携することで、タイプした値が正しい場合は次の問題が出現し、フォーカス*があたります。*注:フォーカスの動作autofocus属性が指定されたinput要素がiframe要素内の場合、自動でフォーカスが当たらない場合があります。31.0.1650.63では、autofocus属性が指定されたinputが複数あった場合は、一番後続のものにフォーカスが当たります。あとからdisplay:block;などで画面に表示されると自動的にフォーカスが移ります。26では、後から表示されたものには自動的にはフォーカスが当たりませんでした。そのため、Firefoxではユーザーがクリックしてフォーカスを当てるか、タブキーで移動する必要があります。回答数に応じて答えを変化させる間接セレクタを使用し、:valid擬似クラスと:invalid擬似クラスの組み合わせに応じて後続の要素を変化させます。文字を入力させるinput要素それぞれの状態をみて、スタイルを出し分けています。簡単なサンプルで説明しましょう。未入力チェック機能付きフォームこのサンプルでは入力事項の正否はないので、pattern属性は指定していません。required属性を使って、入力されたかどうかを見ているだけです。したがって基本的な仕組みは、前述した「input要素の入力が正しい場合は次の問題を表示する」と同じです。異なる点は、4つのinput要素が埋まった(:valid擬似クラスが4つ揃った)ときだけ、送信ボタンを表示するスタイルが適用されるようにしている点です。inline;}タイピングゲームでも同じような方法で、問題のクリア数を表示しています。すべて正しく入力された場合は、ゲーム終了画面を表示しています。時間制限とゲームクリア画面を用意するタイピングゲームでは、すべての問題をクリアするか、制限時間に達したらゲーム終了画面を表示します。Animationsを使用します。次のサンプルでは、前述の「:checked擬似クラスと間接セレクタを使用した場面切り替え」で作成したサンプルを、一定時間後に自動で切り替わるように変更しました。2</div>HTMLの構造に変更はありません。CSSには時間を管理する部分を追記しました。その部分を見てみます。}}animation-delayを使い、5秒後にシーン1の高さを150pxから0pxに、シーン2の高さを0pxから150pxに0.1msかけてアニメーションさせます。Animationsではdisplayの値を変更することができないため、heightを0pxにして非表示にしています。本来であれば、0pxから150pxにアニメーションしていくのですが、0.1msかけてアニメーションすると、一瞬でシーンが切り替わったように見せることができます。5秒経たずに「次の画面へ」が押されたときには、シーンに設定されたanimation-delayを0秒で上書きし、アニメーションをすぐに実行します。タイピングゲームでも、このanimation-delayを使い、指定秒後にゲーム終了画面が画面を覆うようにしています。10秒未満ですべての問題をクリアしたとき(すべてのinputで:valid擬似クラスが有効な状態)は、animation-delayを0秒で上書きし、アニメーションをすぐに動かします。ゲームを最初から遊びたい場合は、そのHTMLを再度読み込めばいいので、特に難しいことはせずに、そのHTMLへのリンクを指定します。擬似セレクタ、属性の実装状況タイピングゲームで利用している属性や擬似クラス、セレクタの実装状況は次のようになっています。現時点でも、多くのブラウザで使用することは可能ですが、IEをターゲットに入れる場合はIE9以降となります。表中に*が付いているものは、接頭辞を必要とします。validationやCSSのセレクタを使用し、タイピングゲームを作成しました。このタイピングゲーム自体は実務に使えるものではありませんが、将来的にこのような実装もアリかもしれないと思ってもらえるようなものを作ってみました。いう遊び心は、自分のスキルを上げるために邪魔になるものではないと思っています。次回も「このテがあったか」と、楽しんでもらえるような実装をお届けします。実務で使用するときは、対応しているブラウザや、そもそもの仕様が変わっていないかなどをそのつど調べる必要はあります。翔大郎フロントエンド・エンジニア大手ソフトウェアダウンロード販売会社、Web制作会社などで、マークアップエンジニア、プログラマ、サービス企画、ディレクターを経験。2013年、株式会社ピクセルグリッドに入社。HTML、CSS、JavaScriptなどをオールラウンドに担当。プログラマブルなCSSの設計、実装を得意とする。PANIC」は、JavaScriptを一切使わず、HTMLとCSSのみで実装。海外サイトで紹介されるなど話題となった。特定商取引法に基づく。