0

I have a div which has a lot of text in it and I want it to kind of open downward when clicked and show the text. I also want to scroll down to the bottom of the element when the div is clicked. I've tried scrollIntoView but for some reason it doesn't scroll all the way down to the element's bottom. On full screen it works but if I decrease the screen size it scrolls less then it should. It seems like it can only scroll the amount under the div BEFORE the open-down. Any suggestion would be appreciated.

import style from "./education.module.css"
import { useState } from "react"
import { useRef } from "react"
import { useEffect } from "react"

const Education = () => {
  const [opened, setOpened] = useState(false)
  const scrollTo = useRef(null)

  useEffect(() => {
    if (opened) {
      const { bottom } = scrollTo.current.getBoundingClientRect()
      if (
        !(
          bottom <=
          (window.innerHeight || document.documentElement.clientHeight)
        )
      )
        scrollTo.current.scrollIntoView({ behavior: "smooth", block: "start" })
    }
  }, [opened])

  return (
    <div
      className={`${style.container} ${opened ? style.heightened : ""}`}
      onClick={() => {
        setOpened(!opened)
      }}
    >
      <p>Végzettségem</p>
      <p ref={scrollTo}>
        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      </p>
    </div>
  )
}

export default Education
.container {
  width: 50vw;
  min-width: 700px;
  background-color: rgb(240, 239, 239);
  border-radius: 10px;
  cursor: pointer;
  height: min-content;
  max-height: 1em;
  padding: 12px;
  font-size: 30px;
  text-align: center;
  margin: auto;
  margin-top: 10vh;
  box-shadow: 2px 2px 2px 1px rgb(187, 187, 187);
  transition: max-height 0s;
  overflow: hidden;
}

.container p:last-child {
  padding: 12px;
  padding-top: 80px;
  margin-top: -50px;
  font-size: 20px;
  text-align: justify;
}

.heightened {
  max-height: 900px;
  transition: max-height 0.3s linear;
}

1 Answer 1

1

You have to listen when the .container's transition has ended before you execute scrollIntoView. You can do this using the transitionend event.

I also don't think you need useEffect hook to accomplish this.

const Education = () => {
  const [opened, setOpened] = useState(false);
  const scrollTo = useRef(null);
  const container = useRef(null);

  useEffect(() => {
    const { current: containerElement } = container;
    containerElement.addEventListener("transitionend", scrollIntoView);

    return () => {
      containerElement.removeEventListener(scrollIntoView);
    };
  }, []);

  function scrollIntoView() {
    console.log("transition end, will scroll to bottom");

    scrollTo.current.scrollIntoView({
      behavior: "smooth",
      block: "end" // important, should use `end` instead `start`
    });
  }
  ...

Edit flamboyant-frog-ixyo4

Sign up to request clarification or add additional context in comments.

2 Comments

so it means that I cannot do simultaneously the animation and the scroll?
I'm not sure if there's a way to doing that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.