<main>
  <our-button variant="success">성공</our-button>
  <our-button variant="error">오류</our-button>
  <our-button variant="warning">경고</our-button>
  <our-button size="sm">소형</our-button>
  <our-button size="md">중형</our-button>
  <our-button size="lg">대형</our-button>
</main>

<template id="our-button">
  <style>
    :host {
      --button-color: #ffffff;
      --button-bg-color: #0d6efd;
      --button-hover-bg-color: #025ce2;
    }
    
    button { 
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      
      margin: 0;
      padding: 0.5rem 1rem;

      font-family: "Noto Sans KR", sans-serif;
      font-size: 1rem;
      font-weight: 400;
      text-align: center;
      text-decoration: none;

      display: inline-block;
      width: auto;

      border: none;
      border-radius: 4px;
      
      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
      cursor: pointer;
      transition: 0.5s;
      
      background: var(--button-bg-color);
      color: var(--button-color);
      
      &:active,
      &:hover,
      &:focus {
        background: var(--button-hover-bg-color);
        outline: 0;
      }
      &:disabled {
        opacity: 0.5;
      }
      
      &.success {
        --button-bg-color: #28a745;
        --button-hover-bg-color: #218838;
      }

      &.error {
        --button-bg-color: #dc3545;
        --button-hover-bg-color: #c82333;
      }

      &.warning {
        --button-color: #212529;
        --button-bg-color: #ffc107;
        --button-hover-bg-color: #e0a800;
      }
      
      &.sm {
        font-size: 0.6rem;
        padding: 0.25rem 0.5rem;
      }
      
      &.lg {
        font-size: 1.5rem;
        padding: 0.7rem 1.4rem;
        border-radius: 8px;
      }
    }
  </style>
  <button>
    <slot/>
  </button>
</template>
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap");

main {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  justify-content: space-evenly;
  align-items: center;
  min-height: 100dvh;
}
class OurButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    const template = document.getElementById("our-button");
    const clone = template.content.cloneNode(true);
    this.shadowRoot.appendChild(clone);
    
    const variant = this.getAttribute("variant");
    this.shadowRoot.querySelector("button").classList.add(variant);
    
    const size = this.getAttribute("size") ?? "md";
    this.shadowRoot.querySelector("button").classList.add(size);
  }
}

customElements.define('our-button', OurButton);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.