<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>https://codepen.io/jh3y/pen/vYqLPaE</title> <style> @import url('https://unpkg.com/normalize.css') layer(normalize); @layer normalize, base, demo; @layer demo { :root { --accent: red; --canvas: color-mix(in lch, canvas, canvasText 1%); --border: color-mix(in lch, canvas, canvasText 10%); --text: color-mix(in lch, canvasText, canvas 25%); --border-radius: 24; --border-width: 3; --trail-size: 25; } aside { --font-level: 1; width: 66ch; max-width: calc(100vw - 4rem); line-height: 1.5; container-type: inline-size; position: relative; } .border { position: absolute; inset: 0; clip-path: inset(0 0 0 0 round calc(var(--border-radius) * 1px)); border-radius: calc(var(--border-radius) * 1px); background: var(--border); z-index: -1; border: 0; container-type: inline-size; } .trail { width: calc(var(--trail-size) * 1cqmin); aspect-ratio: 2 / 1; position: absolute; background: radial-gradient( 100% 100% at right, var(--accent, red), transparent 50% ); offset-path: border-box; offset-anchor: 100% 50%; animation: journey var(--speed, 6s) infinite linear; } @container(width > 600px) { .trail { --speed: 12s; } } @keyframes journey { to { offset-distance: 100%; } } aside p { font-weight: 300; text-align: center; margin: 0; color: var(--text); } .content { background: linear-gradient(var(--canvas), var(--canvas)) padding-box, transparent; border: calc(var(--border-width) * 1px) solid transparent; border-radius: calc(var(--border-radius) * 1px); padding: clamp(1rem, 3vmin + 1rem, 6rem); display: grid; gap: clamp(1rem, 3vmin + 1rem, 4rem); } aside footer { --font-level: 0.5; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; font-weight: 500; gap: 0.5rem 1rem; } footer span:nth-of-type(2) { color: color-mix(in lch, canvasText, canvas 70%); } aside img { width: 2.5rem; aspect-ratio: 1; border-radius: 50%; } /* 3D stuff */ [data-explode='true'] aside { transform: scale(0.75) rotateX(-24deg) rotateY(30deg); } :root { --t: 1s; --d: 1s; } [data-explode='true'] aside { transition: transform var(--t); } [data-explode='true'] .border { transition: clip-path var(--t) calc(var(--d) * 2); } [data-explode='true'] .border { clip-path: inset( -100% -100% -100% -100% round calc(var(--border-radius) * 1px) ); } body { background: radial-gradient( 80% 80% at 75% 25%, hsl(280 100% 98% / 0.1), transparent ), radial-gradient(80% 80% at 50% 100%, hsl(180 100% 98% / 0.1), transparent), radial-gradient(circle at 0 0, hsl(10 100% 98% / 0.1), transparent); background-blend-mode: lighten; } main * { transform-style: preserve-3d; } [data-explode='true'] .content { transition: transform var(--t) calc(var(--d) * 1), opacity calc(var(--t) * 0.5) calc(var(--d) * 1.5); } [data-explode='true'] .content { transform: translate3d(0, 0, 400px); opacity: 0; } .border { transition: clip-path var(--t); } aside { transition: transform var(--t) calc(var(--d) * 2); } .content { transition: transform var(--t) calc(var(--d) * 1), opacity calc(var(--t) * 0.5) calc(var(--d) * 0.5); } } @layer base { :root { --font-size-min: 17; --font-size-max: 20; --font-ratio-min: 1.2; --font-ratio-max: 1.33; --font-width-min: 320; --font-width-max: 1500; } :where(.fluid) { --fluid-min: calc( var(--font-size-min) * pow(var(--font-ratio-min), var(--font-level, 0)) ); --fluid-max: calc( var(--font-size-max) * pow(var(--font-ratio-max), var(--font-level, 0)) ); --fluid-preferred: calc( (var(--fluid-max) - var(--fluid-min)) / (var(--font-width-max) - var(--font-width-min)) ); --fluid-type: clamp( (var(--fluid-min) / 16) * 1rem, ((var(--fluid-min) / 16) * 1rem) - (((var(--fluid-preferred) * var(--font-width-min)) / 16) * 1rem) + (var(--fluid-preferred) * var(--variable-unit, 100vi)), (var(--fluid-max) / 16) * 1rem ); font-size: var(--fluid-type); } *, *:after, *:before { box-sizing: border-box; } body { display: flex; place-items: center; justify-content: center; min-height: 100vh; font-family: 'SF Pro Text', 'SF Pro Icons', 'AOS Icons', 'Helvetica Neue', Helvetica, Arial, sans-serif, system-ui; } body::before { --size: 45px; --line: color-mix(in lch, canvasText, transparent 70%); content: ''; height: 100vh; width: 100vw; position: fixed; background: linear-gradient( 90deg, var(--line) 1px, transparent 1px var(--size) ) 50% 50% / var(--size) var(--size), linear-gradient(var(--line) 1px, transparent 1px var(--size)) 50% 50% / var(--size) var(--size); mask: linear-gradient(-20deg, transparent 50%, white); top: 0; transform-style: flat; pointer-events: none; z-index: -1; } /* Utilities */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } } div.tp-dfwv { width: 274px; } </style> </head> <body> <main> <aside class="fluid"> <div class="border"> <div class="trail"></div> </div> <div class="content"> <p> Some of the most interesting CSS tricks use properties that you might have never even heard of. My goal is to make you confident in your abilities to make your ideas come to life with those tricks. </p> <footer class="fluid"> <img src="https://assets.codepen.io/605876/cropped-headshot--saturated-low-res.jpg" alt="Jhey Tompkins" /> <span>Jhey Tompkins</span><span>Author, great-animation.dev</span> </footer> </div> </aside> </main> </body> </html> 提示:你可以先修改部分代码再运行。 转载请注明:有爱前端 » 边框动画 喜欢 (0)or分享 (0)