Closed Bug 276116 Opened 20 years ago Closed 20 years ago

When display:none getComputedStyle for top and left and offsetTop and offsetLeft unavailable

Categories

(Core :: DOM: CSS Object Model, defect)

x86
Windows XP
defect
Not set
major

Tracking

()

RESOLVED INVALID

People

(Reporter: jeremy, Unassigned)

References

()

Details

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0

When an absolutely positioned element has its display style set to 'none' it is
no longer possible to determine its position through DOM. Both offsetTop and
offsetLeft and the getComputedStyle values are changed to 0px. If the positioned
was given by an inline style the values of style.left and style.top are still
available, however if the positioning is class-based then these aren't
available, making it impossible to ascertain the position of the invisible element.

This may seem somewhat trivial, but it does make complex DHTML transitions
impossible and needs to be fixed. 

I have shouted out all of the available properties on the invisible element and
its style object and none of these contain any clue to the position of the
element on the screen. 

Reproducible: Always

Steps to Reproduce:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<title>Computed Invisible Styles</title>
		<style type="text/css">
			.divClass{
				position: absolute;
				top: 200px;
				left: 500px;
				width: 100px;
				height: 100px;
				background-color: pink;
			}
			.cont{border: 2px black dashed; padding: 10px;}
		</style>
		<script language="JavaScript">
			var bHidePink = false;
			function toggleDispPink(){
				var oElm = document.getElementById('pinkDiv');
				if(bHidePink){
					oElm.style.display = 'block';
					bHidePink = false;
				}
				else{
					oElm.style.display = 'none';
					bHidePink = true;
				}
			}

			var bHideBlue = false;
			function toggleDispBlue(){
				var oElm = document.getElementById('blueDiv');
				if(bHideBlue){
					oElm.style.display = 'block';
					bHideBlue = false;
				}
				else{
					oElm.style.display = 'none';
					bHideBlue = true;
				}
			}

			function alertInfo(sId){
				var oElm = document.getElementById(sId);

				//calculate computedStyle
		        var oCompStyle = window.getComputedStyle(oElm, '');
				var oCompTop = oCompStyle.getPropertyValue('top');
				var oCompLeft = oCompStyle.getPropertyValue('left');
				alert('style top: ' + oElm.style.top + '\nComputedStyle top: ' + oCompTop +
'\nOffsetTop ' + oElm.offsetTop + '\nstyle left: ' + oElm.style.left +
'\nComputedStyle left: ' + oCompLeft + '\nOffsetLeft ' + oElm.offsetLeft);
			}
		</script>
	</head>
	<body>
		<div class="cont">Class based <span style="color: pink">pink</span> Div (When
display is set to none (using toggle button) then there is no way to know its
original position)
			<div><input type="button" onclick="toggleDispPink();" value="Toggle Display
(Block/None)" /></div>
			<div><input type="button" onclick="alertInfo('pinkDiv');" value="Alert
Positional Info" /></div>
		</div>
		<div class="cont">Inline Style based Class based <span style="color:
cornflowerblue">blue</span> Div
			<div><input type="button" onclick="toggleDispBlue();" value="Toggle Display
(Block/None)" /></div>
			<div><input type="button" onclick="alertInfo('blueDiv');" value="Alert
Positional Info" /></div>
		</div>

		<div id="pinkDiv" class="divClass"></div>
		<div id="blueDiv" style="position: absolute; top: 200px; left: 200px; width:
100px; height: 100px; background-color: cornflowerblue;"></div>

	</body>
</html>
NB I also tested this case with the Mozilla/5.0 (Windows; U; Windows NT 5.1;
en-US; rv:1.8a6) Gecko/20041226 Nightly build and it crashed completely. 

See incident report TB2768414G for more details.
Assignee: firefox → nobody
Component: General → Layout: R & A Pos
Product: Firefox → Core
QA Contact: firefox.general → core.layout.r-and-a-pos
Version: unspecified → Trunk
Assignee: nobody → general
Component: Layout: R & A Pos → DOM: CSSOM
QA Contact: core.layout.r-and-a-pos → ian
The crash you're experiencing with current nightly trunk builds, is probably bug
275663.

I think the original bug you mention is INVALID, see:
http://www.w3.org/TR/2004/CR-CSS21-20040225/visuren.html#display-prop
under 'none':
"Please note that a display of 'none' does not create an invisible box; it
creates no box at all. CSS includes mechanisms that enable an element to
generate boxes in the formatting structure that affect formatting but are not
visible themselves. Please consult the section on visibility for details."
While I agree with Martijn about the fact that an element with display: none is
not an invisible box, but no box at all as far as the flow is concerned, this
box is still there however. All you have to do is change the display property to
block and it appears in its original position.

My problem with this whole process is that Mozilla knows where the box should be
if it where made visible. My script however cannot. Which prevents me from
changing its position, relative to its original position, while it is invisible
and then making it reappear in a new position.
Some time ago, I've seen some similar bug, and that one was marked INVALID. I
can't find it now, though.
But there are other ways to achieve what you want.
You can cache the values you want in some variable, before you set the display
to none.
Or, even easier, you can set visibility:hidden and position:absolute instead of
display:none, which -I think- is exactly what you're looking for.
> this box is still there however.

No, it's not.  The box is created if the 'display' value is changed to something
other than 'none'.  Where it would appear happens to depend on the 'display'
value.  Hence computing a position for it while display is 'none' makes no sense.
Status: UNCONFIRMED → RESOLVED
Closed: 20 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.