question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

:visible/:hidden selectors unreliable

See original GitHub issue

Issue

This issue is present in both version 1 and 2 of jQuery.

It is happening on inline elements wrapping block elements, which is valid in HTML5, such as a header and an image wrapped in a single anchor.

Two issues arise:

  1. Different browsers report offsetWidth/Height of the anchor differently. For example Firefox would report one visible anchor in the example below, and Chrome will report 0. This also highly depends on the CSS styles applied, as on the page where this issue was discovered missing images are not displayed at all instead of the common missing image icon.
  2. While a browser may report an anchor as invisible, child elements are still visible and clickable as they inherit anchor properties.

Example

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
    <a href=#>
        <h1>Header</h1>
    </a>
    <script>
        $(function () {
            alert('Visible anchors: ' + $('a:visible').length);
        })
    </script>
</body>
</html>

Solution

There are 2 potential solutions that come to mind, but each has flaws

  1. Loop through child elements and check each for visibility. Potentially harmful for performance, although the selector is already marked as such in the documentation.
  2. Check parent for visibility. Probably not enough on its own, as it will report incorrectly, if anchor doesn’t have visible children.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:22 (17 by maintainers)

github_iconTop GitHub Comments

1reaction
timmywilcommented, Apr 21, 2015

Thank you for opening an issue. While you are correct that the behavior may be unexpected, the selector is working as documented. While the behavior differs between Firefox and Chrome, Chrome reports zero width and zero height, which technically means it is not visible according to our docs…

Visible elements have a width or height that is greater than zero.

The fact the hidden elements can have visible content can seem strange, but it’s the way it is in Chrome. But more importantly, the cost of working around this would be far greater than we are willing to deal with. I don’t think this is the only edge case where the :visible selector behaves in a way that can be unexpected, but I would prefer to keep the selector as simple as possible and let the edge cases be covered by other means.

0reactions
FesterCluckcommented, Sep 20, 2015

My apologies for commenting on a closed issue, but I believe this case warrants review.

Using ClientRectList.prototype.length an anchor tag with no text is “visible”, not to mention one with child elements which have no dimension either.

Please consider https://github.com/FesterCluck/jquery/blob/master/src/css/hiddenVisibleSelectors.js

If this is not part of the new intended behavior, my apologies.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The `hidden` Attribute is Visibly Weak - CSS-Tricks
It's extremely weak. Literally any change to the display property other than the none value on the element with any strength selector will ......
Read more >
Difference between :hidden and :not(:visible) in jQuery
The :hidden selector is the opposite of the :visible selector. So, every element selected by :hidden isn't selected by :visible and vice versa....
Read more >
visibility - CSS: Cascading Style Sheets - MDN Web Docs
The visibility CSS property shows or hides an element without changing the layout of a document. The property can also hide rows or...
Read more >
jQuery Basics: Is Element Hidden or Visible?
The “:visible” selector will match an elements that are essentially Visible to the user within the page. This is determined by inspecting the ......
Read more >
Selecting Elements - jQuery Learning Center
Note: When using the :visible and :hidden pseudo-selectors, jQuery tests the actual visibility of the element, not its CSS visibility or ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found