We've seen a lot of features of the box model. Here, we'll find out some more details with some examples.
The style properties such as min-width and max-height can be applied to any element. We've added them to buttons and text inputs, but we can also add them to springs or boxes. In addition, the flex attribute can be applied to any element.
Example 3.4.1
<button value="Left" style="min-width: 100px;" flex="1"/> <spring flex="1"/> <button value="Right" style="min-width: 100px;" flex="1"/> |
In the example above, all three elements will resize themselves as they are all flexible. The two buttons indicate a minimum width of 100 pixels. The buttons will never be smaller than this size but they may grow larger. Here the window should appear just over 200 pixels wide. That's enough for the two buttons. Because all three elements are flexible, but they don't need any more room, the flexibility adds no extra space.
As we've seen, the flex attribute is used to indicate that an element is flexible and that it will resize as necessary. This has mostly been noticed when the window has been resized. However, when there are number of nested boxes -- that is, boxes inside of other boxes -- the flexibility of an element, as well as its style settings, are used to determine the size that they become.
For example, if a box indicates a maximum width of 100 pixels, the box can only be at most 100 pixels wide, even if there are flexible elements inside it. The best way to understand this is to try it out for yourself.
When a series of elements are placed in a horizontal box, the flex attribute specifies the flexibility horizontally. Elements in a horizontal box expand vertically to fill the entire space. You could say that the elements have a vertical flexibility. Similarly, elements in a vertical box have a flex attribute which indicates the flexibility vertically. These elements will expand horizontally to fill the entire space.
As shown in the image above, the earlier example will have the two buttons expand vertically to fit their container, which in this case is the window and a window is a horizontal box by default. The autostretch attribute controls this behaviour. You can also prevent this strecthing by placing a maximum height on the elements or, better, on the box itself. If a box has a maximum height, the elements inside it are constrained by this. However, the problem with this is that you need to know how big the element will be beforehand.
A good solution would be to add some nested boxes, as below:
Example 3.4.2
<box orient="vertical" flex="1"> <box orient="horizontal"> <button value="Left" style="min-width: 100px;" flex="1"/> <spring flex="1"/> <button value="Right" style="min-width: 100px;" flex="1"/> </box> </box> |
Here, two boxes have been added. We need the horizontal one because we want the buttons to orient horizontally. The inner horizontal box is inside a vertical box so it will be oriented vertically. Of course, there's nothing else to orient it with, since this horizontal box is the only element inside the outer box. However, elements inside vertical boxes autostretch horizontally, and not vertically like horizontal boxes. The outer vertical box effectively removes the vertical stretching. However, a vertical box will also orient their children in a column, which isn't what we want. Since we want the buttons to be oriented horizontally, we just add an extra horizontal box inside the other one.
Remember that vertical boxes stretch their children horizontally, so the inner horizontal box here will stretch horizontally. Since the two buttons and the spring are flexible, they will flex to fill the box. Of course, in this simple case, we could have used the autostretch attribute to achieve the same affect with only one box:
Example 3.4.3
<box orient="horizontal" flex="1" autostretch="never"> <button value="Left" style="min-width: 100px;" flex="1"/> <spring flex="1"/> <button value="Right" style="min-width: 100px;" flex="1"/> </box> |
To achieve complicated layouts, you will generally need to add nested boxes, specify minimum and maximum sizes on some elements, and make certain elements flexible. The best interface is one that can be displayed at various sizes without problems. The box model is difficult to understand without trying various various things out for yourself.
The following is an outline of both types of boxes:
You can put boxes anywhere in a XUL file, including inside an HTML element such as a table. However, the layout will be partly controlled by the HTML element. That means that the flex might not work exactly as you want it. Remember that flexibility only has meaning for elements that are directly inside a box (that is, the children of a box). However, you can achieve a similar effect inside an HTML element by setting the width or height style properties to a value of 100% to have full flexibility.
1. Using Springs for Spacing
Example 3.4.4
<button value="One"/> <spring style="width:5px"/> <button value="Two"/> |
Here, a spring is used as a separator between the two buttons, by setting an explicit width of 5 pixels. You could also set margins (using the CSS margin property).
2. Centering a Button
Example 3.4.5
<window id="example-window" title="Example 3.4.4" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <spring flex="1"/> <box orient="vertical"> <spring flex="1"/> <button value="Middle"/> <spring flex="1"/> </box> <spring flex="1"/> </window> |
This window has three elements in it, a spring, a box and another spring. A window is a horizontal box by default so the three elements will be oriented horizontally. The two springs are flexible so they resize as necessary, and equally. The result is that the box is positioned in the middle horizontally. You could right-align the button by removing the last spring, making the first spring use all of the space as it is the only flexible component.
Inside the box is a a spring, a button and another spring. This works in a similar way but, because the box is vertical, the button appears between the two springs in a column. The result is a button that is centred in the window.
3. A Find Text Dialog
Example 3.4.6
<box orient="vertical" flex="3">
<text value="Search Text:"/>
<textfield id="t1" style="min-width: 100px;" flex="1"/>
</box>
<box orient="vertical" style="min-width: 150px;" flex="1">
<checkbox id="c1" value="Ignore Case"/>
<spring flex="1" style="max-height: 30px;"/>
<box>
<button value="Find"/>
</box>
</box>
|
Here, two vertical boxes are created, one for the text field and the other for the check box and button. The left box has a flexiblity that is 3 times greater than the right one so it will always be 3 times its size horiztonally. The right box enforces a minimum width of 150 pixels.
The text field is flexible so it will resize as the window resizes. The text field also enforces a minimum width of 100 pixels. The check box appears in the right box along with its label. Just below the check box is a spring. The spring will grow and shrink but not exceed 30 pixels. The result is that the check box and the Find button will be spaced apart from each other by some space of no more than 30 pixels.
The Find button itself is placed in its own box. Because boxes are horizontal by default, the button does not scale horizontally but vertically. If the button was not put in the box, it would size itself horizontally to fit its container (which in this case is a vertical box). Since we don't want this, we place it in a horizontal box so that the Find button would scale vertically instead. Since this box is not flexible, it only grows to the size that is necessary. The effect is a button that is just the right size.
(Next) Next, we'll learn about a more specialized type of box, the titledbox.
Examples: 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6