reptile7's JavaScript blog
Monday, March 23, 2009
 
A www.time.gov Style Sheet
Blog Entry #140

With the aid of CSS and a bit of JavaScript, we can code the www.time.gov display in a much cleaner manner. In particular, CSS positioning will enable us to cash in the www.time.gov tables - all four of them - for a single div element and allow us to replace the presentational attributes that position the www.time.gov images - align, hspace, valign, vspace, and also tables[3]'s cellpadding="2" attribute - with a set of style rules, which can be unobtrusively placed in the document head or in an external file.

So, let's start with our new div element container, to which we will give the identifier div0:

<div id="div0"> ...www.time.gov images... </div>

Here's the style rule set we'll use for this guy:

#div0 {
width: 481px; height: 416px;
margin-left: auto; margin-right: auto;
border: 1px solid #ffcd38;
background-color: #00695e;
position: relative; }


Comments
• Excluding the spacer element borders, the www.time.gov foreground measures exactly 481px by 416px.
• The div element has a default width of "100%", i.e., it spans the entire width of the viewport. Giving div0 a specific width and setting its margin-left and margin-right properties to auto horizontally centers div0 within the viewport. (The div element is like the form element in this respect - see the "Centering a form" section of Blog Entry #93.)
• The original www.time.gov border code can be replaced by a single style declaration, border:1px solid #ffcd38;.
div0 is given tables[2]'s #00695e background color.
div0 is relatively positioned so that it serves as the containing block for positioning its img element children.

To the best of my knowledge, CSS alone cannot be used to vertically center a div or other block-level element within the viewport; however, if we give the body element a body0 identifier, then we can vertically center div0 in the viewport via the cross-browser script below:

<body id="body0">
<!-- The original www.time.gov body element attributes - bgcolor, link, alink, and vlink - are all deprecated; we'll deal with them later. -->
<div id="div0"> ...www.time.gov images... </div>
<script type="text/javascript">
var outerdiv, vtotal, topoffset;
outerdiv = document.getElementById("div0");
outerdiv.style.height = "416px";
vtotal = document.getElementById("body0").clientHeight;
topoffset = (vtotal - parseInt(outerdiv.style.height)) / 2;
outerdiv.style.top = topoffset;
</script>


As shown, this script should be placed (or referenced, for an external script) in the document body and after div0. The script requires support for the DOM getElementById( ) method and clientHeight property, but if you're using a relatively modern browser, then you should be OK. Alternatively, I would certainly understand if you simply gave div0 a margin-top:150px; style and said, "Close enough for government work."

We turn now to www.time.gov's images. (In most cases - excepting starstripe.jpg and map2.gif - the www.time.gov images could be replaced with #PCDATA text, but because the www.time.gov coder(s) went to the trouble of creating these images, why not make use of them?) As detailed in the previous entry, ten img placeholders are spread across tables[2] and tables[3]; per their source order, we will give these placeholders the identifiers img0, img1, ... img9.

Upon stripping out the various presentational attributes - including width and height, which are valid for the img element - and also the name attributes for the img4, img5, and img9 placeholders - the name attribute of the img element is legit in HTML but is deprecated by XHTML 1.0 - the www.time.gov img code can be simplified to:

<img id="img0" src="/images/starstripe.jpg" alt="Welcome to" />
<img id="img1" src="/images/head.gif" alt="The Official US Time" />
<img id="img2" src="/images/pleaseclick.gif" alt="Please Click" />
<img id="img3" src="/images/map2.gif" usemap="#usatimezonemap" alt="Select a time zone" />
<img id="img4" src="/images/labels/zone-00.gif" alt="Zone-00" />
<img id="img5" src="/images/zonenames.gif" usemap="#zonenamesb3c96c19" alt="Time Zone Names" />
<a href="exhibits.html"><img id="img6" src="/images/timeex.gif" alt="Time exhibits" /></a>
<a href="about.html"><img id="img7" src="/images/aboutthisservice.gif" alt="About this service" /></a>
<a href="http://www.nist.gov/public_affairs/privacy.htm"><img id="img8" src="/images/privacy.gif" alt="Privacy Statement" /></a>
<span id="span0" onclick="ToggleJava( );"><img id="img9" src="/images/javaoff.gif" alt="Disable/Enable Java" /></span>


The original img9 placeholder is written by a script element and as the child of an anchor element:

<script language="JavaScript1.2"><!--
if(JavaOK){document.write('<a href="#" onclick="ToggleJava(this);"><img src="/images/javaoff.gif" width="186" height="11" align="right" name="IsJava" alt="Disable/Enable Java" border="0" /></a>');}//--></script>


Contra Blog Entry #138, a closer look at the document head's first script element reveals that it contains no commands that set JavaOK, which is initialized with a value of 1, to 0 if the user's browser is not Java-enabled, and thus the "Disable Java Animation" javaoff.gif image is initially loaded into the img9 placeholder regardless of whether the user's browser is Java-enabled or not.

The preceding anchor element is not really a hyperlink, in the sense that its href="#" attribute does not point to a target anchor, but merely serves as a container for a call to the ToggleJava( ) function in the document head's first script element, which, per its identifier, toggles the javaoff.gif and javaon.gif images in the www.time.gov foreground's lower-right-hand corner. I confess that the use of anchor elements as user interface elements gets my goat, so I've replaced img9's anchor element parent with a span0 span element, which can be given a cursor:pointer; style so that it appears to be a link. For its part, the script element is clearly not necessary if its document.write( ) command is triggered by an if statement whose condition is necessarily true. On the other hand, if in the document head JavaOK were toggled to 0 by a not-Java-enabled browser, then a post-img9

document.getElementById("img9").src = JavaOK ? "javaoff.gif" : "javaon.gif";
// The ?: conditional operator is detailed here.


script command would load img9 with either javaoff.gif or javaon.gif as appropriate. Moreover, the ToggleJava( ) function should now be rewritten as:

function ToggleJava( ) {
if (JavaOK) { document.getElementById("img9").src = "javaon.gif"; JavaOK = 0; }
else { document.getElementById("img9").src = "javaoff.gif"; JavaOK = 1; } }
// ToggleJava( ) does not need to be passed this or anything else.


(The setzone( ) function in the document head's second script element should be rewritten analogously - I trust you can do that.)

We're finally ready for some img style rules:

img { border: 0px; }
#img0 { width: 21px; height: 416px; float: left; }
#img1 { width: 438px; height: 30px; position: relative; left: 11px; top: 13px; }
#img2 { width: 181px; height: 10px; position: relative; left: 23px; top: 29px; }
#img3 { width: 413px; height: 204px; position: relative; left: 23px; top: 33px; }
#img4 { width: 404px; height: 18px; position: relative; left: 21px; top: 33px; }
#img5 { width: 413px; height: 20px; position: relative; left: 23px; top: 40px; }
#img6 { width: 112px; height: 13px; position: relative; left: 88px; top: 58px; }
#img7 { width: 147px; height: 13px; position: relative; left: 108px; top: 58px; }
#img8 { width: 208px; height: 11px; position: relative; top: 78px; }
#img9 { width: 186px; height: 11px; position: relative; left: 62px; top: 78px; }
#span0 { cursor: pointer; }


Comments
starstripe.jpg must be floated left if the other images are to 'flow' down its right side.
• Unsurprisingly, these rules do not give identical displays with different browsers. The above left declarations are rendered by the browsers on my computer in an impressively consistent manner - this is not true for the top declarations, however. Using the presentational values in the www.time.gov source and with the aid of DigitalColor Meter's "aperture" feature, I initially worked out a set of left and top values that precisely reproduced the www.time.gov display when using Firefox; my original Firefox top values gave a slightly-different-but-acceptable rendering when using Opera but, alas, pushed the img8 and img9 images below div0's bottom edge when using Safari, so I reduced some of them a bit (rather than increasing div0's height) in order to get everything inside div0.
• It is left to you to add declarations for the tables[2] bgndteal.gif and starstripe-bg.jpg background images if you feel they are necessary.

What's left? Oh yeah - the body element's attributes

<body bgcolor="black" link="#cedbd2" alink="#0000aa" vlink="#cedbd2">

can be replaced by the following style rules:

body { background-color: black; }
a:link, a:visited { color: #cedbd2; }
a:active { color: #0000aa; }


However, the www.time.gov source's anchor elements have no textual content - they surround images in all cases - so unless we convert the timeex.gif, aboutthisservice.gif, and privacy.gif images to text, the above a:link, a:visited, and a:active rules serve no purpose and can be thrown out.

We'll take up the merging of the usatimezonemap and zonenamesb3c96c19 map elements in the following entry.

reptile7

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)