JavaScript の違法化が迫る 2019 年 3 月。今後我々はどのようにして「何回閉じても無駄ですよ〜www(ババババ)」をすれば良いのか。来るべき X デーを目前にして、未来を生きるための術を学ぶ。
はじめに
この記事に書かれている内容は、上記の文章を含めて、妄言や黒魔術が多分に含まれるため、読む際には十分に注意してください。情報の正誤は一切保障しません。記事の内容を参考にするときは、自己責任でよろしくお願いします(必死の補導回避)。
え?この文章は妄言や黒魔術の類なのかって...?無限ループって怖くね?
無限アラートとは?
無限アラートとは、太古から伝わる黒魔術である。
起源については、怪しげな説が幾つかあるが、少なくとも 18 ~ 21 世紀の間に登場したものだと考えられている。
もともと、無限アラートはヒエログリフで書かれていたもので、現在周知されている無限アラートはこれを 130 歳の JC が JavaScript に訳したものである。この魔術は、while
文やfor
文、window.alert
メソッドなど、基礎的な魔術のみで構成されているため、魔術に精通していない人間であっても、容易に詠唱することが可能だ。
また、アラートとはダイアログであり、用途が警告メッセージの表示に限定されたモーダルウィンドウである。そのため、理屈の上では、window.alert
メソッドなしでも、 HTML, CSS を駆使してアラートを実装することは可能となる。今回は JavaScript を一切詠唱せずに作成するため、フォーカスの管理は行わない。
HTML, CSS で作る無限アラート
いくら CSS で再現する、といったところで、 HTML が無ければ CSS なんて飾りにすらならない。まずは HTML から書いていく。
HTML を書く
dialog
要素を使ってみたいが、ブラウザの対応がまだまだ先になりそうなので、普通にdiv
要素を使い、そこにclass
属性やrole
, aria-*
属性などを付与していく。
<p class="hidden-message">メッセージはでないはずだよ</p>
<input type="checkbox" id="modalCloseButtonText">
<div class="modal-dialog" role="alertdialog" aria-modal="true" aria-labelledby="modalHeadingText" aria-describedby="modalBodyText">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-heading" id="modalHeadingText">アラート</h1>
</div>
<div class="modal-body">
<p class="modal-body-text" id="modalBodyText"> ∧_∧ ババババ<br>( ・ω・)=つ≡つ<br>(っ ≡つ=つ<br>`/ )<br>(ノΠU<br>何回閉じても無駄ですよ~ww<br>m9(^Д^)プギャー!!<br> by Boseki (@Hakaato)</p>
</div>
<div class="modal-footer">
<button type="button" class="modal-close-button">
<label for="modalCloseButtonText" class="modal-close-button-text">OK</label>
</button>
</div>
</div>
</div>
CSS を書く
ここで、問題として立ちはだかるのは、「閉じるボタンをクリックされた後、どのようにしてアラートを再表示するか?」である。 HTML, CSS には、そのような呪文は存在していない。そういった魔術は JavaScript が扱うとされているからだ。
どうやって無限アラートにするか
どのようにして無限アラートを実現するか。答えは簡単、そもそもアラートが閉じれなくて良いのだ。
今回の目的は JavaScript を使わずに無限アラートの動作を再現することだ。どうせ閉じてもまた出てくるんだから、丁寧に閉じてやる必要なんかないのである(暴論)。ほんの数秒、あたかもアラートが閉じられたかのように振舞えば良い。
つまり、無限アラートは、ボタンをクリックされるたびに一瞬だけアラートが消えるアニメーションを付与すれば実現できる。
そうして出来上がった CSS がこちら
以上のことから、 CSS は以下のように書ける。
* {
margin: 0;
padding: 0;
}
body {
display: flex;
height: 100vh;
}
.hidden-message {
margin: auto;
letter-spacing: 1.5em;
}
# modalCloseButtonText {
display: none;
}
# modalCloseButtonText:checked + .modal-dialog {
animation: alert_checked .03s linear;
}
# modalCloseButtonText + .modal-dialog {
animation: alert_unchecked .03s linear;
}
.modal-dialog {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow: auto;
background: rgba(0, 0, 0, .5);
}
.modal-content {
display: flex;
flex-direction: column;
min-width: 240px;
margin: auto;
border: 1px solid #696969;
}
.modal-header {
position: absolute;
overflow: hidden;
clip: rect(0, 0, 0, 0);
width: 1px;
height: 1px;
padding: 0;
white-space: nowrap;
border: 0;
clip-path: inset(50%);
}
.modal-body {
min-height: 85px;
padding: .5em 3em;
background: #fff;
flex: 1.7;
}
.modal-footer {
position: relative;
width: 100%;
min-height: 50px;
border-top: 1px solid #e6e6e6;
background: #f2f2f2;
flex: 1;
}
.modal-close-button {
position: absolute;
top: 30%;
left: 60%;
width: 75px;
height: 25px;
}
.modal-close-button-text
{
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}
@keyframes alert_checked {
0%,
50% {
visibility: hidden;
}
100% {
visibility: visible;
}
}
@keyframes alert_unchecked {
0%,
50% {
visibility: hidden;
}
100% {
visibility: visible;
}
}
ごちゃごちゃしているが、チェックボックスの状態が変化するたびにダイアログの表示、非表示のアニメーションが動作しているだけの、比較的簡単なコードだ。ここで、アニメーションを 2 つ用意しているのは、同名のアニメーションを再適用したとしても、ユーザエージェントは何もしないためだ。ちなみに、アラートは Firefox のものに似せている。
また、「あたかもアラートが閉じられたかのように振舞えば良い」とは書いたものの、一瞬だけはアクセシビリティツリーから消えておいて欲しいので、visibility
プロパティを使用する。
完成
See the Pen Infinite alert with Pure CSS by Hakaato (@hakaato) on CodePen.
まとめ
HTML, CSS で書かれた Web ページを公開して補導される時代もそう遠くはない。
共に戦おう。