web components を使ってみた！

## はじめに
みなさんこんにちは。
今回導入するにあたって、個人的にはページ数が増えてくるとメンテナンスが大変になったことと、コード量が増えることで同じ要素で共通化したスタイルでも崩れてしまうことがあり、無駄な時間を費やしてしまった為。

## web componentsとは？
web componentsとは、再利用可能なカプセル化された独自のHTMLタグを生成するためのAPIです。


## ３つの技術

1.カスタム要素
 * 独自HTMLタグの作成、既存のタグの改良、作成したタグの動作の定義、別の開発者が作成したコンポーネントをUIにマッチするように拡張することを可能にする JavaScript API のセットです。
 
2.シャドウDOM
* シャドウDOM ツリーは、メイン文書のDOMとは別にレンダリングされます。そのため、CSSの適用範囲・JavaScriptのアクセス範囲をコンポーネント内に限定することできます。

3.HTMLテンプレート
 * 再利用可能なコンポーネントとして、任意の名前の独自HTML要素として定義できます。

## メリット
・いろんなフレームワークとの互換性を保つことができる。
　(異なるフレームワークで再利用可能)
・簡単に実装できる
・開発期間を短縮できる
・古いブラウザでも動かすことができる
・メンテナンスしやすくなる
・各コンポーネントの独立性が高くなるのでデザインの影響を限定したり、公開されているweb componentsを利用しやすくなる。


## 導入の流れ


html
```html
<div class="btn">
            <a href="<?php echo esc_url(home_url('/portfolio')); ?>" class="">
              <div class="text">Read More</div>
              <div class="circle">
                <img src="<?php bloginfo('template_directory'); ?>/images/common/arrow.svg" class="arrow-icon" alt="Arrow">
              </div>
            </a>
          </div>
```
↓コード量が減り、どのページでも使い回しができる
```html
 <my-button link="/news" text="Read More" icon="<?php bloginfo('template_directory'); ?>/images/common/arrow.svg"></my-button>
```
my-button.js

```my-button.js

class MyButton extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
    this.shadowRoot.innerHTML = `
      <style>
        .btn {
          text-align: end;
          text-decoration: none;
        }

        .btn-news {
          margin-top: 30px;
        }

        a {
          display: inline-flex;
          align-items: center;
          justify-content: end;
          transition: background 0.5s ease, border-color 0.5s ease;
        }

        a:hover .circle {
          background: #fff;
          border: 1px solid var(--sab_color, rgba(24, 156, 81, 1));
        }

        a:hover .arrow-icon {
          filter: invert(54%) sepia(72%) saturate(551%) hue-rotate(77deg) brightness(89%) contrast(91%);
        }

        .text {
          font-size: 18px;
          font-weight: 500;
          line-height: 18px;
          letter-spacing: 0.05em;
          color: var(--text, rgba(37, 37, 37, 1));
        }

        @media (max-width: 768px) {
          .text {
            font-size: 4.267vw;
            line-height: 16px;
          }
        }

        .text__recruit {
          color: #fff;
        }

        .circle {
          margin-left: 20px;
          width: 70px;
          height: 70px;
          border-radius: 50%;
          background: linear-gradient(99.35deg, #189C51 4.83%, #0BC15A 95.17%);
          display: flex;
          align-items: center;
          justify-content: center;
        }

        @media (max-width: 768px) {
          .circle {
            width: 45px;
            height: 45px;
          }
        }

        .circle__recruit {
          background: rgba(255, 255, 255, 1);
        }

        .arrow-icon {
          width: 15px;
          height: auto;
          transition: filter 0.5s ease;
        }

        @media (max-width: 768px) {
          .arrow-icon {
            width: 9px;
          }
        }
      </style>
      <a href="${this.getAttribute('link')}" class="btn ${this.getAttribute(
      'variation'
    )}">
        <span class="text ${this.getAttribute(
          'text-class'
        )}">${this.getAttribute('text')}</span>
        <span class="circle ${this.getAttribute('circle-class')}">
          <img src="${this.getAttribute(
            'icon'
          )}" class="arrow-icon" alt="Arrow">
        </span>
      </a>
    `
  }
}

customElements.define('my-button', MyButton)

```




![スクリーンショット 2024-09-03 21.44.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3800808/e981adaf-11b8-4ed4-04b5-dbe63c905696.png)
ShadowRootがスコープされていて他の要素の干渉を受けないようになっている

### 注意点
タグには必ずハイフンとつける


### 終わりに
個人的には簡単でサクッと使える。
他にもweb componentsを使いやすくする為のライブラリが多く出ている。
使ってみた！ということで初歩的はことを実装してみました。使いこなせれば便利だと思いますが、慣れるまで少し時間がかかりそうな印象でした。
この記事では紹介しきれていないことが多々ありますが、同じような境遇の方に少しでも参考になれば幸いです。





## 参考サイト
https://qiita.com/hedrall/items/f2ebb5338f79007083a3
https://blogs.jp.infragistics.com/entry/what-are-web-components
https://developer.mozilla.org/ja/docs/Web/API/Web_components
https://kinsta.com/jp/blog/web-components/