Sci-Fi Window Frames
HUD-style 160 × 110 px interface frames, cut by a 16-point polygon (notch + bevel at each corner), whose 2 px border is a conic gradient that turns continuously — one turn in 4 s, in 1.5 s and brighter on hover. 100% CSS, thanks to an animated custom property (@property).
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Glassmorphism has 47 effects, including 6 free. Explore the category →
3 usage examples



How it works
Each .scifi-frame stacks three layers. .scifi-frame__border (inset: 0) is painted with a conic-gradient(from var(--sf-angle), #00ffcc, #6366f1, #ec4899, #00ffcc); .scifi-frame__inner, set 2 px further in (inset: 2px), covers it with a dark #0a0a1a → #0f0f2e gradient: only a 2 px rim of the conic gradient remains visible. Both layers are cut by the same 16-point clip-path: polygon() in percentages: at each corner, a notch 3% high by 6% wide (3.3 × 9.6 px at the original size) then a 6% × 7% bevel (9.6 × 7.7 px). The shape is written in the CSS: no clip-path: url(#…), no SVG to provide. The content .scifi-frame__content sits on top (z-index: 1), centered, in Courier New: a 9.6 px capitalized title at 70%, a 20.8 px weight-800 value, cyan #00ffcc.
The rotation fits in one line: @property --sf-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false } declares the variable as an angle, which allows animating it from 0 to 360° (@keyframes scifi-rotate, 4 s, linear, infinite). Measured in Chromium 151, Firefox 153 and WebKit 26.5: about 90° per second in all three. On hover, the duration drops to 1.5 s and the border gets filter: brightness(1.4), the text a cyan text-shadow glow. Changing the duration of a running animation re-maps its progress: measured, the angle jumps by about 160° when the pointer enters (90° → 248° in Chromium, 96° → 264° in Firefox) and as much when it leaves — the border “snaps” as it lights up instead of speeding up smoothly. The second frame of a group (:nth-child(2)) gets a pink-orange-cyan palette and #ff6b9d text.
Tested pasted into a blank page, the sold code works as is in all three engines: polygon applied, rotation, hover, no error. Two details worth knowing. The cut applies to the two decorative layers, not to the container: hover also triggers in the cut corners (measured, the point 2 px from the corner belongs to .scifi-frame). And the content is not cut: text wider than the frame overflows it — size the frame to its content, as in the scenes.
Accessibility
- Continuous motion: the border turns endlessly, and
prefers-reduced-motionis not taken into account (measured: animation still running under emulation). For content that moves for more than 5 s next to other information, WCAG 2.2.2 asks for a way to stop it. Add:@media (prefers-reduced-motion: reduce) { .scifi-frame__border { animation: none } }— the rim stays drawn as a fixed gradient. On a reading page, keep to one or two animated frames. - Contrast: the cyan value
#00ffccmeasures 15.1:1 on the#0a0a1abackground, and the 70% title 7.6:1. In the second frame's pink palette, the#ff6b9dvalue is 7.3:1 but the 70% title drops to 4.0:1 at 9.6 px: raise it toopacity: .85or more. - Screen readers: the two decorative layers are empty
divs, ignored. The content is read in HTML order (“System Status ONLINE”): use a real heading (h3) if the frame structures the page, and write values in lower case in the HTML, withtext-transform: uppercaseadded to.sf-valuefor display: some readers spell out a word typed in capitals (the sold code's “ONLINE”), whereas the title is already capitalized by the CSS. - Keyboard: the frames are not focusable and their hover (speed-up, glow) is purely decorative; nothing is lost without a mouse. If they become links, add
:focus-visibleto the:hoverrules.
Browser compatibility
CSS only: @property, custom-property animation, conic-gradient, clip-path: polygon(), filter, text-shadow. Zero JavaScript, zero dependencies. Measured pasted into a blank page in Chromium 151, Firefox 153 and Playwright's WebKit 26.5: same polygon, same rotation (about 90° per second), same hover. Each frame repaints the gradient (a custom property is not animated on the GPU): fine for a few frames, worth watching beyond ten visible at once.
Without @property (Firefox before 128, Safari before 16.4, Chrome before 85), the variable is not recognized as an angle and does not animate: the border should stay a fixed conic gradient, frame and text intact (expected behavior, not measured: the three engines tested support @property). Without conic-gradient (Firefox before 83), the border disappears: only the cut dark background remains. clip-path: polygon() is supported unprefixed since Chrome 55, Firefox 54 and Safari 13.1.
The code
HTML structure to paste into your page (the CSS + JS come with Premium):
<div class="demo-preview">
<div class="scifi-frames-wrap">
<div class="scifi-frame">
<div class="scifi-frame__border"></div>
<div class="scifi-frame__inner"></div>
<div class="scifi-frame__content">
<div class="sf-title">…</div>
<div class="sf-value">…</div>
</div>
</div>
…
</div>
</div>
The full HTML + CSS + JS of Sci-Fi Window Frames, ready to paste — plus all 840 effects. Or $299 once, lifetime access.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Frame size (CSS — .scifi-frame { width: 160px; height: 110px }) |
160 × 110 px | The polygon is in percentages: it follows the size, but the corners stretch with it (a 30 × 7 px bevel on a 504 × 96 frame). For fixed corners, write the points with calc(): polygon(12px 0, calc(100% - 12px) 0, …). |
Corner shape (CSS — clip-path: polygon(…) of __border AND __inner) |
6% × 3% notch + 6% × 7% bevel | Change both polygons identically, otherwise the rim thickens in places. Removing the notch points (88% 3%, 94% 3% and their mirrors) leaves a simple bevel. |
Border thickness (CSS — .scifi-frame__inner { inset: 2px }) |
2 px | 3 or 4 px for a screen seen from afar (stand, museum). Since the inner layer's polygon is in percentages of a smaller box, the rim is slightly thinner on the bevels than on the straight sides. |
Speed (CSS — animation: scifi-rotate 4s; hover: animation-duration: 1.5s) |
4 s per turn · 1.5 s on hover | 8 s for a calmer permanent display. Remove the hover rule if the angle jump when the pointer enters (about 160°, measured) bothers you; keep only the brightness. |
Colors (CSS — conic-gradient(…) and content color; :nth-child(2) variant) |
#00ffcc → #6366f1 → #ec4899 · variant #ff6b9d → #f59e0b → #06b6d4 | End the gradient with its first color, otherwise a seam shows. The pink variant only affects the 2nd child: for more palettes, add classes (.scifi-frame--alert) rather than nth-child. |
Inner background (CSS — .scifi-frame__inner { background }) |
#0a0a1a → #0f0f2e | Keep it opaque: semi-transparent, it would reveal the whole conic gradient beneath. |
FAQ
brightness(1.4) applied at the same moment, the frame “lights up” at once. For a speed-up without a jump, the speed would have to be driven in JavaScript (Web Animations API, animation.playbackRate).@property (Safari before 16.4, Firefox before 128), the --sf-angle variable cannot be animated: the border stays a fixed gradient (expected, not measured), and everything else — shape, background, text, bright hover — is identical. Nothing breaks, the frame is just still.