CSS で「何回閉じても無駄ですよ〜ｗｗｗ(ババババ)」を再現する

*JavaScript の違法化が迫る 2019 年 3 月。今後我々はどのようにして「何回閉じても無駄ですよ〜ｗｗｗ(ババババ)」をすれば良いのか。来るべき 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-*`属性などを付与していく。

```HTML
<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>(ノΠＵ<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 は以下のように書ける。

```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`プロパティを使用**する。

## 完成

<p class="codepen" data-height="429" data-theme-id="dark" data-default-tab="result" data-user="hakaato" data-slug-hash="XGajNB" style="height: 429px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Infinite alert with Pure CSS">
  <span>See the Pen <a href="https://codepen.io/hakaato/pen/XGajNB/">
  Infinite alert with Pure CSS</a> by Hakaato (<a href="https://codepen.io/hakaato">@hakaato</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## まとめ

HTML, CSS で書かれた Web ページを公開して補導される時代もそう遠くはない。
共に戦おう。