Check if an element's content is overflowing?
Solution 1
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>
The code and the example you can find on http://dabblet.com/gist/2462915
And an explanation you can find here: http://lea.verou.me/2012/04/background-attachment-local/.
Solution 2
The element may be overflown vertically, horizontally or both. This function will return you a boolean value if the DOM element is overflown:
function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
var els = document.getElementsByClassName('demos');
for (var i = 0; i < els.length; i++) {
var el = els[i];
el.style.borderColor = (isOverflown(el) ? 'red' : 'green');
console.log("Element #" + i + " is " + (isOverflown(el) ? '' : 'not ') + "overflown.");
}
.demos {
white-space: nowrap;
overflow: hidden;
width: 120px;
border: 3px solid black;
}
<div class='demos'>This is some text inside the div which we are testing</div>
<div class='demos'>This is text.</div>
ES6 example:
const isOverflown = ({ clientWidth, clientHeight, scrollWidth, scrollHeight }) => {
return scrollHeight > clientHeight || scrollWidth > clientWidth;
}
Solution 3
Comparing element.scrollHeight
to element.clientHeight
should do the task.
Below are the images from MDN explaining Element.scrollHeight and Element.clientHeight.
Solution 4
I made a multipart codepen demonstrating the above answers ( e.g. using overflow hidden and height) but also how you would expand / collapse overflowed items
Example 1: https://codepen.io/Kagerjay/pen/rraKLB ( Real simple example, no javascript, just to clip overflowed items)
Example 2: https://codepen.io/Kagerjay/pen/LBErJL (Single event handler show more / showless on overflowed items)
Example 3: https://codepen.io/Kagerjay/pen/MBYBoJ (Multi event handler on many show more/ show less on overflowed items)
I have attached example 3 below as well, I use Jade/Pug so it might be a tad verbose. I suggest checking out the codepens I've made its simpler to grasp.
// Overflow boolean checker
function isOverflown(element){
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
// Jquery Toggle Text Plugin
$.fn.toggleText = function(t1, t2){
if (this.text() == t1) this.text(t2);
else this.text(t1);
return this;
};
// Toggle Overflow
function toggleOverflow(e){
e.target.parentElement.classList.toggle("grid-parent--showall");
$(e.target).toggleText("Show More", "Show LESS");
}
// Where stuff happens
var parents = document.querySelectorAll(".grid-parent");
parents.forEach(parent => {
if(isOverflown(parent)){
parent.lastElementChild.classList.add("btn-show");
parent.lastElementChild.addEventListener('click', toggleOverflow);
}
})
body {
background-color: #EEF0ED;
margin-bottom: 300px;
}
.grid-parent {
margin: 20px;
width: 250px;
background-color: lightgrey;
display: flex;
flex-wrap: wrap;
overflow: hidden;
max-height: 100px;
position: relative;
}
.grid-parent--showall {
max-height: none;
}
.grid-item {
background-color: blue;
width: 50px;
height: 50px;
box-sizing: border-box;
border: 1px solid red;
}
.grid-item:nth-of-type(even) {
background-color: lightblue;
}
.btn-expand {
display: none;
z-index: 3;
position: absolute;
right: 0px;
bottom: 0px;
padding: 3px;
background-color: red;
color: white;
}
.btn-show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<p>Any grid-parent over 10 child items has a "SHOW MORE" button to expand</p>
<p>Click "SHOW MORE" to see the results</p>
</section>
<radio></radio>
<div class="wrapper">
<h3>5 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>8 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>10 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>13 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>16 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>19 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
</div>
Solution 5
Would something like this: http://jsfiddle.net/Skooljester/jWRRA/1/ work? It just checks the height of the content and compares it to the height of the container. If it's greater than you can put in the code to append a "Show more" button.
Update: Added the code to create a "Show More" button at the top of the container.
Related videos on Youtube
Harry
Updated on July 20, 2022Comments
-
Harry almost 2 years
What's the easiest way to detect if an element has been overflowed?
My use case is, I want to limit a certain content box to have a height of 300px. If the inner content is taller than that, I cut it off with an overflow. But if it is overflowed I want to show a 'more' button, but if not I don't want to show that button.
Is there an easy way to detect overflow, or is there a better method?
-
Robin Wieruch over 2 yearsIf someone is looking for a custom React Hook to perform this task in React land: robinwieruch.de/react-custom-hook-check-if-overflow
-
-
Bergi over 12 yearsYeah, but according to quirksmode it works for the most - and is much simpler than the other posted solutions.
-
Marat Tanalin over 12 years@Harry: It's supported in all current browsers (desktop ones at least), so it doesn't matter that it's formally nonstandard.
-
Sygmoral almost 11 yearsGreat solution! Here's a jQuery variant (to be used with
$("#element").overflown()
):$.fn.overflown=function(){var e=this[0];return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth;}
-
koppor almost 11 yearsHere, these properties always have the same values.
-
carefulnow1 about 7 yearsHow is this different from micnic's answer?
-
Yasir about 7 years@micnic hi , I am using ionic2 and trying to do the same thing... but the function returns true always... is there a different way to do things in angular 2
-
micnic about 7 years@DavidBracoly, this function is for pure DOM API, I do not have experience with Ionic/Angular, I guess you should get the original DOM Element and use this function
-
DreamTeK about 6 yearsNice idea but in your example the background (shadow) would be behind the text!
-
Jared about 6 yearsGreat trick, however in Chrome it shows only static shadow on the bottom, it never disappears and the upper shadow never shows
-
Reza over 5 yearsOnly for Firefox:
element.addEventListener ("overflow", () => log( "overflow" ), false);
Reference: overflow event -
Sebastian Simon about 3 yearsWow, this even works e.g. in a
grid
, where the bounding client rect doesn’t include overflowing content. -
borisdiakur almost 3 years/* Opera doesn't support this in the shorthand */ -> I'm on Opera and it seems to work for me.
-
J_sdev almost 3 yearsThis is the only solution on this entire thread that worked. Thanks for posting.
-
Flow Overstack about 2 yearsNote for all the trigger-happy down-voters: The question was: "What is the easiest way to detect if an element's been overflowed?". It didn't say something like "programmatically", or "using JavaScript only" etc. This answers it!