Files
portfolio/.kiro/specs/page-transitions-ux/design.md
T

411 lines
11 KiB
Markdown

# Design Document: Page Transitions & UX Enhancement
## Overview
This design implements smooth page transitions, loading states, and component animations using Nuxt 4 best practices. The solution leverages Nuxt's built-in transition system, Vue's Transition component, and modern CSS animations to create a polished user experience while maintaining performance and accessibility.
## Architecture
### Transition Layers
The implementation consists of three distinct layers:
1. **Page-Level Transitions**: Global transitions applied to all route changes via `app.vue`
2. **Layout Transitions**: Smooth transitions when switching between layouts
3. **Component-Level Animations**: Micro-interactions for individual components
### Technology Stack
- **Nuxt 4 Page Transitions**: Built-in `<NuxtPage>` transition prop with enhanced performance
- **Vue 3 Transition Component**: For component-level animations
- **CSS Transforms & Opacity**: Hardware-accelerated animations
- **View Transitions API**: Native browser API for smooth page transitions (Chrome 111+)
- **NuxtLoadingIndicator**: Already implemented, will be enhanced
- **Tailwind CSS 4**: Utility classes for transition effects
## Components and Interfaces
### 1. Global Page Transitions
**Location**: `app/app.vue`
**Implementation Strategy**:
- Add `pageTransition` prop to `<NuxtPage>` component
- Define CSS transition classes in global styles
- Use fade + slight vertical movement for elegance
- Duration: 250-300ms for optimal perceived performance
**Transition Modes**:
- `out-in`: Wait for old page to leave before entering new page (prevents overlap)
- Prevents layout shift during navigation
### 2. Layout Transitions
**Location**: `app/layouts/default.vue`
**Implementation Strategy**:
- Add `layoutTransition` configuration in `nuxt.config.ts`
- Apply crossfade effect for layout changes
- Maintain scroll position where appropriate
### 3. Loading States Enhancement
**Current State**: `NuxtLoadingIndicator` already exists in `app.vue`
**Enhancements**:
- Add custom loading spinner for long operations
- Implement skeleton screens for blog post loading
- Add loading state to blog card components during navigation
### 4. Component Animations
**Target Components**:
a) **BlogCard** (`app/components/blog/BlogCard.vue`)
- Hover state: Subtle lift effect with shadow
- Entry animation: Staggered fade-in when list renders
b) **BlogNavigation** (`app/components/blog/BlogNavigation.vue`)
- Smooth hover states on prev/next buttons
- Icon animations on hover
c) **LanguageSwitcher** (`app/components/LanguageSwitcher.vue`)
- Dropdown animation with scale + fade
- Smooth active state transitions
d) **TopNav** (`app/components/common/TopNav.vue`)
- Smooth scroll-based appearance/disappearance
- Mobile menu slide-in animation
### 5. View Transitions API Integration (Native Browser API)
**Progressive Enhancement**:
- Use native View Transitions API for supported browsers (Chrome 111+, Edge 111+)
- Provides smooth, native transitions between pages
- Automatic fallback to CSS transitions for unsupported browsers
**Implementation via Nuxt 4**:
Nuxt 4 has built-in support for View Transitions API through the `experimental.viewTransition` flag:
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
viewTransition: true
}
})
```
This enables automatic View Transitions for:
- Page navigation
- Route changes
- Dynamic content updates
**Manual Control** (when needed):
```typescript
// Composable: useViewTransition
const router = useRouter()
const navigateWithTransition = async (to: string) => {
if (document.startViewTransition) {
await document.startViewTransition(async () => {
await router.push(to)
}).finished
} else {
await router.push(to)
}
}
```
## Data Models
### Transition Configuration
```typescript
// types/transitions.ts
export interface TransitionConfig {
name: string
mode: 'in-out' | 'out-in' | 'default'
duration: number
appear?: boolean
}
export interface AnimationPreferences {
reducedMotion: boolean
enableViewTransitions: boolean
}
```
### CSS Custom Properties
```css
:root {
--transition-duration-fast: 150ms;
--transition-duration-base: 250ms;
--transition-duration-slow: 350ms;
--transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
--transition-timing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
```
## Implementation Details
### 1. Page Transition Classes
**CSS Structure**:
```css
/* Enter transitions */
.page-enter-active,
.page-leave-active {
transition: all var(--transition-duration-base) var(--transition-timing);
}
.page-enter-from {
opacity: 0;
transform: translateY(10px);
}
.page-leave-to {
opacity: 0;
transform: translateY(-10px);
}
```
### 2. Reduced Motion Support
**Media Query**:
```css
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
```
### 3. Staggered List Animations
**For Blog Cards**:
```css
.blog-card {
animation: fadeInUp var(--transition-duration-base) var(--transition-timing) backwards;
}
.blog-card:nth-child(1) { animation-delay: 0ms; }
.blog-card:nth-child(2) { animation-delay: 50ms; }
.blog-card:nth-child(3) { animation-delay: 100ms; }
/* ... */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
```
### 4. Language Switch Transition
**Special Handling**:
- Preserve scroll position using `scrollBehavior` in router
- Apply crossfade to prevent jarring content swap
- Maintain route structure during language change
```typescript
// Composable enhancement
const switchLanguageWithTransition = async (newLocale: string) => {
const scrollY = window.scrollY
await switchLocalePath(newLocale)
// Restore scroll after transition
nextTick(() => {
window.scrollTo(0, scrollY)
})
}
```
## Error Handling
### Transition Failures
1. **CSS Not Loaded**: Fallback to instant transitions
2. **JavaScript Errors**: Graceful degradation to no transitions
3. **Performance Issues**: Detect slow devices and reduce animation complexity
### Browser Compatibility
- **Modern Browsers**: Full transition support with View Transition API
- **Older Browsers**: CSS-only transitions
- **No JavaScript**: Basic CSS transitions still work
## Testing Strategy
### Visual Testing
1. **Manual Testing**:
- Navigate between all major routes
- Test language switching
- Verify mobile menu animations
- Check hover states on all interactive elements
2. **Browser Testing**:
- Chrome/Edge (View Transition API support)
- Firefox (CSS transitions only)
- Safari (CSS transitions only)
- Mobile browsers (iOS Safari, Chrome Mobile)
### Performance Testing
1. **Metrics to Monitor**:
- First Contentful Paint (FCP)
- Largest Contentful Paint (LCP)
- Cumulative Layout Shift (CLS)
- Time to Interactive (TTI)
2. **Animation Performance**:
- Use Chrome DevTools Performance tab
- Ensure 60fps during transitions
- Monitor paint and composite operations
### Accessibility Testing
1. **Reduced Motion**:
- Test with `prefers-reduced-motion: reduce`
- Verify animations are disabled or minimal
2. **Keyboard Navigation**:
- Ensure focus states are visible during transitions
- Test tab order during animations
3. **Screen Readers**:
- Verify ARIA live regions announce page changes
- Test with NVDA/JAWS/VoiceOver
## Configuration Changes
### nuxt.config.ts
```typescript
export default defineNuxtConfig({
// Enable View Transitions API (Nuxt 4 feature)
experimental: {
viewTransition: true
},
app: {
pageTransition: {
name: 'page',
mode: 'out-in'
},
layoutTransition: {
name: 'layout',
mode: 'out-in'
}
},
// Existing config...
})
```
**Note**: The `experimental.viewTransition` flag in Nuxt 4 automatically:
- Adds `<meta name="view-transition" content="same-origin">` to the head
- Enables View Transitions API for navigation
- Provides fallback for unsupported browsers
### CSS Organization
**New File**: `app/assets/css/transitions.css`
- Contains all transition and animation definitions
- Imported in `app/assets/css/main.css`
## Performance Considerations
### Optimization Strategies
1. **Use CSS Transforms**: Hardware-accelerated (GPU)
2. **Avoid Layout Thrashing**: Only animate `transform` and `opacity`
3. **Will-Change Property**: Apply sparingly to animated elements
4. **Reduce Animation Complexity**: Simpler animations on mobile devices
### Bundle Size Impact
- **CSS**: ~2-3KB additional (minified + gzipped)
- **JavaScript**: ~1KB for View Transition API detection
- **Total Impact**: Minimal (<5KB)
## Migration Path
### Phase 1: Core Page Transitions
- Implement global page transitions
- Add transition CSS classes
- Test across routes
### Phase 2: Component Animations
- Add hover states to interactive elements
- Implement staggered list animations
- Enhance loading states
### Phase 3: Advanced Features
- Integrate View Transition API
- Add custom transitions for specific routes
- Optimize performance
## Design Decisions & Rationale
### Why `out-in` Mode?
- Prevents content overlap during transitions
- Cleaner visual experience
- Slightly slower but more polished
### Why 250-300ms Duration?
- Research shows this is the sweet spot for perceived performance
- Fast enough to feel responsive
- Slow enough to be noticeable and polished
### Why CSS Over JavaScript?
- Better performance (GPU acceleration)
- Simpler to maintain
- Works without JavaScript
- Respects `prefers-reduced-motion` automatically
### Why View Transition API?
- Native browser support for smooth transitions
- Better performance than CSS alone
- Progressive enhancement approach
- Future-proof solution
## Nuxt 4 Specific Features
### Built-in View Transitions Support
Nuxt 4 provides first-class support for the View Transitions API:
1. **Automatic Setup**: Just enable `experimental.viewTransition`
2. **SSR Compatible**: Works with server-side rendering
3. **Progressive Enhancement**: Automatic fallback for older browsers
4. **Zero Configuration**: No additional setup needed for basic transitions
### Performance Improvements in Nuxt 4
- **Faster Hydration**: Improved client-side hydration performance
- **Better Code Splitting**: Automatic optimization for route-based code splitting
- **Enhanced Prefetching**: Smarter link prefetching for faster navigation
## References
- [Nuxt 4 Documentation](https://nuxt.com/docs)
- [Nuxt 4 View Transitions](https://nuxt.com/docs/getting-started/transitions#view-transitions-api-experimental)
- [Vue 3 Transition Component](https://vuejs.org/guide/built-ins/transition.html)
- [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
- [Chrome View Transitions Guide](https://developer.chrome.com/docs/web-platform/view-transitions/)
- [Web Animations Performance](https://web.dev/articles/animations-guide)
- [Reduced Motion Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion)