Side navigation
#4374 closed bug (fixed)
Opened March 18, 2009 10:47AM UTC
Closed May 16, 2009 04:20PM UTC
Last modified March 14, 2012 02:34PM UTC
:hidden != :not(:visible)
Reported by: | borgar | Owned by: | brandon |
---|---|---|---|
Priority: | minor | Milestone: | 1.4 |
Component: | core | Version: | 1.3.2 |
Keywords: | hidden visible selector | Cc: | |
Blocked by: | Blocking: |
Description
:hidden
fails on elements that have width but no height.
Shouldn't jQuery(':hidden').length == jQuery(':not(:visible)').length
for pages that have hidden elements?
The bug causes problems for containers that don't clear their floats. They have 0 height and yet are visible (or at least their contents). Animate won't, for example, fade them out because animate uses jQuery(this).is(":hidden")
internally to test if an element is already hidden.
The test (jQuery 1.3.2, line 2369):
Sizzle.selectors.filters.hidden = function(elem){ return elem.offsetWidth === 0 || elem.offsetHeight === 0; };
Should probably be:
Sizzle.selectors.filters.hidden = function(elem){ return elem.offsetWidth === 0 && elem.offsetHeight === 0; };
Attachments (0)
Change History (6)
Changed March 18, 2009 02:03PM UTC by comment:1
resolution: | → invalid |
---|---|
status: | new → closed |
Changed March 18, 2009 04:05PM UTC by comment:2
resolution: | invalid |
---|---|
status: | closed → reopened |
How is this logic correct? How is it acceptable that elements can be both visible and hidden at the same time? Either :hidden
is broken or :visible
is broken.
The following is the logic currently within jQuery:
- An element is hidden if has either no width or no height.
- An element is visible if has width or height.
Therefore:
height=0, width=0, visible=false, hidden=true height=0, width=1, visible=true, hidden=true height=1, width=0, visible=true, hidden=true height=1, width=1, visible=true, hidden=false
Clearing the floats is not always what I want to do. I should not need to do this. CSS does not work that way. Height and width do not affect the ''visibility'' of children while overflow is set to visible.
Element assumed as hidden if it or its parents consumes no space in document.
This is clarified in the release notes for 1.3.2:
In jQuery 1.3.2 an element is visible if its browser-reported offsetWidth or offsetHeight is greater than 0.
Which means that the logic for :visible
is correct:
return elem.offsetWidth > 0 || elem.offsetHeight > 0;
More from the same release notes:
if the element's width is 0 and the element's height is 0 then an element will be reported as hidden
But no it won't because the logic is bugged! (see ticket)
Changed March 18, 2009 05:57PM UTC by comment:3
resolution: | → fixed |
---|---|
status: | reopened → closed |
Thanks for adding more details!
Fixed in r6282.
Changed May 16, 2009 04:19PM UTC by comment:4
resolution: | fixed |
---|---|
status: | closed → reopened |
Changed May 16, 2009 04:20PM UTC by comment:5
owner: | → brandon |
---|---|
status: | reopened → new |
Changed May 16, 2009 04:20PM UTC by comment:6
resolution: | → fixed |
---|---|
status: | new → closed |
I believe the logic is correct. The element is not visible if either its width or height is 0. The solution here is to use make sure the parent is able to clear the floated children. There are several good techniques for this cross-browser now.