Trying to implement a simple show more button with react using useState hook. Everything is working fine except that when the content is toggled on the vertical scroll position jumps down the size of the div that was shown. In other words, the content that is shown is positioned above the "Show More" button instead of extending the text and keeping the scroll position at the beginning of the text. I have searched everything and everywhere but was unable to find an elegant solution without remembering and restoring scroll positions. Here is a sample code that shows my problem.
import {useState} from "react"
export default function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = useState(false)
return (
<>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</>
)
}
Runnable code snippet:
function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = React.useState(false)
return (
<div>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</div>
)
}
ReactDOM.render(<Test/>, document.getElementById("test"));
<body>
<div id="test"></div>
<!-- React.js CDN links -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- Babel (essential for JSX syntax - https://babeljs.io/docs/en/#jsx-and-react) -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</body>
I have solved it! In Chrome CSS property overflow-anchor is auto by default which in turn makes the clicked button a scroll anchor. So when the new content is loaded the window scrolls with the anchor.
In order to fix this behavior you can set overflow-anchor: none; globally or to the button itself.
function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = React.useState(false)
return (
<div>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</div>
)
}
ReactDOM.render(<Test/>, document.getElementById("test"));
body {
overflow-anchor: none;
}
<body>
<div id="test"></div>
<!-- React.js CDN links -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- Babel (essential for JSX syntax - https://babeljs.io/docs/en/#jsx-and-react) -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</body>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With