View Transition API
View Transition API is not a Blue Web API, but a native Web API provided by browsers.
It allows you to easily animate transitions between different UI states.
Code
<style>
@keyframes fillUp {
from {
clip-path: inset(100% 0 0 0);
opacity: 1;
}
to {
clip-path: inset(0 0 0 0);
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 1;
}
}
::view-transition-old(bellIcon) {
animation: fadeOut 0.4s linear;
z-index: 1;
}
::view-transition-new(bellIcon) {
animation: fillUp 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 2;
}
</style>
<div class="position-relative mb-5">
<button type="button" class="blue-menu-item btn">
<span id="bellIcon" class="blue-menu-item-icon" aria-hidden="true" style="view-transition-name: bellIcon"
><svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
class="bi bi-bell"
viewBox="0 0 16 16"
>
<path
d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6"
/></svg
><svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
class="bi bi-bell-fill d-none"
viewBox="0 0 16 16"
>
<path
d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2m.995-14.901a1 1 0 1 0-1.99 0A5 5 0 0 0 3 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901"
/></svg
></span>
<span class="blue-menu-item-label">Parent</span>
</button>
<div
id="targetMenu"
class="blue-menu-item-dropdown d-inline-flex flex-column text-body"
style="--blue-menu-item-dropdown-bg: var(--bs-body-bg);"
>
<button type="button" class="blue-menu-item btn">
<span class="blue-menu-item-icon" aria-hidden="true">π</span>
<span class="blue-menu-item-label">Child</span>
</button>
</div>
</div>
<div id="itemsToAdd" class="d-inline-flex flex-column">
<button type="button" class="blue-menu-item btn" style="view-transition-name: newItem1">
<span class="blue-menu-item-icon" aria-hidden="true">π</span>
<span class="blue-menu-item-label">Child 2</span>
</button>
<button type="button" class="blue-menu-item btn" style="view-transition-name: newItem2">
<span class="blue-menu-item-icon" aria-hidden="true">π</span>
<span class="blue-menu-item-label">Child 3</span>
</button>
</div>
<script>
function moveItem(item) {
document.getElementById("targetMenu").appendChild(item)
document.querySelector("#bellIcon .bi-bell").classList.add("d-none")
document.querySelector("#bellIcon .bi-bell-fill").classList.remove("d-none")
}
document.addEventListener("DOMContentLoaded", () => {
for (const item of document.querySelectorAll("#itemsToAdd > button")) {
;(() => {
item.addEventListener("click", () => {
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
moveItem(item)
return
}
// With a View Transition:
document.startViewTransition(() => moveItem(item))
})
})()
}
})
</script>