Komponenty UI Łatwy
Aurora Text
Text with aurora borealis colors (green, purple, blue) flowing through it with animated gradient layers and optional blur glow.
Otwórz w Lab
MCP
css javascript vue svelte
Targety: TS JS HTML React Vue Svelte
Kod
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: system-ui, -apple-system, sans-serif;
min-height: 100vh;
display: grid;
place-items: center;
background: #0a0a0a;
overflow: hidden;
}
.container {
text-align: center;
padding: 2rem;
}
/* --- Aurora Text --- */
.aurora-wrapper {
position: relative;
display: inline-block;
}
.aurora-text {
--aurora-1: #00ff87;
--aurora-2: #7c3aed;
--aurora-3: #00d4ff;
--aurora-speed: 6s;
position: relative;
z-index: 1;
font-size: clamp(2.5rem, 7vw, 5.5rem);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1.1;
background: linear-gradient(
135deg,
var(--aurora-1) 0%,
var(--aurora-2) 33%,
var(--aurora-3) 66%,
var(--aurora-1) 100%
);
background-size: 300% 300%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: aurora-shift var(--aurora-speed) ease-in-out infinite;
}
@keyframes aurora-shift {
0%,
100% {
background-position: 0% 50%;
}
25% {
background-position: 100% 0%;
}
50% {
background-position: 100% 100%;
}
75% {
background-position: 0% 100%;
}
}
/* Blurred glow behind text */
.aurora-glow {
position: absolute;
inset: 0;
z-index: 0;
font-size: clamp(2.5rem, 7vw, 5.5rem);
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1.1;
white-space: nowrap;
background: linear-gradient(
135deg,
var(--aurora-1, #00ff87) 0%,
var(--aurora-2, #7c3aed) 33%,
var(--aurora-3, #00d4ff) 66%,
var(--aurora-1, #00ff87) 100%
);
background-size: 300% 300%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
filter: blur(28px) brightness(1.5);
opacity: 0.6;
animation: aurora-shift 6s ease-in-out infinite;
animation-delay: -0.5s;
pointer-events: none;
user-select: none;
}
.subtitle {
margin-top: 1.5rem;
font-size: 1rem;
color: #666;
letter-spacing: 0.01em;
position: relative;
z-index: 1;
}
/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
.aurora-text,
.aurora-glow {
animation: none;
}
}// Aurora Text — the core effect is CSS-only.
// This optional script adds a subtle canvas aurora backdrop for enhanced depth.
(function () {
"use strict";
const wrapper = document.querySelector(".aurora-wrapper");
if (!wrapper) return;
// Respect reduced motion
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (prefersReducedMotion) return;
const canvas = document.createElement("canvas");
canvas.width = 600;
canvas.height = 200;
Object.assign(canvas.style, {
position: "absolute",
inset: "0",
width: "100%",
height: "100%",
zIndex: "0",
opacity: "0.3",
pointerEvents: "none",
filter: "blur(40px)",
});
canvas.setAttribute("aria-hidden", "true");
wrapper.style.position = "relative";
wrapper.prepend(canvas);
const ctx = canvas.getContext("2d");
let t = 0;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const w = canvas.width;
const h = canvas.height;
// Draw flowing aurora bands
for (let i = 0; i < 3; i++) {
const offset = i * 1.2;
ctx.beginPath();
ctx.moveTo(0, h * 0.5);
for (let x = 0; x <= w; x += 4) {
const y =
h * 0.5 +
Math.sin((x / w) * Math.PI * 2 + t * 0.8 + offset) * 30 +
Math.sin((x / w) * Math.PI * 3 + t * 1.2 + offset) * 20;
ctx.lineTo(x, y);
}
ctx.lineTo(w, h);
ctx.lineTo(0, h);
ctx.closePath();
const colors = [
"rgba(0, 255, 135, 0.4)",
"rgba(124, 58, 237, 0.4)",
"rgba(0, 212, 255, 0.4)",
];
ctx.fillStyle = colors[i];
ctx.fill();
}
t += 0.015;
requestAnimationFrame(draw);
}
draw();
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Aurora Text</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="aurora-wrapper">
<h1 class="aurora-text">Aurora Borealis</h1>
<div class="aurora-glow" aria-hidden="true">Aurora Borealis</div>
</div>
<p class="subtitle">Northern lights flowing through text</p>
</div>
<script src="script.js"></script>
</body>
</html>import { useEffect, useRef } from "react";
import type { CSSProperties, ReactNode } from "react";
interface AuroraTextProps {
children: ReactNode;
colors?: [string, string, string];
speed?: string;
className?: string;
}
export function AuroraText({
children,
colors = ["#00ff87", "#7c3aed", "#00d4ff"],
speed = "6s",
className = "",
}: AuroraTextProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (prefersReducedMotion) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let t = 0;
let animationFrameId: number;
const defaultColors = [
"rgba(0, 255, 135, 0.4)",
"rgba(124, 58, 237, 0.4)",
"rgba(0, 212, 255, 0.4)",
];
function draw() {
ctx!.clearRect(0, 0, canvas!.width, canvas!.height);
const w = canvas!.width;
const h = canvas!.height;
// Draw flowing aurora bands
for (let i = 0; i < 3; i++) {
const offset = i * 1.2;
ctx!.beginPath();
ctx!.moveTo(0, h * 0.5);
for (let x = 0; x <= w; x += 4) {
const y =
h * 0.5 +
Math.sin((x / w) * Math.PI * 2 + t * 0.8 + offset) * 30 +
Math.sin((x / w) * Math.PI * 3 + t * 1.2 + offset) * 20;
ctx!.lineTo(x, y);
}
ctx!.lineTo(w, h);
ctx!.lineTo(0, h);
ctx!.closePath();
ctx!.fillStyle = defaultColors[i];
ctx!.fill();
}
t += 0.015;
animationFrameId = requestAnimationFrame(draw);
}
draw();
return () => {
cancelAnimationFrame(animationFrameId);
};
}, []);
const textStyle: CSSProperties = {
position: "relative",
zIndex: 1,
backgroundImage: `linear-gradient(135deg, ${colors[0]} 0%, ${colors[1]} 33%, ${colors[2]} 66%, ${colors[0]} 100%)`,
backgroundSize: "300% 300%",
WebkitBackgroundClip: "text",
backgroundClip: "text",
WebkitTextFillColor: "transparent",
animation: `aurora-shift ${speed} ease-in-out infinite`,
};
const glowStyle: CSSProperties = {
...textStyle,
position: "absolute",
inset: 0,
zIndex: 0,
filter: "blur(28px) brightness(1.5)",
opacity: 0.6,
animationDelay: "-0.5s",
pointerEvents: "none",
userSelect: "none",
};
return (
<>
<style>{`
@keyframes aurora-shift {
0%, 100% { background-position: 0% 50%; }
25% { background-position: 100% 0%; }
50% { background-position: 100% 100%; }
75% { background-position: 0% 100%; }
}
@media (prefers-reduced-motion: reduce) {
.aurora-text-component, .aurora-glow-component { animation: none !important; }
}
`}</style>
<span style={{ position: "relative", display: "inline-block" }}>
<canvas
ref={canvasRef}
width={600}
height={200}
style={{
position: "absolute",
inset: 0,
width: "100%",
height: "100%",
zIndex: 0,
opacity: 0.3,
pointerEvents: "none",
filter: "blur(40px)",
}}
aria-hidden="true"
/>
<span className={`aurora-glow-component ${className}`} style={glowStyle} aria-hidden="true">
{children}
</span>
<span className={`aurora-text-component ${className}`} style={textStyle}>
{children}
</span>
</span>
</>
);
}
// Demo usage
export default function AuroraTextDemo() {
return (
<div
style={{
minHeight: "100vh",
display: "grid",
placeItems: "center",
background: "#0a0a0a",
fontFamily: "system-ui, -apple-system, sans-serif",
textAlign: "center",
padding: "2rem",
}}
>
<div>
<h1
style={{
fontSize: "clamp(2.5rem, 7vw, 5.5rem)",
fontWeight: 900,
letterSpacing: "-0.03em",
lineHeight: 1.1,
}}
>
<AuroraText>Aurora Borealis</AuroraText>
</h1>
<p
style={{
marginTop: "1.5rem",
color: "#666",
fontSize: "1rem",
position: "relative",
zIndex: 1,
}}
>
Northern lights flowing through text
</p>
</div>
</div>
);
}<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
const props = withDefaults(
defineProps<{
colors?: [string, string, string];
speed?: string;
}>(),
{
colors: () => ["#00ff87", "#7c3aed", "#00d4ff"],
speed: "6s",
}
);
const canvasRef = ref<HTMLCanvasElement | null>(null);
let animationFrameId = 0;
onMounted(() => {
const canvas = canvasRef.value;
if (!canvas) return;
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (prefersReducedMotion) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let t = 0;
const defaultColors = [
"rgba(0, 255, 135, 0.4)",
"rgba(124, 58, 237, 0.4)",
"rgba(0, 212, 255, 0.4)",
];
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const w = canvas.width;
const h = canvas.height;
for (let i = 0; i < 3; i++) {
const offset = i * 1.2;
ctx.beginPath();
ctx.moveTo(0, h * 0.5);
for (let x = 0; x <= w; x += 4) {
const y =
h * 0.5 +
Math.sin((x / w) * Math.PI * 2 + t * 0.8 + offset) * 30 +
Math.sin((x / w) * Math.PI * 3 + t * 1.2 + offset) * 20;
ctx.lineTo(x, y);
}
ctx.lineTo(w, h);
ctx.lineTo(0, h);
ctx.closePath();
ctx.fillStyle = defaultColors[i];
ctx.fill();
}
t += 0.015;
animationFrameId = requestAnimationFrame(draw);
}
draw();
});
onUnmounted(() => {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
});
</script>
<template>
<div style="min-height:100vh;display:grid;place-items:center;background:#0a0a0a;font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:2rem">
<div>
<h1 style="font-size:clamp(2.5rem,7vw,5.5rem);font-weight:900;letter-spacing:-0.03em;line-height:1.1">
<span style="position:relative;display:inline-block">
<canvas ref="canvasRef" width="600" height="200" style="position:absolute;inset:0;width:100%;height:100%;z-index:0;opacity:0.3;pointer-events:none;filter:blur(40px)"></canvas>
<span class="aurora-glow" :style="{
position:'absolute',inset:0,zIndex:0,filter:'blur(28px) brightness(1.5)',opacity:0.6,animationDelay:'-0.5s',pointerEvents:'none',userSelect:'none',
backgroundImage:`linear-gradient(135deg,${props.colors[0]} 0%,${props.colors[1]} 33%,${props.colors[2]} 66%,${props.colors[0]} 100%)`,
backgroundSize:'300% 300%',WebkitBackgroundClip:'text',backgroundClip:'text',WebkitTextFillColor:'transparent',
animation:`aurora-shift ${props.speed} ease-in-out infinite`
}" aria-hidden="true">Aurora Borealis</span>
<span class="aurora-text" :style="{
position:'relative',zIndex:1,
backgroundImage:`linear-gradient(135deg,${props.colors[0]} 0%,${props.colors[1]} 33%,${props.colors[2]} 66%,${props.colors[0]} 100%)`,
backgroundSize:'300% 300%',WebkitBackgroundClip:'text',backgroundClip:'text',WebkitTextFillColor:'transparent',
animation:`aurora-shift ${props.speed} ease-in-out infinite`
}">Aurora Borealis</span>
</span>
</h1>
<p style="margin-top:1.5rem;color:#666;font-size:1rem;position:relative;z-index:1">Northern lights flowing through text</p>
</div>
</div>
</template>
<style scoped>
@keyframes aurora-shift {
0%, 100% { background-position: 0% 50%; }
25% { background-position: 100% 0%; }
50% { background-position: 100% 100%; }
75% { background-position: 0% 100%; }
}
@media (prefers-reduced-motion: reduce) {
.aurora-text, .aurora-glow { animation: none !important; }
}
</style><script>
import { onMount } from "svelte";
export let colors = ["#00ff87", "#7c3aed", "#00d4ff"];
export let speed = "6s";
let canvasRef;
onMount(() => {
const canvas = canvasRef;
if (!canvas) return;
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (prefersReducedMotion) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let t = 0;
let animationFrameId;
const defaultColors = [
"rgba(0, 255, 135, 0.4)",
"rgba(124, 58, 237, 0.4)",
"rgba(0, 212, 255, 0.4)",
];
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const w = canvas.width;
const h = canvas.height;
for (let i = 0; i < 3; i++) {
const offset = i * 1.2;
ctx.beginPath();
ctx.moveTo(0, h * 0.5);
for (let x = 0; x <= w; x += 4) {
const y =
h * 0.5 +
Math.sin((x / w) * Math.PI * 2 + t * 0.8 + offset) * 30 +
Math.sin((x / w) * Math.PI * 3 + t * 1.2 + offset) * 20;
ctx.lineTo(x, y);
}
ctx.lineTo(w, h);
ctx.lineTo(0, h);
ctx.closePath();
ctx.fillStyle = defaultColors[i];
ctx.fill();
}
t += 0.015;
animationFrameId = requestAnimationFrame(draw);
}
draw();
return () => {
cancelAnimationFrame(animationFrameId);
};
});
</script>
<div style="min-height:100vh;display:grid;place-items:center;background:#0a0a0a;font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:2rem">
<div>
<h1 style="font-size:clamp(2.5rem,7vw,5.5rem);font-weight:900;letter-spacing:-0.03em;line-height:1.1">
<span style="position:relative;display:inline-block">
<canvas bind:this={canvasRef} width="600" height="200" style="position:absolute;inset:0;width:100%;height:100%;z-index:0;opacity:0.3;pointer-events:none;filter:blur(40px)"></canvas>
<span class="aurora-glow" style="position:absolute;inset:0;z-index:0;filter:blur(28px) brightness(1.5);opacity:0.6;animation-delay:-0.5s;pointer-events:none;user-select:none;background-image:linear-gradient(135deg,{colors[0]} 0%,{colors[1]} 33%,{colors[2]} 66%,{colors[0]} 100%);background-size:300% 300%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:aurora-shift {speed} ease-in-out infinite" aria-hidden="true">Aurora Borealis</span>
<span class="aurora-text" style="position:relative;z-index:1;background-image:linear-gradient(135deg,{colors[0]} 0%,{colors[1]} 33%,{colors[2]} 66%,{colors[0]} 100%);background-size:300% 300%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:aurora-shift {speed} ease-in-out infinite">Aurora Borealis</span>
</span>
</h1>
<p style="margin-top:1.5rem;color:#666;font-size:1rem;position:relative;z-index:1">Northern lights flowing through text</p>
</div>
</div>
<style>
@keyframes aurora-shift {
0%, 100% { background-position: 0% 50%; }
25% { background-position: 100% 0%; }
50% { background-position: 100% 100%; }
75% { background-position: 0% 100%; }
}
@media (prefers-reduced-motion: reduce) {
.aurora-text, .aurora-glow { animation: none !important; }
}
</style>Aurora Text
Text that shimmers with northern-lights colors — green, purple, and blue gradients that flow and blend organically through the text.
How it works
- Multiple animated gradients are layered using
background-clip: text - Each gradient layer animates at a different speed and direction for organic movement
- A blurred pseudo-element behind the text creates a soft ambient glow
- Colors are inspired by the aurora borealis: emerald green, violet purple, and cyan blue
Customization
- Override aurora colors via
--aurora-1,--aurora-2,--aurora-3CSS custom properties - Control glow intensity with
--aurora-glow(blur radius of the backdrop) - Adjust animation speed with
--aurora-speed
When to use it
- Dark-themed hero sections
- Feature headings that need an ethereal, premium feel
- Creative portfolio titles