Snippets: Border Animation
:root { --border-box-size: 160px; } .border-box::before, .border-box::after, .border-box { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .border-box { width: var(--border-box-size); height: var(--border-box-size); margin: auto; background: url("https://images.unsplash.com/photo-1510227272981-87123e259b17?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&fit=crop&h=400&w=400&s=3759e09a5b9fbe53088b23c615b6312e") no-repeat 50%/70% rgba(0, 0, 0, 0.1); color: #69ca62; box-shadow: inset 0 0 0 1px rgba(105, 202, 98, 0.5); } .border-box::before, .border-box::after { content: ""; z-index: -1; margin: -5%; box-shadow: inset 0 0 0 2px; animation: clipMe 8s linear infinite; } .border-box::before { animation-delay: -4s; } .border-box:hover::after, .border-box:hover::before { background-color: rgba(255, 0, 0, 0.3); } @keyframes clipMe { 0%, 100% { clip: rect(0px, calc(var(--border-box-size) * 1.1), 2px, 0px); } 25% { clip: rect(0px, 2px, calc(var(--border-box-size) * 1.1), 0px); } 50% { clip: rect(calc(var(--border-box-size) * 1.09), calc(var(--border-box-size) * 1.1), calc(var(--border-box-size) * 1.1), 0px); } 75% { clip: rect(0px, calc(var(--border-box-size) * 1.1), calc(var(--border-box-size) * 1.1), calc(var(--border-box-size) * 1.09)); } } html, body { height: 100vh; width: 100vw; } body { position: relative; background-color: #0f222b; } *, *::before, *::after { box-sizing: border-box; }
CSS Before Head
HTML Head
CSS After Head
JS Before HTML Body
<div class="border-box"></div>
HTML Body
HTML Foot
JS After HTML Body
Full HTML Code