I am using a custom React hook to detect overflow inside an HTMLDivElement using ResizeObserver. The logic works perfectly in Chrome, Edge, and Firefox on Windows, but it does not work in Safari (macOS and iOS).
import { useState, useEffect, RefObject } from 'react';
// Custom hook to detect overflow
const useDetectOverflow = (bool: boolean, htmlRef: RefObject<HTMLDivElement>) => {
const [isOverflowing, setIsOverflowing] = useState(false);
useEffect(() => {
const deployOverflowObserver = () => {
const observer = new ResizeObserver(() => {
if (htmlRef.current) {
setIsOverflowing(htmlRef.current.scrollHeight > htmlRef.current.clientHeight);
}
});
if (htmlRef.current) {
observer.observe(htmlRef.current);
}
};
const timeoutId = setTimeout(deployOverflowObserver, 250);
return () => {
clearTimeout(timeoutId);
};
}, [bool, htmlRef]);
const scrollToBottom = () => {
if (htmlRef.current) {
htmlRef.current.scrollTo({
top: htmlRef.current.scrollHeight,
behavior: 'smooth',
});
}
};
return { isOverflowing, scrollToBottom };
};
export default useDetectOverflow;
I am using a custom React hook to detect overflow inside an HTMLDivElement using ResizeObserver. The logic works perfectly in Chrome, Edge, and Firefox on Windows, but it does not work in Safari (macOS and iOS).
import { useState, useEffect, RefObject } from 'react';
// Custom hook to detect overflow
const useDetectOverflow = (bool: boolean, htmlRef: RefObject<HTMLDivElement>) => {
const [isOverflowing, setIsOverflowing] = useState(false);
useEffect(() => {
const deployOverflowObserver = () => {
const observer = new ResizeObserver(() => {
if (htmlRef.current) {
setIsOverflowing(htmlRef.current.scrollHeight > htmlRef.current.clientHeight);
}
});
if (htmlRef.current) {
observer.observe(htmlRef.current);
}
};
const timeoutId = setTimeout(deployOverflowObserver, 250);
return () => {
clearTimeout(timeoutId);
};
}, [bool, htmlRef]);
const scrollToBottom = () => {
if (htmlRef.current) {
htmlRef.current.scrollTo({
top: htmlRef.current.scrollHeight,
behavior: 'smooth',
});
}
};
return { isOverflowing, scrollToBottom };
};
export default useDetectOverflow;
Issue: ✅ Works on Windows (Chrome, Edge, Firefox).
❌ Does NOT work on Safari (macOS and iOS).
Safari console does not show any errors, but isOverflowing is always false, even when there is an obvious overflow.
Any insights what is the issue.
Share Improve this question asked Mar 31 at 18:29 RichardsonRichardson 2,3141 gold badge24 silver badges62 bronze badges1 Answer
Reset to default 0The issue is due to a short timeout duration. A shorter interval will reduce sensitivity, making it less effective.
const timeoutId = setTimeout(
deployOverflowObserver,
// Warning: A timeout shorter than 2000ms will reduce sensitivity and may cause the observer to malfunction on iOS Safari.
2000
);