Web Components Encapsulation

by hirako2000

HTML

<body id="body">
  <div id="wrapper">
    <main>
      <section>
        <div class="container">
          <div class="vstack-6">
            <div class="vstack ai-center">
              <custom-button bg="secondary" scroll="1" class="as-center"
                             >Scroll to element</custom-button
                >
            </div>
            <div class="vstack ai-center">
              <h4>Variations</h4>
              <p>Solid | Ghost | Outline</p>

              <div class="hstack">
                <custom-button bg="primary">Button</custom-button>
                <custom-button bg="primary" variant="ghost"
                               >Button</custom-button
                  >
                <custom-button
                               bg="primary"
                               content="500000"
                               variant="outline"
                               ></custom-button>
              </div>
            </div>
          </div>
        </div>
      </section>
    </main>
    <footer class="d-flex jc-center p-6">
      <custom-button bg="secondary" scroll="body" scrollOffset="-50"
                     >Return to body</custom-button
        >
    </footer>
  </div>
</body>

CSS

:root {
  --color-black: rgb(0, 0, 0);
  --color-black-rgb: 0, 0, 0;
  --color-white: rgb(255, 255, 255);
  --color-white-rgb: 255, 255, 255;
  --color-primary-dark: rgb(0, 163, 196);
  --color-primary: rgb(11, 197, 234);
  --color-primary-rgb: 11, 197, 234;
  --color-primary-70: rgb(118, 228, 247);
  --color-primary-70-rgb: 118, 228, 247;
  --color-primary-50: rgb(157, 236, 249);
  --color-primary-50-rgb: 157, 236, 249;
  --color-primary-30: rgb(196, 241, 249);
  --color-primary-30-rgb: 196, 241, 249;
  --color-primary-10: rgb(237, 253, 253);
  --color-primary-10-rgb: 237, 253, 253;

  --color-secondary-dark: rgb(50, 38, 89);
  --color-secondary: rgb(68, 51, 122);
  --color-secondary-rgb: 68, 51, 122;
  --color-secondary-70: rgb(85, 60, 154);
  --color-secondary-70-rgb: 85, 60, 154;
  --color-secondary-50: rgb(107, 70, 193);
  --color-secondary-50-rgb: 107, 70, 193;
  --color-secondary-30: rgb(128, 90, 213);
  --color-secondary-30-rgb: 128, 90, 213;
  --color-secondary-10: rgb(159, 122, 234);
  --color-secondary-10-rgb: 159, 122, 234;

  --size-4xs: 0.25rem;
  --size-3xs: 0.5rem;
  --size-2xs: 0.75rem;
  --size-xs: 1rem;
  --size-sm: 1.5rem;
  --size-md: 2rem;
  --size-lg: 3rem;
  --size-xl: 4rem;
  --size-2xl: 6rem;
  --size-3xl: 8rem;
  --size-4xl: 10rem;
  --size-1: 10%;
  --size-20: 20%;
  --size-30: 30%;
  --size-40: 40%;
  --size-50: 50%;
  --size-60: 60%;
  --size-70: 70%;
  --size-80: 80%;
  --size-90: 90%;
  --size-10: 100%;
  --border-width-1: 1px;
  --border-width-2: 2px;
  --border-width-3: 3px;
  --border-width-4: 4px;
  --border-radius-1: 0.5rem;
  --border-radius-2: 1rem;
  --border-radius-3: 1.5rem;
  --border-radius-4: 2rem;
  --font-weight-black: 700;
  --font-weight-bold: 600;
  --font-weight-semibold: 500;
  --font-weight-regular: 400;
  --font-weight-light: 300;
  --line-height-shorter: 1.25;
  --line-height-short: 1.375;
  --line-height-base: 1.5;
  --line-height-tall: 1.625;
  --line-height-taller: 2;
  --letter-spacing-tighter: -0.05em;
 ...

TypeScript

(function () {
  const template = document.createElement("template");
  const f = new CustomButtonDisplay();
  const styles = `<style>
:host {
  position:relative;
  display: inline-flex;
  outline: none;
}
@keyframes animateEffect {
  0% {
      transform: scale(0);
      opacity: 0.6;
 }
  to {
      transform: scale(2);
      opacity: 0;
 }
}
.effect {
  animation: animateEffect 0.8s 1;
  border-radius: 100%;
  position: absolute;
}
.primary .effect {
  background: rgba(var(--color-black-rgb, 0, 0, 0), 0.2);
}
.primary-ghost .effect, .primary-outline .effect {
  background: var(--color-primary-dark, #97cece);
}
.secondary .effect {
  background: var(--color-secondary-30, #bac0d8);
}
.secondary-ghost .effect, .secondary-outline .effect {
  background: rgba(var(--color-black-rgb, 0, 0, 0), 0.2);
}
.white {
  color: var(--color-white, #fff) !important;
}
.white .effect {
  background: var(--color-white, #fff);
}
.black {
  color: var(--color-black, #000) !important;
}
.black .effect {
  background: rgba(var(--color-black-rgb, 0, 0, 0), 0.4);
}
.icon {
  height: 1.3em;
  width: 1.3em;
}
.icon-left {
  margin-right: 0.5em;
}
.icon-right {
  margin-left: 0.5em;
}
.primary {
  color: var(--color-black, #000);
  fill: var(--color-black, #000);
  background: var(--color-primary, #a8d6d6);
}
.primary-ghost:before, .primary:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: calc(100% + 0.3em);
  height: calc(100% + 0.3em);
  transform: translate(-0.15em, -0.15em);
  transition: 0.4s ease;
  background: 0 0;
  border-radius: 0.35em;
  box-shadow: 0 0 0 var(--button-border-width, 2px) transparent;
}
.primary-ghost:focus:before, .primary-outline:focus:before, .primary:focus:before, .secondary-ghost:focus:before, .secondary-outline:focus:before, .secondary:focus:before {
  box-shadow: 0 0 0 var(--button-focus-width, 1px) var(--button-focus-color, #7fd2f0);
}
.primary:hover {
  background: var(--color-primary-dark, #97cece);
}
.primary-ghost,...