Monday, April 02, 2007

Using both "left" and "right" properties in a CSS style

I recently was working on a web page where I needed to draw a rectangle that would always be 50 pixels from the left edge of the browser window and 100 pixels from the right edge of the browser window, and which would stretch/shrink to maintain these criteria as the browser window was resized by the user. (Essentially, the rectangle would be "anchored" to both the left and right edges of the browser window.)

This rectangle would otherwise always appear on the same place on the page, and thus could be set to use the position:absolute style. Anchored Rectangle I decided to use a simple <div> tag set with a background-color CSS property to render the rectangle on the page.

To accomplish this, at first I was thinking I would need to catch the browser's window resize event, and call a Javascript function that would check the browser window's new width, subtract from that width the right "padding" for the rectangle (100 pixels in this case), and set the resulting figure as the new width for the rectangle.

Then I hit upon an alternative solution which wouldn't involve any scripting at all: I could simply set both the left and right CSS properties of the rectangle. The browser would be responsible for maintaining the rectangle's distance from the left edge of the browser window as well as the rectangle's distance from the right edge of the window, and thus script to resize the rectangle would not be necessary. The width property would not need to be specified at all, since the browser itself would calculate the width required to keep the rectangle the specified distances from the left and right browser window edges.

This works great in IE7 and Firefox 2. Unfortunately, it doesn't work in IE6. Apparently IE6 just does not support the specification of both left and right properties, or both top and bottom properties, of a CSS element. Instead, you need to specify one or the other plus width or height (as appropriate).

I did end up finding an approach that would work with IE6 and still only need a single line of CSS (at least for IE support). For IE, the CSS width property can be set using IE's proprietary "expression" syntax as in this snippet of CSS:

left:50px; width:expression((this.parentNode.offsetWidth - 150) + 'px')
This sets the width of the element to which the style is applied to the width of the parent element (the browser window, in the case of top-level elements), minus the specified value (150 in the above example), which should be set to the sum of the left property value and the effective value for the right property. In the above example, the style would cause the element to be offset 50px from the left edge of the browser window and 100px (150 - 50 = 100) from the right edge of the window. The width of the element gets recalculated on-the-fly as the browser window is resized.

Note that the "expression" syntax is IE-only, so as far as I know, it won't work in Firefox or other browsers. It does work ok in both IE6 and IE7.

Also, use of "expression" relies on Javascript being enabled; in the example above, if Javascript is disabled, the rectangle doesn't render on the screen at all.