Files
portfolio/.kiro/specs/page-transitions-ux/design.md
2025-11-10 18:09:18 +03:30

11 KiB

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:

// 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):

// 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

// 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

: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:

/* 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:

@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:

.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
// 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

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