破壊的操作の装飾について

## 概要
危ない操作はちゃんと危ない見た目をしていてほしいよね。
CSSでここまでできるよ（やるかどうかは別として）

## 破壊的操作とは？

データベースで言えばupdateやdeleteのように、もともとの要素に変更を加えるもののこと。「とりかえしのつかない要素」ってやつだ。
同じくデータベースで言えばselectのように参照するだけなど、もとの要素には手を加えない操作を非破壊的という。

webアプリでそういった破壊的操作を行う場合にはワンクッション欲しいのが人情ってものだろう。画面をスクロールしている途中で、誤タップした「削除」ボタン一発で全てが御破産になるなんて、大概の人は勘弁してほしいはずだ。

## 確認を挟む（window.confirm()）

よくある解決策のひとつがこれだ。
破壊的要素のある操作、たとえば「削除」ボタンが押されたときに「本当に削除していいのか？」と確認する。
ホウ・レン・ソウってやつだ。鍋に入れても美味い。
```<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta chrset="utf-8">
    </head>
    <body>
        <button id="delete-button">削除</button>
    
        <script>
            const deleteButton = document.getElementById('delete-button');
            deleteButton.addEventListener('click', function() {
                const result = window.confirm('キャンセルしますか？');
                if(result){
                    // 削除の操作
                    console.log('アイツはもう消した！');
                }
            })
        </script>
    </body>
</html>
```
![画面サンプル1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/69e08c20-af0e-973b-7268-9c50e4881238.png)

`window.confirm()` でユーザが選んだ結果は `result` にtrue/falseで渡されるので、確認後に後続の処理を流してやればいい。

この方法の難点は、びっくりするほどダサいことだろう。
ブラウザごとに表示はバラバラ(サンプル画面はchromeのもの)だし、confirmが表示されている間、同一のタブでは他の操作を受け付けなくなる。
しかも、 `このページの内容` や `OK` 、 `キャンセル` といった文言は変えられない。

文言が変えられないと、たとえばこういう困ったことが起こる。
![画面サンプル2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/e9350bd3-bbf6-8eb4-7a9e-99162dc74572.png)
どっちやねん。

## 確認を挟む（自前で用意する）
`window.confirm` の記述は簡単・お手軽なので、数人しか使わないような小規模運用ならアリだが、小回りが効かない。
サイトに合った装飾もできないので、自前で用意するのが望ましい。

```
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta chrset="utf-8">
    </head>
    <body>
        <button id="delete-button">削除</button>

        <div id="delete-modal" class="modal" style="display: none;">
            <div class="delete-modal-content">
                <div class="delete-modal-header">
                    <h1>!!! Warning !!!</h1>
                    <span class="modal-close-button">×</span>
                </div>
                <div class="delete-modal-message">
                    <p>本当に削除しますか？</p>
                </div>
                <div class="delete-confirm-button-area">
                    <button id="delete-submit">削除する</button>
                    <button class="modal-close-button">やめとく</button>
                </div>
            </div>
        </div>

        <script>
            const deleteButton = document.getElementById('delete-button');
            const deleteSubmit = document.getElementById('delete-submit');
            const modal = document.getElementById('delete-modal');
            const closeButton = document.querySelectorAll('.modal-close-button');

            // 「削除」ボタンがクリックされた
            deleteButton.addEventListener('click', ()=> {
                modal.style.display = 'block';
            });

            // 閉じる系のボタンがクリックされた
            closeButton.forEach(function(target) {
                target.addEventListener('click', ()=> {
                    modal.style.display = 'none';
                });
            });

            // 削除確定
            deleteSubmit.addEventListener('click', function() {
                // 削除の操作
                console.log('アイツはもう消した！');
            })
        </script>
    </body>
</html>
```
![画面サンプル3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/8c563d78-dc4a-7480-2d1a-a59624303741.png)
自前で用意する場合、cssも自分で書かないとこんな表示になる。

```
.modal {
    display: none;
    position: fixed;
    z-index: 10;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    overflow: auto;
    background-color: rgba(0,0,0,0.8);
}

.delete-modal-content{
    background-color: #fff;
    margin: 20% auto;
    width: 40%;
}

.delete-modal-header {
    display: flex;
    justify-content: space-between;
    background: #ff7156;
    padding: .2em 3em;
}

.delete-modal-message, .delete-confirm-button-area {
    padding: .2em 1.4em;
}
```
![画面サンプル4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/18a4a660-e219-844d-aa0b-eb50782a49f4.png)
これくらいスタイルを書いて、ようやくこんな感じ。

自前でやりつつ、省力化もしたい。
そういう場合はBootstrapのmodalなどの、いいかんじのものが用意されてるのを使って適宜カスタマイズするのが簡単と便利を両立できる。
https://getbootstrap.jp/docs/5.0/components/modal/

## もっと危ない感じにしたい
### 虎柄
工事現場や立ち入り禁止の表示にも使われる、黄色と黒の警戒色。いわゆる虎柄。蜂の柄と言ってもいい。
目立つ。目立ちまくる。
```
.modal {
    display: none;
    position: fixed;
    z-index: 10;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    overflow: auto;
    background-image: linear-gradient(
            45deg,
            #000 25%,
            #fff000 25%, #fff000 50%,
            #000 50%, #000 75%,
            #fff000 75%, #fff000 100%
    );
    background-size: 80px 80px;
}
```
![とら](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/c0332ee1-4971-21e9-35b5-d94422d0eadc.png)

### 点滅
動きがあるほうが目に留まりやすい。注意を促すためには見てもらわないことには始まらない。
```
.delete-modal-content{
    background-color: #fff;
    margin: 20% auto;
    width: 40%;
    animation: warning-color-change 2s linear infinite;
    border: solid 1em #ff1493;
}
@keyframes warning-color-change {
    0%,100%{
        border-color:#ff1493;
    }

    25%{
        border-color: #ff0000;
    }

    50%{
        border-color: #ff8991;
    }

    75%{
        border-color:#ffffff;
    }
}
```
![てんめつ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/1e9bb31d-bfd5-39c1-b99c-00adff77844c.gif)

### 動く文字
動きがあるほうが目に留まr
いわゆるニコニコ動画のコメント風なやつ。
```
<p class="warn-text">warning</p>

<style>
    .warn-text{
        font-size:3em;
        color: red;
        animation: warn-anime 3s linear infinite;
        transform: translateX(100%);
    }

    @keyframes warn-anime {
        100% {
            transform: translateX(-100%);
        }
    }
</style>
```
![流れる文字](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/0a1e61dc-abd6-d023-f2ec-0d2db51c9dee.gif)

### 全部乗せ
![warn](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974632/ea071331-cbf1-1b23-d0f9-e548d43ad8bb.gif)
どう見ても過剰で逆に見づらい。
ご利用は計画的に。