<main>
  <header>
    <h1>Action Sheet Pop-up</h1>
  </header>
  <article>
    <p>Lorem ipsum, dolor, sit amet consectetur adipisicing elit. Repellat illo eum hic possimus, libero voluptates, facere nihil deserunt similique error sunt vero minima enim cupiditate quis velit rem ab repellendus.</p>
    <p>Neque hic veniam cum voluptates quae magnam quisquam saepe. Dolorum quasi amet officiis vero aliquid pariatur commodi repellendus. Quos iure nobis doloremque ipsum facere nostrum neque adipisci hic labore voluptates?</p>
    <p>Mollitia beatae, repellat est laboriosam officiis? Earum veritatis incidunt explicabo id tempora perspiciatis non doloribus natus nisi asperiores quia error autem laudantium, amet doloremque, vitae quos. Soluta unde numquam id.</p>
    <p>Recusandae facere esse quod dolorum maxime corrupti ex quam iure id quis eius cumque fugiat, consequatur autem, excepturi molestias libero velit illo a quo. Sed quae aut inventore quia, ipsa.</p>
    <p>Eius id laboriosam, quas iure laborum corrupti optio corporis tempore odit laudantium similique, accusamus, vel! Perspiciatis sed saepe rem. Nihil explicabo ea at vitae rerum eum, corrupti ipsam suscipit, id!</p>
    <p>Voluptate pariatur, cum praesentium, veniam tenetur distinctio totam voluptates ea beatae, dicta voluptatum illum sit! Earum harum odio natus perspiciatis. Magni eos temporibus harum quas laborum aspernatur, minus, sunt illum.</p>
    <p>Ducimus nobis, libero illum commodi aliquid. Molestias beatae ducimus ratione quod, quis itaque ipsum, illum amet labore, nostrum quisquam enim. Sint aperiam qui nihil eaque id quam odio? Repudiandae, sint!</p>
    <p>In rem tenetur accusamus accusantium id, officia quaerat atque, placeat architecto nihil unde, sit cupiditate minima tempore! Magni, atque labore. Dolor voluptatum eius incidunt, enim? Asperiores similique, ut amet atque?</p>
    <p>Illum, quam fugiat, veniam officia totam nihil aut dolore quo! Officiis ipsa harum vero voluptatibus eaque repudiandae amet eligendi ducimus laboriosam ab maiores labore, odit, voluptas quos illo sint nulla.</p>
    <p>Eius earum nihil officiis, inventore accusantium consequuntur dolor reprehenderit in esse quos eos iste nemo amet facere, mollitia, assumenda cum provident quam. Ipsam, vitae! Excepturi quos possimus enim, quia distinctio.</p>
  </article>
</main>
<div id="sheet-pop-up" class="actionsheet" popover>
  <div class="actionsheet__header">
    <button popovertoggletarget="sheet-pop-up">Actions</button>
  </div>
  <div class="actionsheet__content">
    <ul class="actionsheet__actions">
      <li>
        <button autofocus class="ripple">Make</button>
      </li>
      <li>
        <button class="ripple">Things</button>
      </li>
      <li>
        <button class="ripple">Pop</button>
      </li>
    </ul>
    <div class="actionsheet__divider"></div>
    <div class="actionsheet__footer">
      <button popoverhidetarget="sheet-pop-up" class="ripple">Cancel</button>
    </div>
  </div>
</div>
@layer demo {
  .actionsheet {
    --bg: var(--surface-2);
    --blur: 6px;
    border: 0;
    padding: 0;
    display: block;
    top: 100%;
    margin: 0;
    overflow: visible;
    left: 50%;
    width: var(--size-content-3);
    max-width: 100%;
    transition: transform 0.2s;
    transform: translate(-50%, calc((0 - var(--open, 0)) * 100%))
      translateY(calc(var(--translate, 0) * 1px));
    color: var(--text-2);
    filter: drop-shadow(0 0 var(--size-1) hsl(var(--gray-8-hsl) / 0.75));
  }

  .actionsheet:after {
    content: "";
    position: absolute;
    height: 100%;
    width: 100%;
    background: var(--bg);
    top: 100%;
    left: 0;
  }

  .actionsheet::backdrop {
    opacity: var(--open, 0);
    transition: opacity 0.2s;
    background: hsl(0 0% 10% / 0.5);
  }

  @media (prefers-color-scheme: dark) {
    .actionsheet {
      filter: drop-shadow(0 0 var(--size-1) hsl(var(--gray-1-hsl) / 0.75));
    }
    .actionsheet::backdrop {
      background: hsl(0 0% 90% / 0.5);
    }
  }

  .actionsheet:open {
    --open: 1;
  }

  .actionsheet:open::backdrop {
    --open: 1;
  }

  .actionsheet__header {
    font-weight: var(--font-weight-6);
    background: var(--bg);
    position: absolute;
    bottom: 99%;
    left: 0;
    padding: var(--size-2) var(--size-4) 0 var(--size-4);
    width: 100%;
    border-top-right-radius: var(--radius-3);
    border-top-left-radius: var(--radius-3);
    display: flex;
    justify-content: center;
  }

  .actionsheet__actions li {
    padding: 0;
    margin: 0;
    max-inline-size: 100%;
  }

  .actionsheet__content {
    padding: var(--size-4);
    background: var(--bg);
  }

  .actionsheet button {
    width: 100%;
    padding: var(--size-4);
    background: var(--surface-1);
    box-shadow: none;
    color: var(--text-1);
    border-radius: 0;
  }

  .actionsheet button {
    outline-color: transparent;
  }

  .actionsheet__header:after {
    content: "";
    height: 6px;
    width: 40px;
    border-radius: 2px;
    background: var(--text-2);
    position: absolute;
    top: calc(var(--size-4) * 0.5);
    left: 50%;
    transform: translateX(-50%);
    pointer-events: none;
  }

  .actionsheet__header [popuptoggletarget] {
    width: 100%;
    padding: var(--size-4);
    background: transparent;
  }

  .actionsheet__actions {
    background: var(--bg);
    padding: 0;
    display: grid;
    gap: 2px;
    padding-top: 0;
    border: 0;
    list-style-type: none;
  }

  .actionsheet__footer {
    width: 100%;
    background: var(--bg);
    padding-top: var(--size-4);
  }
}

@layer base {
  *,
  *:after,
  *:before {
    box-sizing: border-box;
    /*cursor: none;*/
    touch-action: none;
  }

  body {
    display: block;
    min-height: 100vh;
    font-family: "Google Sans", sans-serif, system-ui;
    overflow: auto;
  }

  :where([popover]) {
    margin: auto;
    border-width: 0;
    border-style: none;
    background: transparent;
  }

  h1 {
    margin: 0;
    color: var(--gray-0);
  }

  header {
    height: 25vmin;
    min-height: 200px;
    background: var(--gradient-27);
    display: grid;
    place-items: center;
    color: var(--gray-0);
    padding: var(--size-4);
    grid-template-columns: 1fr;
  }

  main {
    margin: 0 auto;
  }

  article {
    padding: var(--size-4);
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  article > * + * {
    margin-top: var(--size-4);
  }
}
const clamp = (min, max, value) => Math.min(Math.max(value, min), max);

const HEADER = document.querySelector(".actionsheet__header");
const ACTIONSHEET = document.querySelector(".actionsheet");

const STATE = {
  active: false,
  origin: 0
};

const dragSheet = ({ y }) => {
  if (STATE.active) {
    let translation;
    const { height } = ACTIONSHEET.getBoundingClientRect();
    if (ACTIONSHEET.matches(":open")) {
      translation = clamp(-height, height, (STATE.origin - y) * -1);
    } else {
      translation = clamp(-height, 0, (STATE.origin - y) * -1);
    }
    ACTIONSHEET.style.setProperty("--translate", translation);
  }
};

const endDrag = (e) => {
  const { y, movementY, pointerType } = e;
  STATE.active = false;
  STATE.origin = 0;
  ACTIONSHEET.removeAttribute("style");
  document.body.removeEventListener("pointermove", dragSheet);
  document.body.removeEventListener("pointerup", endDrag);
  requestAnimationFrame(() => {
    if (pointerType === "touch") {
      ACTIONSHEET[
        ACTIONSHEET.matches(":open") ? "hidePopover" : "showPopover"
      ]();
    }
  });
};

const activateDrag = ({ y }) => {
  STATE.active = true;
  STATE.origin = y;
  ACTIONSHEET.style.transition = "none";
  document.body.addEventListener("pointermove", dragSheet);
  document.body.addEventListener("pointerup", endDrag);
};

HEADER.addEventListener("pointerdown", activateDrag);

External CSS

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.css
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.css

External JavaScript

  1. https://codepen.io/web-dot-dev/pen/XWqWYgB.js
  2. https://codepen.io/web-dot-dev/pen/ZExZWBQ.js