Skip to content

WPanel FlowLayout

Mark Reeves edited this page Jan 3, 2018 · 9 revisions

FlowLayout is a component layout mechanism for WPanel. It is used to place WComponents into a WPanel with a particular spatial arrangement. The arrangements are described in Layout configuration.

Diagram information

In the diagrams illustrating the various settings for FlowLayout the FlowLayout contains a set of WComponents each of which has a border; this is done to provide easy recognition of the flow boundaries. All of the added WComponents are natively block elements which should occupy the full width of the parent container. Finally a full width horizontal rule is included to indicate the bounds of the parent container.

Wrapping

If a horizontal flow extends further than the bounds of the parent container components will wrap at inter-component boundaries. No attempt is made to control the wrap point.

In horizontal flows a component will shrink horizontally to its smallest wrap point. This may lead to some interesting effects, especially in Internet Explorer prior to version 10.

Wrapping can be turned off (i.e. set to nowrap) by setting a HTML class attribute value on the WPanel to which the FlowLayout is applied.

// given a WPanel noWrappingFlowPanel:
// and this WPanel has a FlowLayout LEFT, CENTER or RIGHT
noWrappingFlowPanel.addHtmlClass("wc-flex-nowrap");

Layout configuration

Alignment

The layout alignment determines how the components added to the FlowLayout will be presented in the UI.

Available settings for this property are:

  • VERTICAL in which all components occupy the full width of the available space and are, therefore, arranged vertically;

    FlowLayout with align VERTICAL

  • LEFT in which components are placed side by side and left aligned relative to the parent container;

    FlowLayout with align LEFT

  • RIGHT in which components are placed side by side and right aligned relative to the parent container;

    FlowLayout with align RIGHT

  • CENTER in which components are placed side by side and center aligned relative to the parent container.

    FlowLayout with align CENTER

Vertical alignment

Horizontal flows may have the relative vertical alignment of its content determined. This property specifies the vertical alignment of cells relative to the parent container. This property allows for more refined layouts. This applied to all FLowLayouts but is only noticeable if the align property is not VERTICAL. The default vertical alignment is TOP. If any other vertical alignment is required it must be explicitly included in the UI specification for each FlowLayout specified.

Available settings for this property are:

  • TOP which aligns all components to the top of the parent container. This is the default alignment if a valign property is not specified.

    FlowLayout with valign TOP

  • MIDDLE which aligns the middle of the bounding box of each component in the FlowLayout to the middle of the bounding box of the parent container. This setting is very useful if each cell consists of a single line component but those components are of varying heights, for example a flow of a label, a dingle line text input and a button.

    FlowLayout with valign MIDDLE

  • BASELINE which aligns the text box baseline of the bottom-most text box of each component in the FlowLayout to the text box baseline of the parent container. This setting is the most suitable for most component flows where the components each occupy a single vertical line. Flows of interspersed text, images, icons, progress bars etc may be best suited to this setting.

    FlowLayout with valign BASELINE

  • BOTTOM which aligns the bottom of the bounding box of each component in the FlowLayout to the bottom of the bounding box of the parent container. It is unlikely that you will really need this setting but flows of images, especially charts and graphs, would benefit from this vertical alignment.

    FlowLayout with valign BOTTOM

Layout spacing

FlowLayout uses an optional gap property to put space between components in the flow. To place space around a FLowLayout use the containing WPanel's Margin. The default for any flow is to not apply any space between components. Any required space must be specified in the UI specification.

When the alignment is VERTICAL the gap is applied to the top of each component cell in the list excluding the first. Otherwise the gap is applied to the left of each cell other than the first. If the ListLayout components wrap the left gap is still applied. No attempt is made to calculate wrap points and allow for this. See Theme intra component spacing for details of how gaps are applied.

The illustrations below show different flow alignments with gaps.

  • align LEFT

    FlowLayout with align LEFT and gap

  • align RIGHT

    FlowLayout with align RIGHT and gap

  • align CENTER

    FlowLayout with align CENTER and gap

  • align VERTICAL

    FlowLayout with align VERTICAL and gap

Inconsistent spacing due to "empty" cells

If a FlowLayout contains a WComponent which is not included in the current render then it will contain an empty cell for that WComponent. These genuinely empty cells are not output into the HTML and therefore have no impact on inter-component spacing determined by gap.

If, however, any WComponents without UI artefacts are added directly to the FlowLayout each of these will occupy a cell. The cell is then not empty and a wrapper element is added to the HTML output but that wrapper element will be empty. This may cause unusual or erroneous layout issues and is discussed in more detail in WComponents without UI artefacts.

Known issues with FlowLayout

This section is mainly concerned with limitations in FlowLayout but is also relevant to considerations of column layouts, WFieldLayout and other layouts which include horizontal arrangement of elements.

FlowLayout is a layout mechanism for WPanel and is very familiar to Java UI developers. From the point of view of a web UI a FlowLayout can be used to place elements which would otherwise be block elements into a horizontal flow; or, conversely, place elements with inline or inline-block layout into a vertical arrangement.

Horizontal FlowLayout cells are elastic

Each component added to a FlowLayout occupies once cell in the layout. WComponents may be grouped into a single cell using a WContainer.

Each cell of a horizontal FlowLayout will shrink-wrap to its contents. This can have a significant effect if the component is one which calculates its size as a proportion of the available space, such as a WField (when added to the flow as part of a WFieldLayout), or those with no specified width but with a maximum width set to 100% or less for overflow control (such as WDropdown in modern browsers).

The cells of a FlowLayout do not attempt overflow control and replaced content elements (form controls and images for example) may overflow the bounds of a cell if that cell's wrap point is smaller than the replaced widget.

Determining the wrap point of a cell

Determining the wrap point is not arithmetically complex but does require detailed knowledge of the content of the cell. It is imperative that proper information architecture and data analysis is done before undertaking UI design so that the space required for labels, data display, form input fields (especially single or multiple HTML select elements) and images is known.

As a rule of thumb a horizontal FlowLayout cell will be as small as possible. If a cell contains text content the wrap point will be the longest unspaced word in the cell. If a cell contains sized content (such as a WFieldLayout with layout FLAT) then the cell's size is a little more complex. The inner component will calculate its size determined by its own wrap point. If it is then a complex sized control like WFieldLayout or ColumnLayout the relative sizes of the individual parts of the component are determined based on the smallest pixel size of any explicitly sized control or, if there are no explicitly sized controls, the size is split in the correct proportions according to the user agents rendering algorithm. In practice this means that at least one 'column' of the internal layout (usually the one with the largest unwrappable content) will be no bigger than the size of its longest unwrappable piece of non-replaced content in that 'column' and any other 'columns' in that component will be sized proportionally according to the sizing paradigm of the component. This rather obscure situation is probably best illustrated with an example:

Overflow and wrap point in a FlowLayout cell

Overflow and wrap point example screenshot

In the illustration above the FlowLayout cell contains a WFieldSet and that then contains a WFieldLayout. The WFieldSet is there just to show the boundaries of the cell as WFieldLayout is not visible in the UI.

The WFields in the WFieldLayout have a label:input split of 1:1 (50% each). The longest piece of non-wrapping, non-replaced content is the word "component"; therefore the 'column' containing that word is sized to that word (plus the padding of the WFieldSet). The WFieldLayout has a 1:1 split and therefore the left 'column' is the same width and the total size of the FlowLayout cell is determined by this. Adding replaced-content elements (in this case three WTextField components) which are larger than the computed size of their container results in them overflowing.

Wrapping content within a cell

If the output of a horizontal FlowLayout cell contains more than one HTML element each inter-node juncture is a potential wrap point. There is no ability to control non-whitespace specific inter-node wrapping in HTML.

Within an element each word boundary and word-node boundary is a potential wrap point unless the whitespace is controlled (using CSS or   spacing). Word-node and node-node boundaries may ignore whitespace directives and implement inter-node wrapping.

In the illustration above the WRadioButtonSelect which outputs the radio buttons labelled circle, square and triangle is supposed to be FLAT but is suffering from inter-node wrapping at each label:input boundary. Each label is kept with its radio button as far as possible but this situation cannot be guaranteed in all cases.

Controlling overflow and cell size

You cannot control overflow or cell size in a horizontal FlowLayout.

Cells wrap at container boundaries

The cells in a horizontal FlowLayout will wrap when they come to the edge of the parent WPanel. The wrap point is between cells and therefore is determined by the cell content. This is inter-node wrapping in HTML and cannot be prevented. When a flow wraps there is no attempt to determine the wrap point and remove the gap from the wrapped cell. This is because we cannot address the wrap point individually and cannot pre-determine where it will be due to the limitations of the application delivery mechanism.

A (right with gap) horizontal flow with wrapping

Overflow and wrap in right FlowLayout

A (left with gap) horizontal flow with wrapping

Overflow and wrap in left FlowLayout

Hints for specifying FlowLayout

  • Explicitly specify all layouts to prevent application developers from choosing an inappropriate layout.
  • Use FlowLayout sparingly by ensuring your fundamental structural layout components are correct.
  • Remember that two dimension form layouts are less accessible and less usable than vertical form layouts and try to avoid placing multiple controls into a single row.
  • If your components are all inline or inline-block elements a FlowLayout may be unnecessary given judicious use of WText white space separation.

Related Components

Further information

Clone this wiki locally