I’m building a “system health” screen in a web UI for an appliance. Part of that is a bank of gauges to display power supply voltages. The gauges are constructed from a stack of ‘inline-block’ divs. They’re constructed client-side based on a JSON description (threshold levels, reading, title etc.), but I don’t believe that is in any way contributing to my problem as I can reproduce it with static HTML. By changing the ‘top’ property of the .needle element, the reading can be updated live. The gauge is split into 7 segments : good and hi/lo warn, critical, fatal. As long as they’re symmetrical, everything looks fine. If I rearrange things so that my gauge is zero based, the low fatal band correctly expands to extend all the way to zero. The unwanted side effect is that the whole gauge offsets down the page by the height difference between lo-fatal and hi-fatal.
The code below is a self-contained demonstration of the problem:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<!-- IMPORTANT - After any changes, check this against the w3c validator:
http://validator.w3.org/#validate_by_upload
Anything other than a clean pass is not acceptable!
//-->
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>WTF?!?</title>
<style type="text/css">
.gaugeset {
background : #f8f8f8;
font-family : sans-serif;
font-size : 70%;
border : thin solid #ccc;
display : inline-block;
text-align : center;
}
.gauge {
background : #f0f0f0;
font-family : sans-serif;
border : thin solid #ccc;
margin : 7px;
display : inline-block;
border : thin solid black;
}
.gauge > h1 {
background : white;
font-size : 120%;
text-align : center;
-webkit-border-radius: 5px 5px 0px 0px;
-moz-border-radius : 5px 5px 0px 0px;
border-radius : 5px 5px 0px 0px;
margin : 0px;
padding-left : 7px;
padding-right : 7px;
}
.readout {
display : inline-block;
height : 180px;
width : 24px;
margin : 7px;
margin-left : 27px;
margin-right : 45px;
border : thin solid #ccc;
}
.fatal {
background : #ff7f7f;
height : 10%;
}
.critical {
height : 10%;
background : #ffbf7f;
}
.warn {
height : 10%;
background : #ffff7f;
}
.good {
height : 40%;
background : #c0ffc0;
}
#asymetric .fatal {
height : 18px;
}
#asymetric .critical {
height : 22px;
}
#asymetric .warn {
height : 6px;
}
#asymetric .good {
height : 19px;
}
#asymetric #special {
height : 87px;
}
.needle {
position : relative;
left : 27px;
top : 45px;
line-height : 0; /* So that the tip of the arrow is where we want it */
}
/* The text to the left that marks the transitions between zones */
.marker {
position : relative;
right : 29px;
text-align : right;
line-height : 0;
font-size : 70%;
}
</style>
</head>
<body>
<div class="gaugeset">
<div class="gauge">
<h1>1.0V</h1>
<div class="readout" id="asymetric">
<div class="needle">◀ -.--V</div>
<div class="fatal"></div><div class="marker">1.4v</div>
<div class="critical"></div><div class="marker">1.3v</div>
<div class="warn"></div><div class="marker">1.2v</div>
<div class="good"></div><div class="marker">0.8v</div>
<div class="warn"></div><div class="marker">0.7v</div>
<div class="critical"></div><div class="marker">0.6v</div>
<div class="fatal" id="special"></div>
</div>
</div>
<div class="gauge">
<h1>1.0V</h1>
<div class="readout">
<div class="needle">◀ -.--V</div>
<div class="fatal"></div><div class="marker">1.4v</div>
<div class="critical"></div><div class="marker">1.3v</div>
<div class="warn"></div><div class="marker">1.2v</div>
<div class="good"></div><div class="marker">0.8v</div>
<div class="warn"></div><div class="marker">0.7v</div>
<div class="critical"></div><div class="marker">0.6v</div>
<div class="fatal"></div>
</div>
</div>
</div>
</body>
</html>
I’ve been all over it with Firebug inspecting the elements visually and checking the computed heights, tops etc. without success. Something in the assymetric gauge is ‘snagging’ and disrupting the intended document flow. What is it?
You need to add
vertical-align: topto.gauge, because it hasdisplay: inline-block.Read this, particularly the section talking about “baseline” to understand why
vertical-alignmatters: http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/In general, whenever you use
inline-block, you should consider settingvertical-align(unless you’re happy with the default ofbaseline).You can see a comparison of the common values of
vertical-aligncombined withinline-blockhere: http://www.brunildo.org/test/inline-block.html