How to detect overflow in div element?
You can easily do that by comparing scrollHeight with clientHeight, try the following:
<script type="text/javascript">
function GetContainerSize ()
{
var container = document.getElementById ("tempDiv");
var message = "The width of the contents with padding: " + container.scrollWidth + "px.\n";
message += "The height of the contents with padding: " + container.scrollHeight + "px.\n";
alert (message);
}
</script>
For more information please take a look at: http://help.dottoro.com/ljbixkkn.php
Check if an element's content is overflowing?
If you want to show only an identifier for more content, then you can do this with pure CSS. I use pure scrolling shadows for this. The trick is the use of background-attachment: local;
. Your css looks like this:
.scrollbox { overflow: auto; width: 200px; max-height: 200px; margin: 50px auto;
background: /* Shadow covers */ linear-gradient(white 30%, rgba(255,255,255,0)), linear-gradient(rgba(255,255,255,0), white 70%) 0 100%, /* Shadows */ radial-gradient(50% 0, farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)), radial-gradient(50% 100%,farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; background: /* Shadow covers */ linear-gradient(white 30%, rgba(255,255,255,0)), linear-gradient(rgba(255,255,255,0), white 70%) 0 100%, /* Shadows */ radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)), radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; background-repeat: no-repeat; background-color: white; background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px; /* Opera doesn't support this in the shorthand */ background-attachment: local, local, scroll, scroll;}
<div class="scrollbox"> <ul> <li>Not enough content to scroll</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul></div>
<div class="scrollbox"> <ul> <li>Ah! Scroll below!</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>The end!</li> <li>No shadow there.</li> </ul></div>
Determine if an HTML element's content overflows
Normally, you can compare the client[Height|Width]
with scroll[Height|Width]
in order to detect this... but the values will be the same when overflow is visible. So, a detection routine must account for this:
// Determines if the passed element is overflowing its bounds,
// either vertically or horizontally.
// Will temporarily modify the "overflow" style to detect this
// if necessary.
function checkOverflow(el)
{
var curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
}
Tested in FF3, FF40.0.2, IE6, Chrome 0.2.149.30.
How to detect overflow in a nested div (React)?
It's not possible to know if arbitrary children are fully rendered without each one offering specialized callbacks. As such, it might be better to watch elements for size changes.
We can use ResizeObserver
to our advantage here.
If we create a nested pair of div:
<div class="fixed_size_overflow_auto">
<div>
{children}
</div>
</div>
making the outer div have fixed dimensions, we can listen for resize on the inner div. When we detect those resizes, we can calculate if the outer div has overflowed by comparing its offsetHeight
to its scrollHeight
.
Here is the idea, wrapped up in a component that can be styled using styled-components
:
const DetectContentResizeElement: FC<{
className?: string;
onContentResized?: (v: { hasOverflow: boolean }) => void;
}> = ({ children, onContentResized, className }) => {
const contentRef = useRef<HTMLDivElement>(null);
const outerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!contentRef.current || !outerRef.current) {
return;
}
const obs = new ResizeObserver(() => {
const hasOverflow =
(outerRef.current?.offsetHeight ?? 0) <
(contentRef.current?.offsetHeight ?? 0);
onContentResized?.({ hasOverflow });
});
obs.observe(contentRef.current);
return () => obs.disconnect();
}, [onContentResized]);
return (
<div className={className} ref={outerRef}>
<div ref={contentRef}>{children}</div>
</div>
);
};
You can fix the size of this component by "subclassing" it with styled-components:
const FixedHeight = styled(DetectContentResizeElement)`
height: 200px;
width: 200px;
border: solid 1px black;
overflow: auto;
`;
so now you can use this container and get events that tell you when it overflowed:
<FixedHeight
onContentResized={({ hasOverflow }) =>
console.log(`resized. hasOverflow: ${hasOverflow}`)
}
>
<SomeChildElement />
</FixedHeight>
See it in action in this codesandbox project (uses resize-observer-polyfill ponyfill for best compatibility)
How to check if a div is overflowing in react functional component
As Jamie Dixon suggested in the comment, I used useLayoutEffect
hook to set showLink
true. Here is the code
Component
import React from "react";
import "./styles.css";
export default function App(props) {
const ref = React.createRef();
const [showMore, setShowMore] = React.useState(false);
const [showLink, setShowLink] = React.useState(false);
React.useLayoutEffect(() => {
if (ref.current.clientWidth < ref.current.scrollWidth) {
setShowLink(true);
}
}, [ref]);
const onClickMore = () => {
setShowMore(!showMore);
};
return (
<div>
<div ref={ref} className={showMore ? "" : "container"}>
{props.text}
</div>
{showLink && (
<span className="link more" onClick={onClickMore}>
{showMore ? "show less" : "show more"}
</span>
)}
</div>
);
}
CSS
.container {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 200px;
}
.link {
text-decoration: underline;
cursor: pointer;
color: #0d6aa8;
}
Check with jquery if div has overflowing elements
You actually don't need any jQuery to check if there is an overflow happening or not. Using element.offsetHeight
, element.offsetWidth
, element.scrollHeight
and element.scrollWidth
you can determine if your element have content bigger than it's size:
if (element.offsetHeight < element.scrollHeight ||
element.offsetWidth < element.scrollWidth) {
// your element have overflow
} else {
// your element doesn't have overflow
}
See example in action: Fiddle
But if you want to know what element inside your element is visible or not then you need to do more calculation. There is three states for a child element in terms of visibility:
If you want to count semi-visible items it would be the script you need:
var invisibleItems = [];
for(var i=0; i<element.childElementCount; i++){
if (element.children[i].offsetTop + element.children[i].offsetHeight >
element.offsetTop + element.offsetHeight ||
element.children[i].offsetLeft + element.children[i].offsetWidth >
element.offsetLeft + element.offsetWidth ){
invisibleItems.push(element.children[i]);
}
}
And if you don't want to count semi-visible you can calculate with a little difference.
How to detect overflow HTML elements
Compare scrollWidth/scrollHeight with clientWidth/clientHeight of the element.
if (e.scrollWidth > e.clientWidth){/*overflow*/}
https://jsfiddle.net/pdrk50a6/
Edit: I do not know your root element, yet in the end it is going to be something like this.
document.body.onresize = function(){
var tR = [];
var tL = document.querySelectorAll('div');
for(var i=0, j=tL.length; i<j; i++)
if (tL[i].scrollWidth > tL[i].clientWidth) tR.push(tL[i])
//Do whatever you need with the tR elements (overflown)
}
How to detect whether an element that have parent `overflow: hidden;`, is hidden?
EDIT: my compulsion forced me into changing this code without jQuery and correcting a bug
Here's a jsFiddle for a quick test, I repeat the code below:
HTML:
<div id="someContainer" style="overflow:hidden; position:relative; height:26px; background-color: #ffffff;">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
<pre id="output"></pre>
JS (no jQuery):
var i, top, container, output, height;
container = document.getElementById("someContainer");
output = document.getElementById("output");
height = container.offsetHeight;
output.innerText += "Height: " + height + "px\n";
for (i = 0; i < container.children.length; i++)
{
top = container.children[i].offsetTop;
output.innerText += "Top " + i + ": " + top + "px => visible=" + (top < height) + "\n";
}
The output will be:
Height: 26px
Top 0: 0px => visible=true
Top 1: 18px => visible=true
Top 2: 36px => visible=false
The first two items are visible (at least in part, I cut the B
in half on purpose), while the last item is not visible. It falls beyond the lower edge of the container.
NOTE: I had to add
position: relative;
to the container so that it becomes a positioning reference for child elements. Otherwise,offsetTop
would compute incorrectly under specific circumstances (depending on outer HTML).
Related Topics
Change Value of Input and Submit Form in JavaScript
Calculate Color Values from Green to Red
Converting Em to Px in JavaScript (And Getting Default Font Size)
How to Apply CSS to Only Numbers in a Text Inside/Or Any <P><P> Element
How to Detect in iOS Webapp When Switching Back to Safari from Background
Vue 2 - Mutating Props Vue-Warn
How to Use JavaScript Source Maps (.Map Files)
Es6: Call Class Constructor Without New Keyword
Event When User Stops Scrolling
Correct Way to Convert Size in Bytes to Kb, Mb, Gb in JavaScript
Jquery/JavaScript Opacity Animation with Scroll
Jquery .Animate() Stop Scrolling When User Scrolls Manually
Jqgrid Viewgridrow Dialog Big Span and Icon
Is There an Alternative Method to Use Onbeforeunload in Mobile Safari
How to Detect Browser's Protocol Handlers