Complex Menu Positioning

By default, Flyout Menus are positioned with the top-left corner being 2 pixels to the right and 2 pixels above the top-right corner of the image defined with the same tag name as the menu. Variables can be set to move the menu to the left of the image, or to change the number of pixels away from the image. For most uses, these variables offer menu position options which are quite flexible.

However, there may be occasions when menus must be positioned taking more images into account on the page. The Flyout Menus allow you set up a series of positioning rules for more complex positioning behavior.

There is quite a bit of complexity when it comes to using this positioning code, so it may take several tries before the menus appear correctly positioned.

Due to the way its object model and styles are implemented, Internet Explorer for the Macintosh is very slow at using the complex menu positioning. The explanation for why this browser is different is in the annotated source.

Complex Positioning Example

As an example, the menus below are set so that they will never cover up the text in the logo image (overwriting the box is fine), and attempt to not go below the picture image. In either case, they will try to get as close as possible to having the menu centered vertically with its arrow image. The exception to these positioning rules is that the menu will always attempt to not appear off the page, so it will move to prevent that from happening. Keeping the menu on the page takes precedence over all other rules, and cannot be overridden. If the menu is too tall to fit at all on the page, it will be positioned so as much of the top-left part is visible as possible.

 
picture
First Link
Second Link
 
 
Third Link
Fourth Link

A simplified version of this example is available which shows the menus being implemented without the descriptive text.

This is the source of the menu code which includes the positioning rules:

var newDefs = new Object;
newDefs.overimg = "redarrow.gif";
newDefs.useclass = "menutext";
newDefs.position = "IMG|m=m;picture|b>b;logo|b<t";
flyDefs (newDefs);

makeLayer ("arrow1", "",
	"This is menu 1", "It should be positioned", "so the top edge is right",
	"under the logo."
);

makeLayer ("arrow2", "",
	"This is menu 2", "It should be centered", "relative to the arrow"
);

makeLayer ("arrow3", "",
	"This is menu 3", "It is quite a long menu", "so it should also be",
	"positioned so the top", "edge is right under the", "logo, but the bottom",
	"edge may come close to", "the bottom of the picture,", "or may even go below it.",
	"If you size and scroll the", "window to try to force the", "bottom of the menu off below",
	"the bottom of the screen,", "it will reposition itself", "by obscuring the logo."
);

makeLayer ("arrow4", "",
	"This is menu 4", "It should be long enough", "to be aligned with the",
	"bottom of the picture, but", "probably won't reach the", "logo."
);

This looks like the menu definitions in the Customizing Flyout Menus section, except for the line which defines a new position default. Let's first look at the logic of what the line is doing, and then describe the syntax.

  1. The Flyouts will use the default positioning rules to put the top-left corner of the menu near the top-right corner of the arrow image.
  2. The IMG|m=m rule tells the Flyout code to compute the vertical middle of both the arrow image and the menu, and position the menu so they are the same.
  3. The picture|b>b rule says to compute the bottom of the image named picture and of the menus, and make sure the bottom of the picture is positioned lower than (has a larger number, representing the Y position) the bottom of the menu. If not, then move the menu up so they align.
  4. The logo|b-6<t rule will compute 6 pixels above the bottom of the image named logo and the top of the menu, and make sure 6 pixels above the bottom of the logo is positioned higher than (has a smaller number, again representing the Y position) the top of the menu. If not, move the menu down so they align.
  5. Make sure the menu is on the screen. First check horizontally, moving first to the left if it's off the right of the window, then to the right to make sure the left of the menu is visible. Do the same vertically, first checking the bottom, then the top.

The way these rules are ordered means that the preference is for the menus to be aligned with the middle of the arrow, the next preference is that they not go below the picture, but the greatest preference is they not cover up the logo.

If the desire is to have the menus possibly cover up the logo to make sure that they don't go below the bottom of the picture, then the picture and logo rules would be reversed.

Defining Positioning Rules

The position defaults definition is a series of rules each separated with a ; (semicolon). Each rule follows the pattern (without spaces):

image orientation image-target relation menu-target

Image

The image must be one defined on the page. In the example above, the last two rules refer to images named logo and picture. However, the first rule uses IMG as the name of the image, which represents the arrow image used for that menu. For example, while positioning the first menu, IMG would be replaced by the image named arrow1. If the named image cannot be found, the rule is skipped.

Orientation

The orientation can be either - (dash) or | (vertical line.) If it is a dash, then the rule controls horizontal alignment. If it is a vertical line, then the rule controls vertical alignment. In the above example, vertical lines were used since only the vertical position of the menu was adjusted.

Image-Target

The next character represents the part of the image to use as a target. For horizontal alignment, the options are l (lowercase L, representing left), c (center), and r (right.) For example, r would use the right side of the image as a target location.

For vertical alignment, the options are t (top), m (middle), and b (bottom.)

You can also specify a pixel offset from the position by using + or - (minus) followed by the number of pixels. For example, r+5 would cause the image target location to be 5 pixels to the right of the image.

Relation

This can be either <, =, or >. For horizontal positioning, < means the image target location should be to the left (have a lower X value) than the menu target location, = means they should be the same, and > means the image target location should be to the right of the menu target location. Note this means that a menu will almost always move when = is used, but if < or > is used, the menu will only move to make the relation true.

For vertical positioning, < means the image target location should be above (have a lower Y value) than the menu target location, = means they should be the same, and > means the image target should be below the menu target.

Menu-Target

This is the same as image-target, but represents the target location of the menu itself.