Motivation
Since Toolkit 5, laying out components wanted to be much easier, without resorting to CustomLayouts?. This basically meant "Layout extends Sizeable", which led to various battles between developers and designers inside IT Mill :)
Since the early prototypes (initially developed by Joonas in autumn of 2007) proved out to be too sticky to implement. The "Layout extends Sizeable" was dropped for a while from development. But now is back again, with new prototypes to prove it's possible!
So let's get started!
Spec bits
All layouts should be sizable. This means that with OrderedLayouts? and GridLayouts? all cells are sized by dividing the whole layout size with the number of components in it, and not calculated relative to content size.
If a layout has a specified size, which implies specified cell sizes, contains components that are bigger than their container cells, the component get clipped. As simple as that. It is the responsibility of the user/designer to make the layout work as intended.
Prototype 1 (OrderedLayout?, vertical)
Since the initial prototype with TABLE elements and table-layout:fixed seemed to be unreliable in several cases (mainly in Safari and IE7), we decided to have two different implementation, depending on the browser (one for standards compliant browsers and another for IE, surprise surprise). This shouldn't be considered as a big issue, since both prototypes seem to work extremely reliably.
Second, these layouts should behave as progressive enhancements, adding complexity only when it's necessary. In most basic cases layouts should be as simple in Toolkit 4.
First, the standards version
It starts with a container, as usual, but the big difference is that we use relative positioning. This container acts as the sizer if any size is specified. Otherwise it will just wrap the contained cells.
<div style="position:relative; height:100%; width:100%; overflow:hidden;"> </div>
Then, if layout margins have been applied, another container is inserted to provide them (here a 15px margin). This container uses absolute positioning, which has great benefits when sizing the component.
<div style="position:relative; height:100%; width:100%; overflow:hidden;"> <div style="position:absolute; top:15px; bottom: 15px; left:15px; right:15px;"> </div> </div>
Then come the actual layout cells. The only calculations the implementation has to make in JavaScript? are the percentage heights of the cells. The reason why the cells use absolute positioning is that we can eliminate any possible 1px rounding errors which might come from the percentage heights.
<div style="position:relative; height:100%; width:100%; overflow:hidden;"> <div style="position:absolute; top:15px; bottom: 15px; left:15px; right:15px;"> <div style="position:absolute; top:0; height:33.3%; overflow:hidden; width:100%;">Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</div> <div style="position:absolute; top:33.3%; height:33.3%; overflow:hidden; width:100%;">Dolor sit amet</div> <div style="position:absolute; top:66.6%; bottom:0; overflow:hidden; width:100%;"><button>Click Me</button></div> </div> </div>
Spacings are implemented simply by adding another element inside the layout cells. Alignments are implemented also simply with an added one-cell TABLE.
Note by Matti: 3 component layout with spacings on -> actual component area will not be equal
Then onto the IE version
It also starts with a container element, which looks exactly as the earlier version, except for the static positioning:
<div style="height:100%; width:100%; overflow:hidden;"> </div>
Then comes a little bit of magic. IE proprietary expressions! The layout margins and dimensions get calculated from inline css straight into the layout cells, no other wrapper element necessary:
<div style="height:100%; width:100%; overflow:hidden;"> <div style="height:expression((this.parentNode.offsetHeight-30)/3); margin: 15px 15px 0 15px; overflow:hidden;">Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</div> <div style="height:expression((this.parentNode.offsetHeight-30)/3); margin: 0 15px 0 15px; overflow:hidden;">Dolor sit amet</div> <div style="height:expression((this.parentNode.offsetHeight-30)/3); margin: 0 15px 0 15px; overflow:hidden;"><button>Click Me</button></div> </div>
Spacings are now easy to implement also, provided that we know the pixel values of the (same goes for the margins). Simply reduce the spacing values from the equations (10px here between cells, which amounts to 20px total) and add necessary margins to specific cells (all but first):
<div style="height:100%; width:100%; overflow:hidden;"> <div style="height:expression((this.parentNode.offsetHeight-30-20)/3); margin: 15px 15px 0 15px; overflow:hidden;">Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</div> <div style="height:expression((this.parentNode.offsetHeight-30-20)/3); margin: 10px 15px 0 15px; overflow:hidden;">Dolor sit amet</div> <div style="height:expression((this.parentNode.offsetHeight-30-20)/3); margin: 10px 15px 0 15px; overflow:hidden;"><button>Click Me</button></div> </div>
Alignments are done similarly as with standards version, adding a one-cell TABLE is enough.
See working examples: std-vertical.html | ie-vertical.html
Prototype 2 (OrderedLayout? horizontal)
The horizontal versions are mostly identical to the vertical ones, only in other direction. Keep in mind, though, that these implementations are to provide behaviors only when needed. Without e.g. size set, the layouts should fall back to simpler implementation (sprint team can decide whether or not they want to use these protos as default implementations in all cases).
Standards version
<div style="position:relative; height:100%; width:100%; overflow:hidden;"> <div style="position:absolute; top:15px; bottom: 15px; left:15px; right:15px;"> <div style="position:absolute; left:0; width:33.3%; height:100%; overflow:hidden;">Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</div> <div style="position:absolute; left:33.3%; width:33.3%; height:100%; overflow:hidden;">Dolor sit amet</div> <div style="position:absolute; left:66.6%; right:0; height:100%; overflow:hidden;"><button>Click Me</button></div> </div> </div>
IE version Some mods are needed. Both width and height need to be calculated, and display:inline is needed to cure IE6-double-float-margin bug.
<div style="height:100%; width:100%; overflow:hidden;"> <div style="height:expression((this.parentNode.offsetHeight-30)); width:expression((this.parentNode.offsetWidth-30-20)/3); margin:15px 0 0 15px; float: left; display:inline; overflow:hidden;">Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</div> <div style="height:expression((this.parentNode.offsetHeight-30)); width:expression((this.parentNode.offsetWidth-30-20)/3); margin:15px 0 0 10px; float: left; display:inline; overflow:hidden;">Dolor sit amet</div> <div style="height:expression((this.parentNode.offsetHeight-30)); width:expression((this.parentNode.offsetWidth-30-20)/3); margin:15px 0 0 10px; float: left; display:inline; overflow:hidden;"><button>Click Me</button></div> </div>
See working examples: std-horizontal.html | ie-horizontal.html
One more "ultimate" proto for IE, testing nested layouts and alignments, with programmatic build also: vertical-horizontal-ie.html
Attachments
-
std-vertical.html
(1.8 kB) - added by Jouni Koivuviita
8 months ago.
Vertical OrderedLayout? implemtation proto for standards compliant browsers.
-
ie-vertical.html
(1.8 kB) - added by Jouni Koivuviita
8 months ago.
Vertical OrderedLayout? implemtation proto for IE.
- std-horizontal.html (1.8 kB) - added by Jouni Koivuviita 8 months ago.
- ie-horizontal.html (1.1 kB) - added by Jouni Koivuviita 8 months ago.
- vertical-horizontal-ie.html (6.3 kB) - added by Jouni Koivuviita 8 months ago.
