Shield
CSSA shield fills from its base and a check settles at its centre once it is whole.
- Tier
- CSS
- Dependencies
- None
- Duration
- 4 s, loops
- Categories
- Icons and micro-interactions
- Use cases
- Success and confirmation, Security and trust
- Industries
- Healthcare and life sciences, Security and identity
- Style
- Geometric solid · none stroke
- Set
- vault
- Tags
- loopgeometricui
Companion assets
The same artwork, not animated. Derived from the entry’s own resting state, so it matches exactly.
Code
animation.svg
<svg xmlns="http://www.w3.org/2000/svg" aria-labelledby="vault-shield-title" class="pulsar pulsar-vault-shield" data-pulsar="vault-shield" role="img" viewBox="0 0 48 48"><title id="vault-shield-title">Shield</title><defs><mask id="vault-shield-fill-mask"><rect width="48" height="48"></rect><rect id="vault-shield-mask-rect" width="48" height="48" fill="#fff"></rect></mask><mask id="vault-shield-check-mask"><rect width="48" height="48" fill="#fff"></rect><path id="vault-shield-check-path" fill="#000" d="m16 22 6 6 10-10v4L22 32l-6-6Z"></path></mask></defs><path fill="currentColor" d="M6 4h36v20c0 11-9 20-18 20S6 35 6 24Z" opacity=".1"></path><g mask="url(#vault-shield-fill-mask)"><path fill="currentColor" d="M6 4h36v20c0 11-9 20-18 20S6 35 6 24Z" mask="url(#vault-shield-check-mask)"></path></g></svg>
animation.css
/* Accent: the rising fill inside the mask, against the shield outline behind it. */
.pulsar-vault-shield g path {
fill: var(--pulsar-accent, currentColor);
}
.pulsar-vault-shield #vault-shield-mask-rect {
transform-box: view-box;
animation: vault-shield-fill 4000ms ease-in-out infinite;
}
/*
The fill level, as a transform rather than the rect's own y and height.
Chromium does not re-render a mask when its children's geometry properties
animate, so the original held the rect at height 0 forever and the shield
never filled: five identical frames, none of which showed the animation.
*/
@keyframes vault-shield-fill {
0% {
transform: translateY(44px);
}
35%,
90% {
transform: translateY(4px);
}
100% {
transform: translateY(44px);
}
}
.pulsar-vault-shield #vault-shield-check-path {
transform-origin: 24px 25px;
transform-box: view-box;
animation: vault-shield-check 4000ms ease-in-out infinite;
}
@keyframes vault-shield-check {
0% {
transform: scale(0);
opacity: 0;
}
35% {
transform: scale(0);
opacity: 0;
}
55% {
transform: scale(1);
opacity: 1;
}
80% {
transform: scale(1);
opacity: 1;
}
90% {
transform: scale(1);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.pulsar-vault-shield #vault-shield-mask-rect {
animation: none;
transform: translateY(4px);
}
.pulsar-vault-shield #vault-shield-check-path {
animation: none;
transform: scale(1);
opacity: 1;
}
}