React: Hiding an Element as you Scroll
Tags: react, javascript, css, tutorial
Published: 2020-09-18 02:49:09

Recently I was looking for a way to hide (or possibly show) an element as you scroll down the page in my React app (portfolio site). YES, there are some React components that you can add on that may do the trick depending on the task (see [React-Headroom](https://github.com/KyleAMathews/react-headroom)), but this guide is meant to give you the run-down on how to enable this feature in a React component for yourself. After taking a quick look at the example below (the social media icons appear and disappear), lets get down to business.
###### Example from [kyleluke.dev](https://www.kyleluke.dev)
![](https://media.giphy.com/media/YuT6S5ucGtT3ETMDgX/source.gif)

## Setting State
```
state = {
    opacity: '1'
}
```
First, the state will need to be set to the base value you are wanting your feature to have. State for this feature will be the css values that you will want to change. Are you wanting it to appear, or disappear (where would you like the state to start)? Are you wanting it to slide in and out (top, right, bottom, or left positions), or fade in and out (opacity)?

From here, we will be able to adjust the state based on the transition we would like to see, and the timing of that transition while scrolling the page.

## Timing the Transition
```
componentDidMount() {
    if (typeof window !== "undefined") {
      window.onscroll = () => {
        let currentScrollPos = window.pageYOffset;
        let maxScroll = document.body.scrollHeight - window.innerHeight;
        // console.log(maxScroll)
        if (currentScrollPos > 0 && currentScrollPos < maxScroll) {
          this.setState({ opacity: "0" })
          // console.log(currentScrollPos)
        } else {
          this.setState({ opacity: "1" })
        }
      }
    }
  }
```

As the component mounts, we will start watching the window for an onscroll event. You will first create a currentScrollPos variable, and then work with your desired scroll location for the state to change.

This example is set to watch for a scroll position of 0 (top of the page), and the scroll position when the user scrolls to bottom of the page, or its maxScroll position (total scroll height - window height = user has scrolled as far down as they can).

This part can be the most tricky, as you want to do the math as to where your desired scroll location will be for the transition to happen. Think about the window height along with the body height, as you will not be able to scroll the entire body height. You will find example console.log() variables that you may want to watch while troubleshooting your own component.

## Updating State for Transition
```
if (currentScrollPos > 0 && currentScrollPos < maxScroll) {
        this.setState({ opacity: "0" })
    } 
else {
        this.setState({ opacity: "1" })
    }
```
Performing the transition is as easy as updating state. You might be setting the opacity to change, you might be moving the position from -5rem to 0 (or vice versa). This is where you can tinker with a variety of CSS properties and values to perform the transition you are going for.

## Declaring the Element
```
render() {
    return (
        <div className="your-class" style={{ opacity: `${this.state.opacity}`}} >
        {/* additonal content */}
        </div>
    )
}
```
Here we declare the element in the return value within the component you are working with. Here you would adjust the style you are transitioning, in this case we are working with opacity. You are able to transition multiple styles with this technique.

## Additional CSS that may be helpful
```
.your-class {
    z-index:200;
    position: fixed;
    bottom:0;  // this can be used to transition a sliding effect. Try -5rem in initial state
    transition: opacity .1s ease;  // this allows for a smooth transition effect
}
```
The styling here is highly specialized for your select case, but I wanted to include some ideas you might think about as supplements to your transition. Particularly the CSS property: transition. It has many features that can make your transition perform in a much nicer looking way.

## Full Component

```
import React, { Component } from 'react';

class Index extends Component {
  state = {
    opacity: '1'
  }
  
  componentDidMount() {
    if (typeof window !== "undefined") {
      window.onscroll = () => {
        let currentScrollPos = window.pageYOffset;
        let maxScroll = document.body.scrollHeight - window.innerHeight;
        // console.log(maxScroll)
        if (currentScrollPos > 0 && currentScrollPos < maxScroll) {
          this.setState({ opacity: "0" })
          // console.log(currentScrollPos)
        } else {
          this.setState({ opacity: "1" })
        }
      }
    }
  }

  render() {
    return (
        <div className="your-class" style={{ opacity: `${this.state.opacity}`}} >
         {/* additonal content */} Hello World
        </div>
    )
  }
}

export default Index
```
Here is the complete component with all of the steps put together. Hopefully this helps visualize what steps are required to hide/show an element in a particular zoom location in your app!

Please leave comments if you found this useful, and any improvements you have made in your own app!