jQuery `.is(":visible")` not working in Chrome
It seems jQuery's :visible
selector does not work for some inline elements in Chrome. The solution is to add a display style, like "block"
or "inline-block"
to make it work.
Also note that jQuery has a somewhat different definition of what is visible than many developers:
Elements are considered visible if they consume space in the document.
Visible elements have a width or height that is greater than zero.
In other words, an element must have a non-zero width and height to consume space and be visible.
Elements with
visibility: hidden
oropacity: 0
are considered visible, since they still consume space in the layout.
On the other hand, even if its visibility
is set to hidden
or the opacity is zero, it's still :visible
to jQuery as it consumes space, which can be confusing when the CSS explicitly says its visibility is hidden.
Elements that are not in a document are considered hidden; jQuery does not have a way to know if they will be visible when appended to a document since it depends on the applicable styles.
All option elements are considered hidden, regardless of their selected state.
During animations that hide an element, the element is considered visible until the end of the animation. During animations to show an element, the element is considered visible at the start at the animation.
The easy way to look at it, is that if you can see the element on the screen, even if you can't see its content, it's transparent etc., it's visible, i.e. it takes up space.
I cleaned up your markup a little and added a display style (i.e. setting the elements display to "block" etc), and this works for me:
FIDDLE
Official API reference for :visible
As of jQuery 3, the definition of :visible
has changed slightly
jQuery 3 slightly modifies the meaning of
:visible
(and therefore of:hidden
).
Starting with this version, elements will be considered:visible
if they have any layout boxes, including those of zero width and/or height. For example,br
elements and inline elements with no content will be selected by the:visible
selector.
I don't know why your code doesn't work on chrome, but I suggest you use some workarounds :
$el.is(':visible') === $el.is(':not(:hidden)');
or
$el.is(':visible') === !$el.is(':hidden');
If you are certain that jQuery gives you some bad results in chrome, you can just rely on the css rule checking :
if($el.css('display') !== 'none') {
// i'm visible
}
Plus, you might want to use the latest jQuery because it might have bugs from older version fixed.
I assume it has something to do with a quirk in our HTML because other places on the same page work just fine.
The only way I was able to solve this problem was to do:
if($('#element_id').css('display') == 'none')
{
// Take element is hidden action
}
else
{
// Take element is visible action
}