Animations & Transitions
Add smooth entrance effects and prevent flash of unstyled content
Animation attributes help you create polished, professional interfaces with smooth transitions when content loads or changes.
dbind_cloak
Purpose: Hide elements until DBindly finishes processing them, preventing "flash of unstyled content" (FOUC).
Syntax:
<element dbind_cloak>
<!-- Content hidden until processed -->
</element>How It Works
- CSS rule hides all
[dbind_cloak]elements by default - DBindly processes the element (binds data, applies conditions)
- DBindly removes the
dbind_cloakattribute - Element becomes visible with correct content
Setup
Add this CSS rule to your stylesheet (usually in <head>):
<style>
[dbind_cloak] {
display: none !important;
}
</style>Or for a fade-in effect:
<style>
[dbind_cloak] {
opacity: 0;
transition: opacity 0.3s ease;
}
</style>Basic Usage
<!-- Hide until data is bound -->
<div dbind_cloak>
<h1 dbind_data="title"></h1>
<p dbind_data="description"></p>
</div>
<!-- Hide conditional elements until processed -->
<span dbind_cloak dbind_show="isActive">Active</span>Use Cases
1. Prevent Template Flash
Without cloak:
User sees: {{name}} - {{email}}
Then sees: John Doe - john@example.com
With cloak:
User sees nothing, then: John Doe - john@example.com
<div class="user-profile" dbind_cloak>
<h2 dbind_data="name"></h2>
<p dbind_data="email"></p>
</div>2. Conditional Content
Prevent wrong content from flashing:
<div class="auth-status" dbind_cloak>
<div dbind_show="isLoggedIn">
Welcome, <span dbind_data="userName"></span>!
</div>
<div dbind_show="isGuest">
Please log in
</div>
</div>3. Entire Page/Section
<main dbind_cloak dbind_collection="pageData">
<header>
<h1 dbind_data="data.title"></h1>
</header>
<article dbind_html="data.content"></article>
<footer>
<span dbind_data="data.author"></span>
</footer>
</main>4. Navigation with Active States
<nav dbind_cloak>
<a href="/" dbind_class="homeActiveClass">Home</a>
<a href="/products" dbind_class="productsActiveClass">Products</a>
<a href="/about" dbind_class="aboutActiveClass">About</a>
</nav>Combining with Loading
<div class="content-section" dbind_collection="items">
<!-- Skeleton shown immediately (no cloak) -->
<div class="skeleton" dbind_loading="show">
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
</div>
<!-- Actual content cloaked until data ready -->
<div dbind_cloak dbind_loading="hide" dbind_repeat="data">
<div class="item" dbind_data="name"></div>
</div>
</div>dbind_transition
Purpose: Apply entrance animations when elements appear or when content changes.
Syntax:
<element dbind_transition="animationType"></element>
<element dbind_transition="animationType:duration"></element>
<element dbind_transition="animationType:duration:delay"></element>Transition Types
| Type | Effect | Best For |
|---|---|---|
fade | Opacity fade in | Text, overlays |
slide-up | Slide up while fading | Cards, list items |
slide-down | Slide down while fading | Dropdowns, notifications |
slide-left | Slide from right to left | Navigation, panels |
slide-right | Slide from left to right | Side panels |
scale | Scale up while fading | Modals, popups |
scale-down | Scale down while fading | Alerts |
blur | Blur to clear | Images, backgrounds |
Parameters
| Parameter | Default | Description |
|---|---|---|
| Duration | 300ms | Animation duration |
| Delay | 0ms | Delay before animation starts |
<!-- Default: fade, 300ms, no delay -->
<div dbind_transition="fade"></div>
<!-- Custom duration -->
<div dbind_transition="slide-up:500"></div>
<!-- Duration and delay -->
<div dbind_transition="scale:400:100"></div>Basic Usage
<!-- Simple fade in -->
<div dbind_transition="fade" dbind_collection="content">
<h1 dbind_data="data.title"></h1>
</div>
<!-- Slide up effect -->
<div dbind_repeat="items" dbind_transition="slide-up">
<div class="card" dbind_data="name"></div>
</div>Use Cases
1. Staggered List Animation
<div class="product-grid">
<div
dbind_repeat="products"
dbind_transition="slide-up:300:{{_index * 50}}"
class="product-card"
>
<img dbind_src="image" dbind_alt="name">
<h3 dbind_data="name"></h3>
<p dbind_data="price" dbind_format="currency:USD"></p>
</div>
</div>This creates a cascading effect where each card animates in sequence.
2. Modal Popup
<!-- Modal backdrop -->
<div
class="modal-backdrop"
dbind_show="modalOpen"
dbind_transition="fade:200"
>
</div>
<!-- Modal content -->
<div
class="modal"
dbind_show="modalOpen"
dbind_transition="scale:300:100"
role="dialog"
aria-modal="true"
>
<h2 dbind_data="modalTitle"></h2>
<div dbind_html="modalContent"></div>
<button dbind_click="closeModal">Close</button>
</div>3. Notification Toast
<div class="toast-container">
<div
class="toast"
dbind_show="showToast"
dbind_transition="slide-down:300"
dbind_class="toastClass"
role="alert"
>
<span class="toast-icon" dbind_data="toastIcon"></span>
<span dbind_data="toastMessage"></span>
<button dbind_click="dismissToast">×</button>
</div>
</div>4. Accordion Content
<div class="accordion">
<div dbind_repeat="sections" class="accordion-item">
<button
class="accordion-header"
dbind_click="toggleSection:{{_index}}"
dbind_aria-expanded="isOpen"
>
<span dbind_data="title"></span>
</button>
<div
class="accordion-content"
dbind_show="isOpen"
dbind_transition="slide-down:250"
>
<p dbind_data="content"></p>
</div>
</div>
</div>5. Tab Content Switch
<div class="tabs">
<div role="tablist" class="tab-list">
<button role="tab" dbind_click="setTab:1">Tab 1</button>
<button role="tab" dbind_click="setTab:2">Tab 2</button>
<button role="tab" dbind_click="setTab:3">Tab 3</button>
</div>
<div dbind_if="activeTab==1" dbind_transition="fade:200" class="tab-panel">
<h3>Tab 1 Content</h3>
<p>Content for the first tab.</p>
</div>
<div dbind_if="activeTab==2" dbind_transition="fade:200" class="tab-panel">
<h3>Tab 2 Content</h3>
<p>Content for the second tab.</p>
</div>
<div dbind_if="activeTab==3" dbind_transition="fade:200" class="tab-panel">
<h3>Tab 3 Content</h3>
<p>Content for the third tab.</p>
</div>
</div>6. Image Gallery Lightbox
<div
class="lightbox"
dbind_show="lightboxOpen"
dbind_transition="fade:300"
>
<div class="lightbox-backdrop" dbind_click="closeLightbox"></div>
<div class="lightbox-content" dbind_transition="scale:400:100">
<img dbind_src="currentImage" dbind_alt="currentImageAlt">
<button class="prev" dbind_click="prevImage">←</button>
<button class="next" dbind_click="nextImage">→</button>
<button class="close" dbind_click="closeLightbox">×</button>
</div>
</div>7. Dropdown Menu
<div class="dropdown">
<button
class="dropdown-trigger"
dbind_click="toggleDropdown"
dbind_aria-expanded="isOpen"
>
Select Option
</button>
<ul
class="dropdown-menu"
dbind_show="isOpen"
dbind_transition="slide-down:200"
role="listbox"
>
<li dbind_repeat="options" role="option" dbind_click="selectOption:{{value}}">
<span dbind_data="label"></span>
</li>
</ul>
</div>Custom CSS Transitions
You can create custom transitions using CSS:
<style>
.custom-bounce {
animation: bounceIn 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes bounceIn {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1.05);
}
70% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
</style>
<div dbind_show="showModal" class="custom-bounce">
Modal content
</div>Transition Classes Pattern
<style>
.card-enter {
opacity: 0;
transform: translateY(20px);
}
.card-enter-active {
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease-out;
}
</style>
<div
dbind_repeat="cards"
class="card"
dbind_transition-class="card-enter"
>
<span dbind_data="title"></span>
</div>Animation with Loading States
Combine animations with loading for polished UX:
<div class="content-section" dbind_collection="items">
<!-- Skeleton - no animation (immediate) -->
<div class="skeleton-list" dbind_loading="show">
<div class="skeleton-item"></div>
<div class="skeleton-item"></div>
<div class="skeleton-item"></div>
</div>
<!-- Content - animated entrance -->
<div class="item-list" dbind_loading="hide">
<div
dbind_repeat="data"
dbind_transition="slide-up:300:{{_index * 75}}"
class="item-card"
>
<img dbind_src="image" dbind_alt="name">
<h3 dbind_data="name"></h3>
</div>
</div>
<!-- Empty state - fade in -->
<div
class="empty-state"
dbind_empty="data"
dbind_transition="fade:400"
dbind_loading="hide"
>
<p>No items found</p>
</div>
</div>Respecting Reduced Motion
Always respect user preferences for reduced motion:
/* Base animations */
.animated {
animation: fadeIn 0.3s ease;
}
/* Disable for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
.animated,
[dbind_transition] {
animation: none !important;
transition: none !important;
}
}DBindly automatically respects the prefers-reduced-motion media query and will skip animations for users who have enabled this preference.
Complete Example: Animated Dashboard
<!DOCTYPE html>
<html>
<head>
<style>
[dbind_cloak] { display: none !important; }
.dashboard {
padding: 24px;
max-width: 1200px;
margin: 0 auto;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 32px;
}
.stat-card {
background: white;
border-radius: 12px;
padding: 24px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.activity-list {
background: white;
border-radius: 12px;
padding: 24px;
}
.activity-item {
display: flex;
gap: 16px;
padding: 16px 0;
border-bottom: 1px solid #e5e7eb;
}
.activity-item:last-child {
border-bottom: none;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
[dbind_transition] {
animation: none !important;
transition: none !important;
}
}
</style>
</head>
<body>
<div class="dashboard" dbind_cloak dbind_collection="dashboard">
<!-- Header -->
<header dbind_transition="fade:300">
<h1>Dashboard</h1>
<p>Welcome back, <span dbind_data="data.userName"></span></p>
</header>
<!-- Stats Grid -->
<section class="stats-grid">
<div class="stat-card" dbind_transition="slide-up:300:0">
<span class="stat-label">Total Users</span>
<span class="stat-value" dbind_data="data.stats.users" dbind_format="compact"></span>
<span class="stat-change positive" dbind_show="data.stats.usersGrowth > 0">
+<span dbind_data="data.stats.usersGrowth" dbind_format="percent:1"></span>
</span>
</div>
<div class="stat-card" dbind_transition="slide-up:300:75">
<span class="stat-label">Revenue</span>
<span class="stat-value" dbind_data="data.stats.revenue" dbind_format="currency:USD"></span>
<span class="stat-change positive" dbind_show="data.stats.revenueGrowth > 0">
+<span dbind_data="data.stats.revenueGrowth" dbind_format="percent:1"></span>
</span>
</div>
<div class="stat-card" dbind_transition="slide-up:300:150">
<span class="stat-label">Orders</span>
<span class="stat-value" dbind_data="data.stats.orders" dbind_format="number"></span>
</div>
<div class="stat-card" dbind_transition="slide-up:300:225">
<span class="stat-label">Conversion</span>
<span class="stat-value" dbind_data="data.stats.conversion" dbind_format="percent:1"></span>
</div>
</section>
<!-- Recent Activity -->
<section class="activity-section" dbind_transition="fade:400:300">
<h2>Recent Activity</h2>
<div class="activity-list">
<div
dbind_repeat="data.activities"
dbind_transition="slide-up:250:{{_index * 50}}"
class="activity-item"
>
<img dbind_src="user.avatar" dbind_alt="user.name" class="avatar">
<div class="activity-content">
<p>
<strong dbind_data="user.name"></strong>
<span dbind_data="action"></span>
</p>
<time dbind_data="timestamp" dbind_format="date:relative"></time>
</div>
</div>
<div class="empty-activity" dbind_empty="data.activities" dbind_transition="fade:300">
<p>No recent activity</p>
</div>
</div>
</section>
<!-- Notification Toast -->
<div
class="toast"
dbind_show="showToast"
dbind_transition="slide-down:300"
role="alert"
dbind_live="polite"
>
<span dbind_data="toastMessage"></span>
<button dbind_click="dismissToast">×</button>
</div>
</div>
<script src="https://api.dbindly.com/dbindly.min.js"></script>
<script>
DBindly.init({
apiUrl: 'https://api.dbindly.com',
apiKey: 'pk_live_your_api_key'
});
</script>
</body>
</html>Animation Performance Tips
1. Use Transform and Opacity
These properties are GPU-accelerated:
/* Good: GPU accelerated */
.animate {
transform: translateY(20px);
opacity: 0;
}
/* Avoid: Causes layout recalculation */
.animate {
margin-top: 20px;
height: 0;
}2. Limit Animated Elements
Don't animate hundreds of elements at once:
<!-- Good: Limit visible animations -->
<div dbind_repeat="items" dbind_limit="10" dbind_transition="fade:200">
<div class="item" dbind_data="name"></div>
</div>3. Use will-change Sparingly
Only use for elements that will animate:
.modal {
will-change: transform, opacity;
}4. Avoid Animation During Scroll
Use intersection observers for scroll-triggered animations.
Next Steps
- Loading - Loading states with animations
- Accessibility - Accessible animations
- Styling - Dynamic styling