#4374 closed bug (fixed)
: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; };
Change History (6)
comment:1 Changed 15 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 Changed 15 years ago by
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)
comment:3 Changed 15 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
Thanks for adding more details!
Fixed in r6282.
comment:4 Changed 14 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:5 Changed 14 years ago by
Owner: | set to brandon |
---|---|
Status: | reopened → new |
comment:6 Changed 14 years ago by
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.