最も凶悪な退会ボタン

# なかなか退会できないサービスって、嫌ですよね

「何箇所もクリックして、ようやく退会できるサービス」ってユーザー体験よくないですよね。

そういうサイト、たまにあると思います。

ですが今回は、それどころではない「クソの権化」とも言える退会ボタンをTwitter上で見つけました。
そちらをご紹介して行きたいと思います。

# どんなボタンか

こちらです。

https://twitter.com/ng_web_design/status/1598973471106953218?s=20&t=WEVelYipfBPx3jst18NkqA

「退会する」ボタンをクリックすると、ボタンが少しずつ割れていき、小さなボタンが中から出てきます。
まるでマトリョーシカです。

そして、何度も何度もクリックさせられた挙句、最終的に退会できたのかイマイチわかりません。
かなり凶悪なUXです。

今回は、このボタンのソースコードを**極秘入手**[^1]しましたので、以下に記載します。

# HTML

パカっと割れるようにするために、同じボタンが2つずつあります。

```html
<div class="wrapper">
  <div class="button-wrapper-wrapper mini last" style="z-index: 9;">
    <div class="button-wrapper button-wrapper1">
      <button><span>退会</span></button>
    </div>
    <div class="button-wrapper button-wrapper2">
      <button><span>退会</span></button>
    </div>
  </div>
  <div class="button-wrapper-wrapper mini" style="z-index: 9;">
    <div class="button-wrapper button-wrapper1">
      <button><span>ガチで？</span></button>
    </div>
    <div class="button-wrapper button-wrapper2">
      <button><span>ガチで？</span></button>
    </div>
  </div>
  <div class="button-wrapper-wrapper mini" style="z-index: 9;">
    <div class="button-wrapper button-wrapper1">
      <button><span>本当に？</span></button>
    </div>
    <div class="button-wrapper button-wrapper2">
      <button><span>本当に？</span></button>
    </div>
  </div>
  <div class="button-wrapper-wrapper" style="z-index: 10;">
    <div class="button-wrapper button-wrapper1">
      <button><span>退会する</span></button>
    </div>
    <div class="button-wrapper button-wrapper2">
      <button><span>退会する</span></button>
    </div>
  </div>
</div>
```


# CSS

うまいことボタンを重ねたり、半分にしたりしています。

```css
html {
  height: 100%;
}
body {
  min-height: 100%;
  background-image: linear-gradient(rgb(76, 129, 152), rgb(54, 93, 109));
  display: flex;
  justify-content: center;
  align-items: center;
}

.wrapper {
  position: relative;
}

.button-wrapper-wrapper {
  transition: 0.2s;
  display: flex;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: 1s;
}

.button-wrapper-wrapper:active button {
  background-image: linear-gradient(#bbb, #fff);
}

.button-wrapper-wrapper button span {
  filter: blur(0);
  transition: 2s;
}

.button-wrapper-wrapper.fade button span {
  filter: blur(16px);
}

.wrapper,
button,
.button-wrapper-wrapper {
  height: 50px;
  width: 160px;
}

.button-wrapper {
  flex-grow: 0;
  width: 50%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

.button-wrapper1 {
  transform-origin: right 120%;
  left: 0;
}

.button-wrapper2 {
  transform-origin: left 120%;
  right: 0;
}

.button-wrapper-wrapper.paka .button-wrapper1 {
  transform: rotate(-30deg);
}

.button-wrapper-wrapper.paka .button-wrapper2 {
  transform: rotate(30deg);
}

button {
  user-select: none;
  position: absolute;
  border: none;
  background-image: linear-gradient(#fff, #aaa);
  border-radius: 100px;
  font-size: 24px;
  top: 0;
}

.button-wrapper1 button {
  left: 0;
}

.button-wrapper2 button {
  right: 0;
}

.mini {
  transform: translate(-50%, -50%) scale(0.1);
}

```

# JavaScript

JSは割と短いです。
クラスをつけたり外したり、要素の`style`をいじったりするくらいです。

```js
document.querySelectorAll(".button-wrapper-wrapper").forEach((elm) =>
  elm.addEventListener("click", (e) => {
    const left = elm.querySelector(".button-wrapper1");
    const right = elm.querySelector(".button-wrapper2");
    if (!elm.previousElementSibling) {
      elm.classList.add("paka");
      return;
    }
    if (Number(left.style.left.replace("px", "")) < -40) {
      elm.style.display = "none";
      elm.previousElementSibling.classList.remove("mini");
    } else {
      left.style.left = Number(left.style.left.replace("px", "")) - 3 + "px";
      right.style.right =
        Number(right.style.right.replace("px", "")) - 3 + "px";
    }
  })
);

```

# 完成品

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="wvXQJgx" data-user="Yametaro" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Yametaro/pen/wvXQJgx">
  Untitled</a> by Yametaro (<a href="https://codepen.io/Yametaro">@Yametaro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# みなさんも、ぜひ使ってみてください

「どうしても最悪なUXを提供しなければならない」
そんな場面がありましたら、こちらのボタンを使ってみてください。
それだけでもう立派な「クソアプリ」になると思います。

[^1]:（本当はワイが作りました）