reptile7's JavaScript blog
Saturday, July 18, 2009
How Much Is That Image in the Window?
Blog Entry #151

In the previous post, we went through HTML Goodies' "Remote Image" script in detail, but said little about how it all works out in practice - we'll do that today. Let's begin with a closer look at Joe's demo...

More on width, height, cond1, and cond2

You can use the to-be-displayed image's intrinsic width and height for the transferview( ) width and height argument values, but you don't have to. Joe himself pairs a 79px-by-114px joe2.gif image with the function's width=200 and height=300 arguments, giving the window below:
The 'Remote Image' demo window
I can see why Joe did not assign 79 to width. The width of the joe2.gif image is actually smaller than that of the underlying button, which itself extends slightly beyond the right edge of the viewport for the width=100 window that is generated when width=79 is increased by 20 via the cond1 assignment statement. (A 100px-by-100px viewport is as small as you're gonna get with Firefox, MSIE, and Safari; Opera will let you take the width down to 70.)

You can see from the above image that a width=220 cond1 value for the joe2.gif image is a bit large, but not overly so, whereas a height=370 cond2 value is clearly overkill. As a sort of compromise, assigning 114 to height while keeping the width=200 argument (onclick="transferview('/images/joe2.gif', 200, 114);") gives a nicely sized demo window:
The 'Remote Image' demo window with a height based on the image's height
The preceding screen shots were taken when using MSIE 5.2.3 for Mac OS X. In contrast, Firefox, Opera, and Safari do not place an empty line box between the joe2.gif image and the button and do not equip the height=114 window with a right scrollbar.

Centering the display

In the ImageWindow document, the joe2.gif img placeholder and the Close Window control are wrapped in a center element, which centers the display horizontally but not vertically. The center element is "shorthand" for a <div align="center"> ... </div> element and was deprecated by HTML 4.0. Moreover, the align attribute is now deprecated for most of the elements that can/could take it (align is still legit for the "internal" table elements - tr, td, col, etc.); align can specify a horizontal or vertical alignment for some of these elements, and only a horizontal alignment for the others - the div element is in the latter group.

Should we get rid of ImageWindow's center element? We noted last time that, as CDATA, a stringified center element in a script does not violate the HTML 4.01 Strict DTD. But if we were to ever migrate the ImageWindow document to an external file in which the document is written as normal HTML, then yeah, we would want to exchange the center element for a state-of-the-art alternative. Perhaps the most straightforward way to do this is to:
(1) Replace the center element with a regular div element (as noted above, the center element is itself a type of div element).
(2) Give the div element a text-align:center; style via, e.g., (a) an inline style attribute added to the div element start-tag, (b) a style element block in the document head, or (c) a = "center"; JavaScript command.

Its documentation in the CSS 2.1 Specification's "Text" chapter notwithstanding, the text-align:center; style smoothly centers the joe2.gif image and button with all of the OS X browsers on my computer. The CSS text-align property applies to block-level elements, table cells, and inline-block elements, which raises the question: Why not assign the text-align:center; style to the document's body element, which is a 'root' block for all practical purposes, and then just ditch the center element? In this case, the joe2.gif img element would become a direct child of the body element, which is OK by the HTML 4.01 Transitional DTD but is forbidden by the Strict DTD, and thus not the way to go if you're setting the bar high.
Body element declaration in the Transitional DTD:
<!ELEMENT BODY O O (%flow;)* +(INS|DEL) -- document body, children can be block-level or inline -->
Body element declaration in the Strict DTD:
<!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL) -- document body, children must be block-level -->

The div element has an effective width of 100%, and the text-align:center; style centers the contents of the div. Alternatively, the div element can be shrunk to 'blanket' its contents by setting its CSS width to a suitable value and then itself horizontally centered within the ImageWindow viewport à la a table element, i.e., by setting its CSS margin-left and margin-right properties to auto. For example, the button has a width of about 95 pixels (it varies slightly depending on the browser), so we might set the width of the div to 100px for centering purposes. In this case, the joe2.gif image and button will be left-justified with respect to each other (in the absence of further tweaking), but the resulting display looks fine IMO.

The form element is a block-level element, and you may be wondering, "Why don't we bring the joe2.gif image into the form that holds the button, and then apply text-align:center; to the form?" This would also be a viable option for updating the center element. Doing so will initially put the joe2.gif image and the button in the same line box; the latter can be 're-dropped' via one or two <br /> elements, per your preference.

But I would just as soon lose the form element too. The button - more precisely, its underlying input element - is a user interface element and doesn't need a form container; to put it another way, despite my use of the word "control" earlier, the Close Window input is not really a form control in the sense that we're not sending its name*/value data to a processing agent. The only practical reason to hold on to the form element is to accommodate users of ancient browsers (e.g., Netscape 4.x) that won't render form control elements outside of a form, and if you are using one of these browsers, given the ready/free availability of more recent browsers, may I kindly suggest that you consider upgrading?

*Indeed, the Close Window input doesn't even have a name attribute: FYI, this is actually a violation of both the Strict and Transitional DTDs, which require the name attribute for all input types except submit and reset - see here, e.g.

As for vertically centering the div container within the ImageWindow viewport, this can be done via the following general method:
(1) Take a screen shot of the div and obtain the div's height from the resulting image.
(2) Using the CSS position and top properties, push down the div by half of the viewport's remaining (unused) vertical space.
For example, suppose the height of the div is 140 pixels and the total height of the viewport is 370 pixels (as set by the ) command): the amount of remaining vertical space in the viewport is then 370 - 140 = 230 pixels, and thus the div can be vertically centered with a position:absolute;top:115px; style.
(A related but complementary approach to vertically centering a div element, for which we knew the height of the div but didn't know the height of the viewport, was presented in Blog Entry #140.)


Float it

Admittedly, you may not care about centering the display; perhaps you would rather float the image left or right and then flank it with some text or whatever - I do this in my demo below.

More on transferview( )'s parameterization

The parameterization of the transferview( ) function allows it to be used with a document containing >1 images for display in ≥1 new windows. For such a document, if you feed the images' intrinsic widths to the transferview( ) width argument, then the ) strWindowName parameter, newwin + width, will cause
(a) images with the same width to be opened in a common window, and
(b) images with different widths to be opened in different windows.
If this is to your tastes, fine. If you would prefer that all of the images open in a common window, then get rid of the + width part and just set strWindowName to newwin. If you would prefer that all of the images open in different windows, then you should use the special value _blank for strWindowName, quoting Mozilla.

We can of course expand transferview( )'s parameterization beyond the image, width, and height variables. For example,

function transferview(image, width, height, myTitle) {
ImageWindow.document.title = myTitle;
... }
<!-- To be triggered by: -->
onevent="transferview('myImage.gif', ###, ###, 'Title element text');"

can be used to set custom titles for a series of image windows.

More style, and a demo

At the beginning of the previous post, we noted that planting the window image in a document opens the door to styling that document and its elements per our preferences - e.g., we can give the image a custom border, we can surround the image with a custom background, etc. - I trust you can write out the CSS to do these kinds of things.

Let's wrap up our "Remote Image" discourse with a demo:

Welcome to the "Remote Image" Demo Opener Page.

A couple of comments:
• JavaScript commands are used to apply various styles to the new window's document, with one exception: an inline style attribute sets the img float property, as neither Firefox, MSIE, nor Opera would float the image JavaScriptically (although Safari would do so).
• The new window's button is "cleared" (placed below the floated image) and centered via a separate div container; like the text-align property, the CSS clear property does not apply to inline elements.

We'll take on HTML Goodies' "Hello Goodbye" script, which codes a self-closing window, in the next post.


Comments: Post a Comment

<< Home

Powered by Blogger

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