Skip to main content

Overview

Natours uses CSS keyframe animations to create smooth, engaging entrance effects. All animations are defined in sass/base/_animations.scss and utilize GPU-accelerated transforms for optimal performance.
All animations use transform and opacity properties exclusively to ensure hardware acceleration and smooth 60fps performance.

Keyframe Animations

The project includes three primary keyframe animations for element entrance effects:

moveInLeft

Animates elements entering from the left side of the screen with a subtle bounce effect.
sass/base/_animations.scss
@keyframes moveInLeft {
  0% {
    opacity: 0;
    transform: translateX(-100px);
  }

  80% {
    transform: translateX(10px);
  }

  100% {
    opacity: 1;
    transform: translateX(0);
  }
}
1

Start State (0%)

Element is invisible (opacity: 0) and positioned 100px to the left
2

Bounce Point (80%)

Element overshoots slightly by 10px to the right, creating a natural bounce effect
3

End State (100%)

Element reaches final position with full opacity
Usage Example:
sass/base/_typography.scss
.heading-primary--main {
  display: block;
  font-size: 6rem;
  font-weight: 400;
  letter-spacing: 3.5rem;
  animation: moveInLeft 1s ease;
}

moveInRight

Mirror animation to moveInLeft, animating elements from the right side.
sass/base/_animations.scss
@keyframes moveInRight {
  0% {
    opacity: 0;
    transform: translateX(100px);
  }

  80% {
    transform: translateX(-10px);
  }

  100% {
    opacity: 1;
    transform: translateX(0);
  }
}
This animation follows the same bounce pattern as moveInLeft but in the opposite direction, creating visual balance when used with paired elements. Usage Example:
sass/base/_typography.scss
.heading-primary--sub {
  display: block;
  font-size: 2rem;
  font-weight: 400;
  letter-spacing: 1.75rem;
  animation: moveInRight 1s ease;
}

moveInBottom

Animates elements entering from below, perfect for call-to-action buttons and secondary elements.
sass/base/_animations.scss
@keyframes moveInBottom {
  0% {
    opacity: 0;
    transform: translateY(32px);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
moveInBottom uses a simpler animation without the bounce effect, making it ideal for buttons and UI elements where subtlety is preferred.
Usage Example:
sass/components/_button.scss
.btn--animated {
  animation: moveInBottom .5s ease .75s;
  animation-fill-mode: backwards;
}

Animation Properties

Duration and Timing

Short Animations

Use 0.5s for buttons and small UI elements
animation: moveInBottom .5s ease;

Long Animations

Use 1s for large headings and hero elements
animation: moveInLeft 1s ease;

Animation Delay

Create staggered entrance effects by adding delays:
animation: moveInBottom .5s ease .75s;
This delays the button animation by 0.75s, allowing header text to animate in first.

Animation Fill Mode

animation-fill-mode: backwards;
animation-fill-mode: backwards ensures that elements start with the styles defined at 0% of the keyframe, even during the delay period. This prevents a flash of unstyled content before the animation begins.

Real-World Examples

Hero Header Animation

The header combines multiple animations to create a coordinated entrance:
<h1 class="heading-primary">
  <span class="heading-primary--main">Outdoors</span>
  <span class="heading-primary--sub">is where life happens</span>
</h1>
<a href="#section-tours" class="btn btn--white btn--animated">Discover our tours</a>
Animation Timeline:
1

0s - Main Heading

“Outdoors” animates in from the left (1s duration)
2

0s - Subheading

“is where life happens” animates in from the right (1s duration)
3

0.75s - Button

Button begins animating from bottom after 0.75s delay (0.5s duration)
4

1.25s - Complete

All animations complete, hero is fully visible

Performance Considerations

Always use backface-visibility: hidden on animated elements to prevent flickering during animations:
.heading-primary {
  backface-visibility: hidden;
}

GPU Acceleration

All Natours animations use transform properties which are GPU-accelerated:
  • transform: translateX()
  • transform: translateY()
  • opacity
  • left, right, top, bottom
  • width, height
Stick to transform and opacity for animations to ensure smooth 60fps performance across all devices.

Animation Timing Functions

All animations use the ease timing function for natural, organic motion:
animation: moveInLeft 1s ease;
The ease function provides:
  • Slow start
  • Fast middle
  • Slow end
This creates more natural-feeling animations compared to linear timing.

Customizing Animations

To create custom variations:
// Faster entrance from left
.custom-element {
  animation: moveInLeft 0.6s ease-out;
}

// Delayed entrance from bottom
.delayed-element {
  animation: moveInBottom 0.8s ease 1.5s;
  animation-fill-mode: backwards;
}

// Subtle entrance from right
.subtle-element {
  animation: moveInRight 1.2s ease-in-out;
}

Browser Compatibility

All animations are compatible with modern browsers. No vendor prefixes are required for:
  • Chrome 43+
  • Firefox 16+
  • Safari 9+
  • Edge (all versions)
For older browser support, consider using Autoprefixer as part of your build process to automatically add vendor prefixes.

Build docs developers (and LLMs) love