HierMenus CENTRAL: HierMenus In Progress. HierMenus 5.3 Release Notes (6/7)
[previous] [next] |
dir="rtl" in Internet Explorer (cont.)
More image horizontal spacing incorrect
You may have noticed, by way of the last example gif on the previous page (which was taken from an actual HM 5.2.1 LoadMe page), that the hspace parameter of an image element, which we've previously used to assist in ironing out minor quirks in IE image positioning, is interpreted differently in Internet Explorer with rtl mode in effect. Basically, the hspace value assigned is doubled and assigned entirely to the right of the image; as opposed to being assigned as is to the left and right of the image. Further, images with assigned hspace values tend to run slightly over the text they are next to in rtl settings.
hspace is a deprecated HTML attribute, we had no regrets about removing it entirely (actually, we force it to zero, just to be safe). Doing this triggered a chain reaction of additional minor adjustments in our fixSize routine, adjustments that originally assumed that hspace would be in effect. But we feel the end result is worth the effort; as more image positioning is now consistent in both standard and dir="rtl" implementations.
Reported mouse position is off by width of vertical scrollbar
Recall from our discussion on the previous page that, by default, the position of the visible pixel in the top left corner of the initial Internet Explorer browser window on an rtl enabled page is (0,0). This is (generally) true whether the vertical scrollbar of the page (remember, in Internet Explorer rtl mode automatically moves the vertical scrollbar to the left of the page) is visible or not. If the vertical scrollbar is visible, (0,0) appears to the immediate right of it. If the vertical scrollbar is hidden, (0,0) is located in the top right corner of the initial browser window.
The mouse position reported within an event handler, however, does not follow this same positioning logic. Instead, the mouse position is always reported as if (0,0) is the top left corner of the window, whether that position happens to be obscured by a vertical scrollbar or not. To put it another way: if the vertical scrollbar is visible, then the left pixel position to the immediate right of the vertical scrollbar is 0; but if you place your mouse on that pixel position, fire an event handler, and then, within the event handler, interrogate the clientX parameter, you will find that it is not 0; but instead includes the width of the scrollbar.
(Note: Technically the position reported wouldn't be 0 even with the scrollbar visible, since IE reports the mouse position relative to the edge of its browser chrome, which takes an additional couple pixels even in a full width screen. But typically, it's very close to zero.)
If you're unclear on this point, have a look at the following example page, which opens in a new window and is designed specifically to illustrate our point in Internet Explorer 5.0+. On the example page, we've defined a blue, 1 pixel wide by 300 pixel tall absolutely positioned div and placed it at pixel position (0,0) on an rtl mode page. As we expect, when you initially view the page, the blue div will appear as a thin, vertical blue bar flush against the vertical scrollbar. We've also attached an event handler to the mouseover property of the div. When you roll over the blue line, the left position of the mouse position that is included in IE's event object is reported via an alert box to the screen. Although the object is definitely positioned at a left pixel position of zero on the document, and there is no horizontal scrollbar on the page, the position reported by the mouse is much higher than zero (18 on our test machines).
Internet Explorer Mouse Position in rtl Documents
Though conceptually this is a simple problem, there does not appear to be a simple solution for it. In order to properly adjust the mouse position in relation to the x position of the document, we must know two things: whether the vertical scrollbar is currently showing on the page, and the exact width of the vertical scrollbar itself. Neither is easily obtained using JavaScript in an Internet Explorer document.
To determine the scrollbar's potential visibility you must account for the style overflow property as well as IE's proprietary scroll property; not to mention the possibility of the scrolling property when within a frame, or the scrollbars property within a newly opened window (or any legal combinations of the above). If the scroll or overflow properties are set to auto, you must determine whether the scrollbars are showing, or not, based on the dimensions of the document and browser window. And we are currently unaware of any graceful way to determine the actual width of the vertical scrollbar in Internet Explorer. Of course, if you know something we don't on either of these points, please feel free to give us a holler--we'd love to hear about alternatives!
Even if we could gracefully determine the visibility of the vertical scrollbar and its width, there's another problem. The rule above about the mouse postion is not always consistent. Specifically, if the document is in standards mode and overflow="auto" is specified on the document's <html> tag, then the document positioning is shifted so that its left pixel position of 0 is beneath the vertical scroll bar (like the mouse position), and that position remains as is whether the vertical scrollbar is displayed or not. Similar (but, unfortunately not always identical) types of exceptions are found when using IE's proprietary scroll property on the <body> tag.
The net result is that we have no immediate answer
that conclusively solves this problem within the HM scripts. However,
if you are using mouse positioning for your menu popups in an rtl
mode page, and you know that your pages always display a vertical scrollbar,
you can simply add a constant value to the menu's popup position to adjust
for the discrepancy. This won't be perfect in all cases, of course, but will
account for most scenarios:
HM_Array1 = [ [150, // menu width "mouse_x_position - "+ "(HM_DOM&&HM_IE&&HM_f_RTLCheck() ? 16 : 0)", // left_position , // top_position ,,,,,], // etc. ["Experts","/experts/",1,0,1], ["Contents","/index2.html",1,0,0], ...
Be sure to also see the top-left vs. top-right menu positioning discussion in the Advanced Topics section of an earlier page of this article.
dir="rtl" in Mozilla (Gecko)
In Gecko browsers, rtl mode does not shift the x/y positioning of the document as it does in Internet Explorer, so the number of unique issues we encountered in this browser were much less than in Internet Explorer. In fact, apart from the scrollParent width bug described in the Internet Explorer section on the previous page (which actually affects all rtl capable browsers), only one further Gecko problem was uncovered.
Text in rtl elements is placed at the left position of the parent element
This odd bug, which appears to have been corrected in Gecko builds equal to or later than 20030312 (that's roughly Netscape 7.1 and later, as well as Mozilla 1.3 and later) seems to only occur if the container element is absolutely positioned, if it is set to dir="rtl" (either directly or by virtue of inheritance), and has a specifically set width. In this situation, the text within the container element itself is poitioned not within the container as you would expect, but instead is positioned as if it were in the container's parent element. The remaining properties of the container element itself are accurate, and, adding to the confusion, the width of the text block itself is accurate. The entire block of text is simply shifted to the left side of the container element's parent.
To illustrate, have a look at this sample page, which will open in a new window and is designed specifically to be useful only in earlier, Gecko-based browsers. The page contains a 400px wide absolutely positioned div (at pixel position 10,10). Within this div are four additional divs; each 100px wide and positioned to be adjacent to one another in a horizontal fashion. Each of the four divs is separately colored and contains a small amount of text. This type of setup is very similar, internally, to the type of structure created dynamically by HierMenus.
The result that we expect from this layout, and that we get in Netscape 7.1 or Mozilla 1.3 and later, is as follows:
In earlier Geckos, however, this is what we see:
We can't effectively remove the width parameters of our menu items, so fixing the problem that way isn't possible. And forcing an additional non-positioned div around the menu item text caused sizing problems of its own, especially in variable width menus (which, in rtl settings, would all but lose their variable width setting entirely).
The only graceful workaround we were able to discover is this: in early Gecko browsers where rtl mode is in effect, we create all menus with an explicit dir="ltr" attribute on the menu item itself, and force the text alignment of the item to be right-aligned. Additionally, we then force the rtl display of the menu text by enclosing it in a span tag with a dir="rtl" setting. Using a span tag avoids the additional sizing problems we encountered when attempting to force an enclosing div around the menu item text, and the combination of setting dir="ltr" and style.textAlign="right" on the menu item nicely emulates the desired rtl behavior.
This workaround may cause a problem for a very small number of HM implementations (specifically, those that include additional container objects, such as divs or tables, in their menu item descriptions), but since the problem will surface only in earlier Gecko browsers where rtl mode is in effect, we feel that the simple workaround is worth it. All other browsers (including later version Gecko browsers) will ignore the workaround completely, so as to not include additional document structure that is unnecessary.
dir="rtl" in Opera
Only one Opera specific problem was encountered in regards to rtl processing, and that is that not all Opera 7.x versions support directionality. Only Opera versions of 7.2 or later appear to support dir="rtl", and therefore our HM_f_RTLCheck function in the Opera code was adjusted to account for this fact:
// 5.3 function HM_f_RTLCheck() { if(HM_BrowserVersion<7.2) return false; ...
We conclude this HM release bulletin with a look at some of the more interesting issues surrounding our rollover and more image positioning implementations (a much smaller list than the rtl issues, we promise), as well as a quick roundup of bug fixes that found their way into the HM 5.3 release.
Created: October 23, 2003
Revised: October 23, 2003
URL: https://www.webreference.com/dhtml/hiermenus/inprogress/9/6.html