In addition to parallax components and scroll events, a good way to add responsive touches is to have elements fade in as they scroll through the view.

In this tip, you’ll see how to do this in Vue3 using scrolling events and CSS transformations.

This is a screenshot of how we will learn to build in this tutorial.


Vue3 Related articles:

  • Vue 3 Tutorial (for Vue 2 users)
  • How does Vue3 Composition API replace Vue Mixins
  • Extract and reuse logic in the Vue3 Composition API
  • How do I build the same components in Vue2 and Vue3
  • A preliminary study on Vue Router in Vue3

Style our Fadin element

The first thing we need to do is build the template and set the component styles. In this example, we will use blank blocks to illustrate how things work.

So, in our template, we just want to…

  • Packing container
  • Some full-width elements
  • Some half-width elements add some variation
<template>
  <div class='container'>
    <div class='fade-in full-width' />
    <div class='fade-in full-width' />
    <div class='half-width fade-in' />
    <div class='half-width fade-in' />
  </div>
</template>
Copy the code

Then, to style them, we build a basic container and style our blocks with some padding, colors, and appropriate widths.

<style scoped>
  .container {
    width: 80%;
    min-width: 450px;
    margin: 0 auto;
  }

  .fade-in {
    background-color: #2ecc71;
    height: 500px;
    margin-bottom: 50px;
    opacity: 0;
    transition: 0.3 s all ease-out;
    transform: scale(0.8);
    box-sizing: border-box;
    padding: 20px;
    display: inline-block;
  }
  .full-width{
    width: 100%;
  }

  .half-width {
    width: 47.5%;
  }

  .half-width:nth-of-type(2n + 1) {
    margin-right: 2.5%;
  }

  .half-width:nth-of-type(2n) {
    margin-left: 2.5%;
  }
</style>
Copy the code

One thing to note is that all of our fade-in elements start with a default opacity of 0, we will use scripts to process them, and we will also change the proportions of the elements.

In fact, our fade-in element is given a transition property, which means that when we change the opacity and scale, it will transition smoothly between our two values — giving us the desired smoothness.

So, if we load our page, we shouldn’t see anything — but we should be able to scroll down our page because our elements are right there, just completely transparent.

Let’s use some Javascript to make it visible.

Fade our element in

In this tutorial, we will use the Vue3 Composition API — so, in the script, we will first create a setup method and import some lifecycle hooks.

<script>
import { onMounted, onUnmounted } from 'vue'
export default {
  setup () {

    onMounted(() => {

    })

    onUnmounted(() => {

    })
  }
}
</script>
Copy the code

We then create an array containing all the faded elements. We can use the document. The getElementsByClassName do this – but, this returns HTMLCollection, and we need an Array, so we can use the Javascript Array. The from method for casting.

onMounted((a)= > {
  fadeInElements = Array.from(document.getElementsByClassName('fade-in'))})Copy the code

Now that we have an array of all the elements to fade in, we want to do a few things:

  1. Every time views are scrolled, they iterate over them.
  2. Determines whether the element is visible.
  3. If so, fade it in and delete it from the array

First, we create scroll listeners when we install (Mounted) components and remove them when we unmount (Mounted) components. The other thing we need to do is call the handleScroll method when we install the component to load something without the user scrolling through the content.

var fadeInElements = []

onMounted((a)= > {
  fadeInElements = Array.from(document.getElementsByClassName('fade-in'))
  document.addEventListener('scroll', handleScroll)
  handleScroll()
})

onUnmounted((a)= > {
  document.removeEventListener('scroll', handleScroll)
})
Copy the code

In the scroll listener, let’s create a for loop that iterates through the array of faded elements we created.

const handleScroll = (evt) = > {
  for (var i = 0; i < fadeInElements.length; i++) {
    var elem = fadeInElements[i]
  }
}
Copy the code

At this point, we need some helper method to determine if the element is visible. To do this, we will use the elements’ bounding Rectangle to return the size and position of the elements relative to the viewport.

We will also add a small buffer, so at least 200px of elements must be visible before fading in. This will really enhance the effect as it ensures that site visitors can see what is happening. Without this buffer, our fade transition would be triggered when 1 pixel of our element appeared on the screen, and most of the elements would be outside the viewport.

const isElemVisible = (el) = > {
  var rect = el.getBoundingClientRect()
  var elemTop = rect.top + 200 // 200 = buffer
  var elemBottom = rect.bottom
  return elemTop < window.innerHeight && elemBottom >= 0
}
Copy the code

Back inside the scrollevent listener, we want to know if the isElemVisible help method is true for each element. If so, we change the opacity and scale of the element, and then remove it from the array.

for (var i = 0; i < fadeInElements.length; i++) {
  var elem = fadeInElements[i]
  if (isElemVisible(elem)) {
    elem.style.opacity = '1'
    elem.style.transform = 'scale(1)'
    fadeInElements.splice(i, 1) // Run it only once}}Copy the code

Now, if we go back to our application and check, you’ll see that the elements become visible as we scroll. That’s exactly what we want!

If you want, we’re done!

So, we have the fade scroll effect we’ve been looking for! There are many ways to extend this effect, for example.

  • Fade elements out as you scroll so that you can fade in again.
  • Use CSS animations instead of transitions to add more advanced animations.
  • Extract logic into custom instructions so that it can be reused throughout the project.

Once you’ve got the hang of scrolling listeners and CSS animations/ Transitions, you can do it flawlessly.

I hope you learned a thing or two and can think of some cool ways to incorporate some of these techniques into your own Vue projects.


Source: ItNext-io, by Matt Maribojoc, translated: Front-end Full Stack Developer