List Movement
Home
Snippets
List Movement
HTML
CSS
JS
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" /> <ul class="list"> <li>Apples <button hidden disabled aria-label="Move to Top"> <i class="fa-solid fa-arrow-up"></i></button></li> <li>Oranges <button hidden aria-label="Move to Top"> <i class="fa-solid fa-arrow-up"></i> </button></li> <li>Mangos <button hidden aria-label="Move to Top"> <i class="fa-solid fa-arrow-up"></i> </button></li> <li>Bananas <button hidden aria-label="Move to Top"> <i class="fa-solid fa-arrow-up"></i> </button></li> </ul>
body { height: 100vh; margin: 0; display: grid; place-items: center; font-family: Avenir, Montserrat, Corbel, "URW Gothic", source-sans-pro, sans-serif; } ul { list-style: none; margin: 0; padding: 0; li { background: lightskyblue; padding: 0.5rem 3rem 0.5rem 1rem; margin-block-end: 0.25rem; view-transition-name: match-element; position: relative; button { position: absolute; top: 0; right: 0; height: 100%; width: 30px; border: 0; background: skyblue; display: grid; place-items: center; &[hidden] { display: none; } &:focus, &:hover { background: lch(100% 0 0 / 75%); } &:disabled { .fa-solid, & { opacity: 0.5; } } .fa-solid { width: 20px !important; view-transition-name: match-element; } } } } ::view-transition-group(*) { animation-duration: 1s; } ::view-transition-old(woosh), ::view-transition-new(woosh) { animation: woosh 1s ease-in-out; } @keyframes woosh { 50% { translate: -100px 0; scale: 1.5; box-shadow: 0 30px 15px lch(0% 0 0 / 50%); } } ::view-transition-old(tony-hawk), ::view-transition-new(tony-hawk) { animation: tony-hawk 1s ease-in-out; } @keyframes tony-hawk { 50% { rotate: 20deg; scale: 2.5; } }
const button = document.querySelector("button"); const list = document.querySelector(".list"); let listItems = list.querySelectorAll("li"); const listItemButtons = list.querySelectorAll("li > button"); function makeFirstListItemsButtonDisabled() { listItems = list.querySelectorAll("li"); listItems.forEach((item) => { item.querySelector("button").disabled = false; }); listItems[0].querySelector("button").disabled = true; } function moveListItemFirst(item) { const firstListItem = list.querySelector(".list :first-child"); list.insertBefore(item, firstListItem); } listItemButtons.forEach((button) => { button.hidden = false; button.addEventListener("click", async () => { const item = button.parentElement; item.style.viewTransitionName = "woosh"; item.querySelector(".fa-solid").style.viewTransitionName = "tony-hawk"; if (document.startViewTransition) { const transition = document.startViewTransition(() => { moveListItemFirst(item); }); try { await transition.finished; } finally { item.style.viewTransitionName = ""; item.querySelector(".fa-solid").style.viewTransitionName = ""; makeFirstListItemsButtonDisabled(); } } else { moveListItemFirst(item); } }); });
Ad #1
Ad #2
Scroll to Top