From this simple html.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hello</title>
<style type="text/css" media="screen">
.t1 {
padding: 0px;
margin: 0px;
}
.popup {
display: inline-block;
position: relative;
width: 0px;
padding: 0px;
margin-left: -0.5em;
}
.hint {
position: absolute;
z-index: 1;
width: 20em;
background-color: white;
border: 1px solid green;
padding: 0.5em;
margin-top: 1em;
}
.list {
padding: 0px;
padding-left: 1em;
margin: 0px;
}
</style>
</head>
<body>
<!-- properly layout -->
<div style="height: 10em;">
<span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span>
<div class="popup">
<div class="hint">
<ul class="list">
<li>NewSimpleObject(int x);</li>
<li>NewComplexObject(int x, int y);</li>
<li>NewComplicateObject(int x, int y, intz);</li>
</ul>
</div>
<div> </div> <!-- no idea why, but ending space is required for proper layout -->
</div>
</div>
<!-- incorrect layout -->
<div style="height: 10em;">
<span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span>
<!-- mysterious vertical space appear here -->
<div class="popup">
<div class="hint">
<ul class="list">
<li>NewSimpleObject(int x);</li>
<li>NewComplexObject(int x, int y);</li>
<li>NewComplicateObject(int x, int y, intz);</li>
</ul>
</div>
<!-- <div> </div> -->
</div>
</div>
</body>
</html>
Here is the result:
The result is similar across browser. So I believe this is not a browser bug.
Where does the vertical space between the text-line and the popup-hint in the second rendering come from ? And how can the <div> </div> solve this problem ?
UPDATED:
Conclude from Richard M answer. Box with no content has no dimension (with an exception of Inline). The <div> </div> make "popup" dimension exists.
The better solution, according to Richard, is to use inline instead of inline-block. Since the vertical dimension of inline is the same regardless of its content existence
For some reason I don't know yet, the margin-top: 1em is no longer necessary when switch to "inline"
UPDATED 2:
OH NO.. This issue cannot be concluded yet. The change that Richard M suggest (use inline
and remove margin-top
) would work only with Webkit Browser (Chrome, Safari) On IE and Firefox , the popup
box align to the left rather than to the text line.
The first sample in the question (inline-block & non-empty content) is probably the most reliable option for now.
UPDATED 3:
Conclusion ! The true cause of this issue originate from the fact that non-inline
block with no content has no dimension. Richard M suggest using inline
to avoid this issue. Unfortunately, I've found this solution inconsistence across browsers. I came up with another option in opposite direction, using inline-block
with forced dimension via height: 1px;
This work correctly in any browser.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hello</title>
<style type="text/css" media="screen">
.t1 {
padding: 0;
margin: 0;
width: 0em;
}
.popup {
display: inline-block;
padding: 0;
margin: 0;
position: relative;
width: 0;
height: 1px; <!-- force vertical dimension -->
}
.hint {
position: absolute;
z-index: 1;
padding: 0;
margin: 0;
margin-top: 1px; <!-- compensate for the setup dimension -->
width: auto;
white-space: nowrap;
background-color: white;
border: 1px solid green;
}
.list {
padding: 0;
padding-left: 1em;
margin: 0.5em;
}
</style>
</head>
<body>
<!-- properly layout -->
<div style="height: 10em;">
<span class="t1">MyObject o = www.mycompany.project.ObjectFactory.</span><!--
whitespace is not welcome
--><div class="popup">
<div class="hint">
<ul class="list">
<li>NewSimpleObject(int x);</li>
<li>NewComplexObject(int x, int y);</li>
<li>NewComplicateObject(int x, int y, int z);</li>
</ul>
</div>
</div><!--
whitespace is not welcome
--><span>(1, 2, ...</span>
</div>
</body>
</html>