Can I detect element visibility using only CSS?
No, it is not possible and can't be possible, at least in stylesheets.
Otherwise, you could create an infinite loop:
element:visible {
display: none;
}
The element would be visible at first, then the selector would select it and hide it, then the selector wouldn't apply and it would become visible again, etc.
It would be possible to allow that pseudo-class only in JS APIs like querySelector
. But as far as I know there isn't anything like that, and it wouldn't be CSS-only.
Check if element is visible in DOM
According to this MDN documentation, an element's offsetParent
property will return null
whenever it, or any of its parents, is hidden via the display style property. Just make sure that the element isn't fixed. A script to check this, if you have no position: fixed;
elements on your page, might look like:
// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
return (el.offsetParent === null)
}
On the other hand, if you do have position fixed elements that might get caught in this search, you will sadly (and slowly) have to use window.getComputedStyle()
. The function in that case might be:
// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
var style = window.getComputedStyle(el);
return (style.display === 'none')
}
Option #2 is probably a little more straightforward since it accounts for more edge cases, but I bet its a good deal slower, too, so if you have to repeat this operation many times, best to probably avoid it.
Check if an element is visible on screen
Here is a script returning a promise using the new IntersectionObserver
API for checking whether or not an element is actually visible in the viewport:
function isVisible(domElement) {
return new Promise(resolve => {
const o = new IntersectionObserver(([entry]) => {
resolve(entry.intersectionRatio === 1);
o.disconnect();
});
o.observe(domElement);
});
}
Which you can use in your code:
const visible = await isVisible(document.querySelector('#myElement'));
console.log(visible);
How can I check that an element is visible with Puppeteer and pure JavaScript?
I found that Puppeteer has an API method for this purpose: Page.waitForSelector, via its visible
option. I wasn't aware of the latter option, but it lets you wait until an element is visible.
await page.waitForSelector('#element', {
visible: true,
})
Conversely you can wait for an element to be hidden, via the hidden
option.
I think this is the idiomatic answer, with regards to the Puppeteer API. Thanks to Colin Cline though as I think his answer is probably useful as a general JavaScript solution.
How detect visibility of element that previously was invisible in the browser?
For everyone who face same problem, I solved it by using IntersectionObserver API. Example:
const onIntersectionChange = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
//Element become visible. Do your logic here and remove monitoring
observer.unobserve(entry.target);
}
});
};
const intersectionObserver = new IntersectionObserver(onIntersectionChange, {
threshold: 0.5
});
watchingElements.forEach(element => {
intersectionObserver.observe(element);
});
Get only visible element using pure javascript
Here's something you can use, pure Javascript:
// Get all elements on the page (change this to another DOM element if you want)
var all = document.getElementsByTagName("*");
for (var i = 0, max = all.length; i < max; i++) {
if (isHidden(all[i]))
// hidden
else
// visible
}
function isHidden(el) {
var style = window.getComputedStyle(el);
return ((style.display === 'none') || (style.visibility === 'hidden'))
}
How do I check if an element is really visible with JavaScript?
For the point 2.
I see that no one has suggested to use document.elementFromPoint(x,y)
, to me it is the fastest way to test if an element is nested or hidden by another. You can pass the offsets of the targetted element to the function.
Here's PPK test page on elementFromPoint.
From MDN's documentation:
The
elementFromPoint()
method—available on both the Document and ShadowRoot objects—returns the topmost Element at the specified coordinates (relative to the viewport).
How do I check if an element is hidden in jQuery?
Since the question refers to a single element, this code might be more suitable:
// Checks CSS content for display:[none|block], ignores visibility:[true|false]
$(element).is(":visible");
// The same works with hidden
$(element).is(":hidden");
It is the same as twernt's suggestion, but applied to a single element; and it matches the algorithm recommended in the jQuery FAQ.
We use jQuery's is() to check the selected element with another element, selector or any jQuery object. This method traverses along the DOM elements to find a match, which satisfies the passed parameter. It will return true if there is a match, otherwise return false.
Targeting first visible element with pure CSS
In pure CSS, no it's not possible. Chris Coyier has :first listed as purely a jQuery construct: http://css-tricks.com/pseudo-class-selectors/.
Related Topics
What Is the Current State of Sub-Pixel Accuracy in the Major Browsers
Firefox Line-Height Issue with Input Fields
What Are Cross-Browser, Cross Platfom Web Safe Fonts
CSS Transform to Skew the Shape to a Trapezium
How to Make Nginx Serve Static Content Like .Js, .Css, .Html
Facebook Like Widget on Fan Page, Comment Area Out of Visible Area
Css: Rotate Image and Align Top Left
Customize a Select with Font-Awesome
Rgba Background with Ie Filter Alternative: IE9 Renders Both!
Smart Way to Add Corner Image to Div Border on All Four Corners
Converting Between Physical Pixels and CSS Pixels
How Do CSS Sprites Speed Up a Web Site
Css3 White to Transparent Gradient
CSS Background Image Disappearing in Chrome
Use Fontawesome Icon in Svg Without External Files
Make Second Div Appear Above First, Without Absolute Position or Changing HTML