electric-border-css
v1.0.1
Published
Stunning animated electric border effect using pure CSS and SVG. Available for React, Next.js, Vue, and Svelte.
Maintainers
Readme
⚡ Electric Border CSS
Stunning animated electric border effect using pure CSS and SVG
Live Demo • Documentation • Examples • Playground
📋 Table of Contents
- Features
- Quick Start
- Framework Support
- Color Presets
- Customization
- Props/API
- Browser Support
- Examples
- Troubleshooting
- FAQ
- Contributing
- License
✨ Features
🎨 Design
- Pure CSS & SVG animations
- 8+ stunning color presets
- Fully customizable colors
- Smooth, elegant effects
- Responsive on all devices
🚀 Developer Experience
- React, Next.js, Vue, Svelte ready
- Full TypeScript support
- Zero dependencies
- NPM package available
- Interactive playground included
⚡ Performance
- GPU-accelerated animations
- Hardware optimization
- Minimal bundle size
- Lazy-load compatible
- 60 FPS smooth
♿ Accessibility
- Respects
prefers-reduced-motion - Semantic HTML structure
- Keyboard navigation
- ARIA-compatible
- Screen reader friendly
🚀 Quick Start
HTML/CSS
1. Download or CDN (Coming Soon)
<!-- Option 1: Local Files -->
<link rel="stylesheet" href="style.css">
<!-- Option 2: CDN (Coming Soon) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/electric-border-css/style.css">2. Add HTML Structure
<!-- SVG Filter (place once per page) -->
<svg class="svg-container" style="position: absolute; width: 0; height: 0;">
<defs>
<filter id="turbulent-displace" colorInterpolationFilters="sRGB">
<!-- Filter definitions (see quick-start.html for full code) -->
</filter>
</defs>
</svg>
<!-- Your Electric Border Card -->
<div class="card-container">
<div class="inner-container">
<div class="border-outer">
<div class="main-card"></div>
</div>
<div class="glow-layer-1"></div>
<div class="glow-layer-2"></div>
</div>
<div class="overlay-1"></div>
<div class="overlay-2"></div>
<div class="background-glow"></div>
<div class="content-container">
<div class="content-top">
<div class="scrollbar-glass">Featured</div>
<p class="title">Your Title</p>
</div>
<hr class="divider" />
<div class="content-bottom">
<p class="description">Your description here.</p>
</div>
</div>
</div>3. Use Color Presets (Optional)
<!-- Apply preset class for instant color -->
<div class="card-container electric-purple">
<div class="card-container electric-pink">
<div class="card-container electric-green">💡 Pro Tip: Copy quick-start.html for a complete working example!
React
Installation
npm install electric-border-css
# or
yarn add electric-border-css
# or
pnpm add electric-border-cssBasic Usage
import { ElectricBorder } from 'electric-border-css/react';
import 'electric-border-css/react/ElectricBorder.css';
function App() {
return (
<ElectricBorder
preset="purple"
label="Featured"
title="Electric Border"
description="Beautiful animated effect"
/>
);
}With Custom Content
<ElectricBorder preset="cyan" width={400} height={600}>
<div className="custom-content">
<h1>Custom Content</h1>
<p>Full control over the card content!</p>
<button onClick={handleClick}>Action</button>
</div>
</ElectricBorder>TypeScript Support
import type { ElectricBorderProps } from 'electric-border-css/react';
const props: ElectricBorderProps = {
preset: 'purple',
width: 350,
height: 500,
animationSpeed: 3,
glowIntensity: 0.7,
};
<ElectricBorder {...props} />Next.js
Installation
npm install electric-border-cssApp Router (Next.js 13+)
// app/page.tsx
import { ElectricBorder } from 'electric-border-css/nextjs';
export default function Page() {
return (
<ElectricBorder
preset="cyan"
label="Interactive"
title="Click to Navigate"
href="/dashboard"
/>
);
}Pages Router (Next.js 12 and below)
// pages/index.tsx
import { ElectricBorder } from 'electric-border-css/nextjs';
export default function Home() {
return (
<ElectricBorder
preset="purple"
title="My Card"
/>
);
}Dynamic Routes
const products = [
{ id: 1, name: 'Product 1', color: 'purple' },
{ id: 2, name: 'Product 2', color: 'cyan' },
];
export default function Products() {
return (
<div className="grid">
{products.map(product => (
<ElectricBorder
key={product.id}
href={`/products/${product.id}`}
preset={product.color}
title={product.name}
/>
))}
</div>
);
}📚 Full Next.js Documentation →
Vue 3
Installation
npm install electric-border-cssBasic Usage
<script setup lang="ts">
import ElectricBorder from 'electric-border-css/vue';
const handleClick = () => {
console.log('Card clicked!');
};
</script>
<template>
<ElectricBorder
preset="pink"
label="Featured"
title="Electric Border"
description="Vue 3 Component"
@click="handleClick"
/>
</template>With Custom Content (Slots)
<template>
<ElectricBorder preset="green">
<div class="custom-content">
<h2>Custom Content</h2>
<p>Use slots for full control!</p>
<button @click="handleAction">Click Me</button>
</div>
</ElectricBorder>
</template>
<style scoped>
.custom-content {
padding: 48px;
display: flex;
flex-direction: column;
gap: 16px;
}
</style>Reactive State
<script setup lang="ts">
import { ref } from 'vue';
import ElectricBorder from 'electric-border-css/vue';
const currentColor = ref('#00fffb');
const intensity = ref(0.5);
</script>
<template>
<input type="color" v-model="currentColor" />
<input type="range" min="0.1" max="1" step="0.1" v-model="intensity" />
<ElectricBorder
:color="currentColor"
:glow-intensity="intensity"
label="Live Preview"
title="Customizable"
/>
</template>Svelte
Installation
npm install electric-border-cssBasic Usage
<script lang="ts">
import ElectricBorder from 'electric-border-css/svelte';
function handleClick() {
console.log('Card clicked!');
}
</script>
<ElectricBorder
preset="orange"
label="Featured"
title="Electric Border"
description="Svelte Component"
on:click={handleClick}
/>With Reactive Bindings
<script lang="ts">
import ElectricBorder from 'electric-border-css/svelte';
let currentColor = '#00fffb';
let speed = 3;
let intensity = 0.5;
</script>
<div class="controls">
<label>Color: <input type="color" bind:value={currentColor} /></label>
<label>Speed: <input type="range" min="1" max="10" step="0.5" bind:value={speed} /></label>
<label>Intensity: <input type="range" min="0.1" max="1" step="0.1" bind:value={intensity} /></label>
</div>
<ElectricBorder
color={currentColor}
animationSpeed={speed}
glowIntensity={intensity}
label="Live Preview"
title="Customizable"
/>SvelteKit
<!-- +page.svelte -->
<script lang="ts">
import { goto } from '$app/navigation';
import ElectricBorder from 'electric-border-css/svelte';
import type { PageData } from './$types';
export let data: PageData;
function navigateToProduct(id: number) {
goto(`/products/${id}`);
}
</script>
<div class="grid">
{#each data.products as product}
<ElectricBorder
preset={product.colorPreset}
label={product.category}
title={product.name}
on:click={() => navigateToProduct(product.id)}
/>
{/each}
</div>🎨 Color Presets
All components support 8 beautiful color presets:
| Preset | Color Code | Use Case |
|--------|-----------|----------|
| cyan (default) | #00fffb | Tech, Modern, Default |
| yellow | #f2ff00 | Attention, Bright, Energetic |
| purple | #b000ff | Premium, Luxury, Royal |
| pink | #ff00ff | Bold, Creative, Fun |
| green | #00ff88 | Success, Nature, Matrix |
| orange | #ff6600 | Warm, Energetic, Action |
| red | #ff0044 | Alert, Important, Bold |
| blue | #0088ff | Professional, Cool, Trust |
Usage:
// Framework components
<ElectricBorder preset="purple" />
// Vanilla CSS
<div class="card-container electric-purple">Custom Colors:
// Any hex, rgb, hsl color
<ElectricBorder color="#ff6600" />
<ElectricBorder color="rgb(255, 102, 0)" />
<ElectricBorder color="hsl(24, 100%, 50%)" />🎛️ Customization
Component Props
All framework components share these props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| width | number | 350 | Card width in pixels |
| height | number | 500 | Card height in pixels |
| color | string | - | Custom border color (overrides preset) |
| preset | 'cyan' \| 'yellow' \| 'purple' \| ... | 'cyan' | Color preset |
| animationSpeed | number | 3 | Animation duration in seconds (1-10) |
| glowIntensity | number | 0.5 | Glow opacity (0.1 - 1.0) |
| blurAmount | number | 28 | Background blur in pixels (10-50) |
| borderRadius | number | 24 | Border radius in pixels |
| label | string | - | Small label text |
| title | string | - | Main title text |
| description | string | - | Description text |
| disableHover | boolean | false | Disable hover effects |
CSS Variables (Vanilla)
:root {
/* Primary color */
--electric-border-color: #00fffb;
/* Auto-calculated (no need to change) */
--electric-light-color: oklch(from var(--electric-border-color) l c h);
--gradient-color: oklch(from var(--electric-border-color) 0.3 calc(c / 2) h / 0.4);
}Animation Speed
/* Slow and elegant */
.glow-layer-1 { animation-duration: 5s; }
/* Fast and energetic */
.glow-layer-1 { animation-duration: 1.5s; }Glow Intensity
/* Subtle */
.glow-layer-1 { opacity: 0.3; }
.glow-layer-2 { opacity: 0.2; }
/* Intense */
.glow-layer-1 { opacity: 0.8; }
.glow-layer-2 { opacity: 0.5; }📘 Props/API
React/Next.js
interface ElectricBorderProps {
width?: number;
height?: number;
color?: string;
preset?: 'cyan' | 'purple' | 'pink' | 'green' | 'orange' | 'red' | 'blue' | 'yellow';
animationSpeed?: number;
glowIntensity?: number;
blurAmount?: number;
borderRadius?: number;
label?: string;
title?: string;
description?: string;
children?: React.ReactNode;
className?: string;
style?: CSSProperties;
disableHover?: boolean;
onClick?: () => void;
// Next.js only
href?: string;
target?: '_blank' | '_self' | '_parent' | '_top';
}Vue 3
interface ElectricBorderProps {
width?: number;
height?: number;
color?: string;
preset?: 'cyan' | 'purple' | 'pink' | 'green' | 'orange' | 'red' | 'blue' | 'yellow';
animationSpeed?: number;
glowIntensity?: number;
blurAmount?: number;
borderRadius?: number;
label?: string;
title?: string;
description?: string;
customClass?: string;
disableHover?: boolean;
}
// Events
@click - Emitted when card is clicked
// Slots
<slot> - Default slot for custom contentSvelte
// Props
export let width: number = 350;
export let height: number = 500;
export let color: string | undefined = undefined;
export let preset: 'cyan' | 'purple' | ... = 'cyan';
export let animationSpeed: number = 3;
export let glowIntensity: number = 0.5;
export let blurAmount: number = 28;
export let borderRadius: number = 24;
export let label: string | undefined = undefined;
export let title: string | undefined = undefined;
export let description: string | undefined = undefined;
export let customClass: string = '';
export let disableHover: boolean = false;
// Events
on:click - Fired when card is clicked
// Slots
<slot /> - Default slot for custom content🌐 Browser Support
| Browser | Support | Notes | |---------|---------|-------| | Chrome/Edge | ✅ Full | All features work | | Firefox | ✅ Full | All features work | | Safari | ✅ Full | iOS 15+ recommended | | Opera | ✅ Full | All features work | | IE 11 | ❌ No | Not supported |
Required CSS Features:
- CSS Custom Properties (CSS Variables)
- CSS Animations
- SVG Filters
- OKLCH color space (with fallbacks)
💡 Examples
Pricing Cards
const plans = [
{ name: 'Basic', price: '$9', features: ['5 projects', 'Basic support'], color: 'cyan' },
{ name: 'Pro', price: '$29', features: ['Unlimited projects', 'Priority support'], color: 'purple' },
{ name: 'Enterprise', price: '$99', features: ['Everything', 'Dedicated support'], color: 'pink' },
];
<div className="pricing-grid">
{plans.map(plan => (
<ElectricBorder key={plan.name} preset={plan.color}>
<div className="pricing-card">
<h3>{plan.name}</h3>
<p className="price">{plan.price}/mo</p>
<ul>
{plan.features.map(feature => <li key={feature}>{feature}</li>)}
</ul>
<button>Subscribe</button>
</div>
</ElectricBorder>
))}
</div>Hero Section
<section className="hero">
<ElectricBorder preset="purple" width={600} height={400}>
<div className="hero-content">
<h1>Welcome to Our Platform</h1>
<p>Build amazing things with our tools</p>
<button>Get Started →</button>
</div>
</ElectricBorder>
</section>Dashboard Widget
<ElectricBorder preset="green" width={300} height={200}>
<div className="stat-widget">
<h4>Total Users</h4>
<p className="stat">1,250</p>
<span className="change">+12.5% ↑</span>
</div>
</ElectricBorder>🔧 Troubleshooting
Common Issues
Issue: Colors not displaying
Solution: Ensure your browser supports OKLCH color space.
For older browsers, add fallback colors in CSS.Issue: Animations not working
Solution: Check that SVG filter ID matches in both <filter> and filter: url(#...).
Each page should have unique filter IDs if multiple instances.Issue: Performance issues with many cards
Solution:
1. Limit to 5-10 cards per page
2. Use lazy loading with Intersection Observer
3. Reduce numOctaves in SVG filter (mobile)
4. Add will-change: transform to animated elementsIssue: TypeScript errors
Solution: Ensure you have @types/react installed for React/Next.js:
npm install --save-dev @types/reactIssue: Component not found
Solution: Check your import path:
✅ import { ElectricBorder } from 'electric-border-css/react';
❌ import { ElectricBorder } from 'electric-border-css';React Specific
Issue: CSS not loading
// Make sure to import CSS
import 'electric-border-css/react/ElectricBorder.css';Next.js Specific
Issue: Hydration mismatch
// The component uses 'use client' directive, so it should work.
// If issues persist, wrap in a client component:
// components/ClientCard.tsx
'use client';
import { ElectricBorder } from 'electric-border-css/nextjs';
export default function ClientCard(props) {
return <ElectricBorder {...props} />;
}Vue Specific
Issue: Component not rendering
<!-- Ensure proper import -->
<script setup lang="ts">
import ElectricBorder from 'electric-border-css/vue';
// NOT: import { ElectricBorder } from 'electric-border-css/vue';
</script>Svelte Specific
Issue: Props not reactive
<!-- Use reactive statements if needed -->
<script lang="ts">
let color = '#00fffb';
$: dynamicProps = { color };
</script>
<ElectricBorder {...dynamicProps} />❓ FAQ
Q: Can I use this in commercial projects? A: Yes! MIT License allows commercial use.
Q: Does this work with Tailwind CSS? A: Yes! The component works perfectly with Tailwind. Apply Tailwind classes to the children/slot content.
Q: Can I customize the animation?
A: Yes! Use animationSpeed, glowIntensity, and blurAmount props. For advanced customization, modify the CSS.
Q: How do I add my own colors?
A: Use the color prop with any valid color: color="#ff6600" or color="rgb(255,102,0)".
Q: Is this SSR compatible? A: Yes! Works with Next.js SSR, Nuxt (Vue), and SvelteKit.
Q: How much does this add to bundle size? A: Very minimal! CSS-only effect (~5KB gzipped). Component wrappers are tiny (~2KB each).
Q: Can I use multiple colors on one page? A: Yes! Each instance can have its own color preset or custom color.
Q: Does this affect accessibility?
A: The effect respects prefers-reduced-motion. Animations pause for users who prefer reduced motion.
Q: How do I contribute? A: See CONTRIBUTING.md for guidelines. Pull requests welcome!
Q: Where can I see live examples? A: Check examples.html for an interactive playground, or see EXAMPLES.md for code examples.
🤝 Contributing
We welcome contributions! Here's how:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
Development Setup
# Clone the repo
git clone https://github.com/hammadxcm/electric-border-css.git
cd electric-border-css
# Open examples
open examples.html
# Test components (for framework components)
cd components/react
npm install
npm test📄 License
MIT © Fyniti
See LICENSE for full details.
🙏 Acknowledgments
- Inspired by modern UI design trends
- Built with passion for the web development community
- Thanks to all contributors and users!
📞 Support & Contact
- 🐛 Report Issues
- 💬 Discussions
- 🌐 Website
- 📧 Email: [email protected]
🔗 Links
Made with ❤️ by Fyniti
If you find this project helpful, please consider:
⭐ Star this repository 🐛 Report issues 🔗 Share with others ☕ Buy me a coffee
