craftdeer
craftdeer

Reputation: 1025

How to slide or hide a div with transition in react?

I am trying to display a div with the click of a button with slide effect. When something is clicked, it will toggle as shown or invisible with slide effect. I have achieved this so far by doing this.

class App extends Component {
  constructor() {
   super();
   this.state = {
    myclass: '',
    }
 this.divclicked = this.divclicked.bind(this);
 }

 divclicked() {
  if (this.state.myclass === '') {
   this.setState({
    myclass: 'coolclass'
   })
  }
 else {
  this.setState({
    myclass: '',
  })
 }
}

render() {
 return (
  <div className="App">
    <div id="box" onClick={this.divclicked}>
    </div>
    <div id="seconddiv" className={this.state.myclass}>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
    </div>
  </div>
  );
 }
}

export default App;

And my CSS

#box {
 height: 50px;
 width: 50px;
 background-color: red
}

#seconddiv.coolclass{
 height:300px;
 background: purple;
}

#seconddiv {
 height: 0px;
 transition: 0.5s;
 overflow: hidden;
}

So here, when the red box with the id of "box" is clicked, I give the "seconddiv" a className and CSS takes care of hiding the div. The problem is that when I am giving the className coolclass, I do not want to use px but want to use percentage. So currently, it is going from 0px to 300px. But I want it to go from 0px to 100%; How do I achieve this. When I try to put the height of 100% in seconddiv, the slide animation doesn't work.

Upvotes: 4

Views: 30851

Answers (2)

Juanma Menendez
Juanma Menendez

Reputation: 20169

You can just combine conditional rendering ( x && y ) with some scale animation

Example

const scaleAnimationIn = keyframes`
  0% {
    transform: scale(0, 1);
    animation-timing-function: ease-out;
  }
  100% {
    transform: scale(1, 1);
  }
`


const QuestionHeaderPausedText = styled.div`
   animation: ${scaleAnimationIn} 1s;
   animation-delay: 7s;
   animation-fill-mode: both;
`

In the return/render method just:

{isSomeConditionTrue && <QuestionHeaderPausedText>
   My text
</QuestionHeaderPausedText>}

This example use Styled Components but the method (scaling) will work with any css solution.

Upvotes: 2

Chase DeAnda
Chase DeAnda

Reputation: 16441

You need to set your initial height to 0%. You also need to give .App a height of 100% so that it stretches the full height of the window. In this example, I gave it a static height of 1200px, but that should be determined by the body.

class App extends React.Component {
  constructor() {
   super();
   this.state = {
    myclass: '',
    }
 this.divclicked = this.divclicked.bind(this);
 }

 divclicked() {
  if (this.state.myclass === '') {
   this.setState({
    myclass: 'coolclass'
   })
  }
 else {
  this.setState({
    myclass: '',
  })
 }
}

render() {
 return (
  <div className="App">
    <div id="box" onClick={this.divclicked}>
    </div>
    <div id="seconddiv" className={this.state.myclass}>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
     <p>help help</p>
    </div>
  </div>
  );
 }
}

ReactDOM.render(<App/>,document.getElementById('root'));
#box {
 height: 50px;
 width: 50px;
 background-color: red
}

#seconddiv.coolclass{
 max-height:100%;
 background: purple;
}

#seconddiv {
 max-height: 0%;
 transition: 0.5s;
 overflow: hidden;
}
.App {
  height: 100%;
}
#root {
  height: 1200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Upvotes: 4

Related Questions