Flexible components grow and shrink to fit their given space. Components
with larger flex values will be made larger than components with lower
flex values, at the ratio determined by the two components. The actual
value is not relevant unless there are other flexible components within
the same container. Once the default sizes of components in a box are
calculated, the remaining space in the box is divided among the flexible
components, according to their flex ratios. Specifying a flex value of 0
has the same effect as leaving the flex attribute out entirely.
2 Different Underlying Implementations
ZK 9 implements hflex/vflex in a whole new, more performant way – by
CSS3 flexbox,
which is supported by modern browsers natively. With this change, it
doesn’t calculate an element’s size in javascript thus improving the
client-side performance. This change should be transparent for
developers.
The exceptional case is min, e.g. hflex="min" or vflex="min", which
still sets width by JavaScript.
Fall Back to the Old Way
However, if your application depends on the previous implementation, you
can fall back by the property org.zkoss.zul.css.flex=”false”.
Notice that, if the parent has no predefined size (width/height) (i.e.,
its size is decided by its children), the flexible component won’t take
any space. For example, the inner div (with vflex) in the following
example takes no space:
<div><!--Wrong! The height is required since it is minimal height by default--><dateboxwidth="150px"/><divvflex="1"style="background: yellow"/><!--height will be zero since height not specified in parent div--></div>
To solve it, you have to specify the height in the outer div, such as
<div height="100%">, <div height="200px">, or <div vflex="1">.
Fit-the-Rest Flexibility
The simplest use of flex is to have one component to take the rest of
the space of its parent (or the page, if it is the root component). For
example,
Notice you could specify style="overflow: auto" in the tabpanel such
that the scrollbar will be inside the tabbox rather than the browser
window if the content is too large to fit.
Proportional Flexibility
The absolute value of the vflex/hflex is not that important. It is used
to determine the proportion among flexible components. That is, you can
give different integers to differentiate child components so they will
take space proportionally per the given vflex/hflex value. For example,
Sometimes, you might wish that the parent component’s size is determined
by its children. Or I shall say, the size of the parent component is
just high/wide enough to hold all of its child components. Specifying
vflex/hflex="min" can fulfill this fit-the-content requirement.
<borderlayoutheight="200px"width="400px"><northtitle="North"vflex="min"><borderlayoutvflex="min"><westtitle="West"size="40%"flex="true"vflex="min"><divstyle="background:#B8D335"><labelvalue="40%"style="color:white;font-size:50px"/></div></west><centerflex="true"vflex="min"><divstyle="background:#E6D92C"><labelvalue="60%"style="color:white;font-size:50px"/></div></center></borderlayout></north><center><labelvalue="This is the working area"style="font-size:30px"/></center></borderlayout>
As you can see, the height of the north region of the outer borderlayout
is determined by its child borderlayout. And the height of the inner
borderlayout, in this example, is determined by the height of its west
child region.
Don’t specify Minimum on a parent and 1 on a child
Because min means “calculate the size by its children” and 1 means
“calculate the size by its parent”, this configuration will make 2
components’ size calculation depends on each other and get 0
finally. But there are workarounds, please read the following sections.
Component width within Vlayout/Vbox using minimum hflex
In the case below, we see nothing for the incorrect usage (min on the
parent - vlayout, 1 on the child - div):
However, in the case below, because one of the children, red div has a
fixed width, vlayout can determine its width. So that yellow div can
also determine its width upon its parent, which is 150px.
<vlayout hflex="min" height="75px"> <div hflex="1" vflex="1" style="background: yellow">150px</div> <div width="100px" vflex="1" style="background: cyan">100px</div> <div width="150px" vflex="1" style="background: red">150px</div></vlayout>`</pre></div></td>
</tr>
</tbody>
</table>
### Component height within Hlayout/Hbox using minimum vflex
Normally, if the siblings of yellow **div** have been defined height
correctly, that yellow **div** height should be equal to the **max
height** of siblings, which is 30px in the following sample.
<hlayout width="100px" vflex="min"> <div hflex="1" vflex="1" style="background: yellow">30px</div> <div hflex="1" height="20px" style="background: cyan">20px</div> <div hflex="1" height="30px" style="background: red">30px</div></hlayout>`</pre></div></td>
</tr>
</tbody>
</table>
However, in the following use case, we should see nothing as it is an
incorrect usage:
```xml
```
# Grid's Column and Flexibility
If hflex is specified in the header of
[grid](/zk_component_ref/grid),
[listbox](/zk_component_ref/listbox) and
[tree](/zk_component_ref/tree), it is applied to
the whole column (including the header and contents).
For example, we could assign 33% to the first column and 66% to the
second as follows.
```xml
username:password:
```
The result is

Notice that we also specify `hflex="1"` to the textbox, so it will take
up the whole space.
### Alignment
When we create a form, we will put some input elements in a Grid. We can
set hflex="min" to Grid and each Column to keep Grid with minimal size.
<grid hflex="min"> <columns> <column hflex="min" align="right"/> <column hflex="min"/> </columns> <rows> <row> <label value="Name:"/> <textbox/> </row> <row> <label value="Birthday:"/> <datebox/> </row> </rows></grid>`</pre></div></td>
</tr>
</tbody>
</table>
If we need the Datebox's width the same as Textbox, we can specify
hflex="1" to Datebox.
<grid hflex="min"> <columns> <column hflex="min" align="right"/> <column hflex="min"/> </columns> <rows> <row> <label value="Name:"/> <textbox/> </row> <row> <label value="Birthday:"/> <datebox hflex="1"/> </row> </rows></grid>`</pre></div></td>
</tr>
</tbody>
</table>
### Cell colspan
Sometimes we need to put some elements in cross column, we can put it in
a Cell and set hflex="1" to the element.
<grid hflex="min"> <columns> <column hflex="min" align="right" /> <column hflex="min" /> <column hflex="min" align="right" /> <column hflex="min" /> </columns> <rows> <row> <label value="Name:" /> <textbox/> <label value="Birthday:" /> <datebox/> </row> <row> <label value="Address:" /> <cell colspan="3"> <textbox rows="5" hflex="1"/> </cell> </row> </rows></grid>`</pre></div></td>
</tr>
</tbody>
</table>
For a complete list of controls that you could apply to the columns of
grid, listbox and tree, please refer to [ZK Developer's Reference/UI Patterns/Grid's Columns and Hflex](/zk_dev_ref/ui_patterns/grids_columns_and_hflex).
# Flexibility versus Percentage
The use of hflex and vflex is similar to the use of percentage in width
and height. For example,
```xml
1
2
```
The advantage of percentage is that the performance will be a little
better, since it is done by the browser. However, hflex and vflex are
recommended because of the following issues:
- The use of 100% will cause overflow (and then scrollbar appears if
overflow:auto), if padding is not zero. Moreover, some browsers might
show mysterious scrollbars or overflow the parent's space even if
padding is zero.
- The percentage does *not* work, if any of the parent DOM element does
not specify the width or height.
- The percentage does *not* support *take-the-rest-space*. For example,
the following doesn't work:
```xml
```
## Body Height and Padding
By default, ZK's theme configures the document's BODY tag as follows.
```css
body {
height: 100%;
padding: 0 5px;
}
```
Sometimes you might prefer to add some padding vertically, but it
*cannot* be done by changing BODY's styling as follows.
```css
body {
height: 100%;
padding: 5px; /* WRONG! It causes vertical scrollbar to appear since the 100% height is used with vertical padding */
}
```
As described in the previous section, a vertical scrollbar will appear,
since both the vertical padding and the 100% height are specified.
**Solution**: you shall *not* change the default CSS styling of BODY.
Rather, you could enclose the content with [the div component](/zk_component_ref/div), and then
specify `vflex="1"` and the padding to the div component. For example,
```xml
aaa
```
# Flexibility and Resizing
Vflex and hflex support resizing. If the parent component or the browser
window changes its size to increase or decrease the extra space, the
child components with vflex/hflex will recalculate themselves to
accommodate the new size.
```xml
<![CDATA[
int[] str = new int[100];
for(int i=0;i<100;i++){
str[i]=i;
}
]]>
Top of the Tree
Bottom of the Tree
```
Note that the height proportion between the two trees is always 1 : 2,
when we change the browser height.
# Limitations
## Span Ignores Width and Height
[Span](/zk_component_ref/span) ignores the
width and height, so hflex and vflex have no effect on them (unless you
specify [display:block](http://www.quirksmode.org/css/display.html) --
but it makes it div eventually).
```xml
12
```
And, the result is as follows - the width has no effect:

This limitation can be solved by the use of
[hlayout](/zk_component_ref/hlayout) and
[div](/zk_component_ref/div) as follows.
```xml
1
2
```

## Hflex Must Align Correctly
Hflex will be wrong if a component is not aligned in the same *row* with
its siblings. For example,
```xml
1
2
```
As shown below, the second div is not aligned vertically with the first
div, so is the width not as expected:

This limitation can be solved by use of
[hlayout](/zk_component_ref/hlayout) and
[div](/zk_component_ref/div) as shown in the
previous subsection.
## Input elements have incorrect margin values in WebKit browsers
In WebKit browsers (Chrome, Safari), the left and right margin values of
an input element are considered 2px by browsers, where they are really
0px on screen. This may cause hflex to wrongly handle InputElements like
textbox, intbox, etc. For example, in the following case the Textbox
does not occupy the entire Div width in Chrome:
```xml
```
You can work around this by specifying Textbox margin to be 0:
```xml
```
## Minimum Flexibility Doesn't Change a Component's Size Dynamically
When specifying `min` at `hflex`/`vflex`, ZK only sets a component's
size once at the page creation. The component doesn't change its size
accordingly even if you add or remove its child components (change its
content size). Therefore, if you want to resize the component upon its
content again, please call
[org.zkoss.zk.ui.util.Clients#resize(org.zkoss.zk.ui.Component)](https://www.zkoss.org/javadoc/latest/zk/org/zkoss/zk/ui/util/Clients.html#resize(org.zkoss.zk.ui.Component)).
The same rule applies when you change the content of a parent component
to minimum hflex/vflex, the parent component doesn't resize itself upon
its content. You can need to call
[org.zkoss.zk.ui.util.Clients#resize(org.zkoss.zk.ui.Component)](https://www.zkoss.org/javadoc/latest/zk/org/zkoss/zk/ui/util/Clients.html#resize(org.zkoss.zk.ui.Component)).
For example,
```xml