Positioning and Layout of Controls
Related topics: Web Application Flow · Managing Web Control Visibility
Layout: Windows vs. Web
Where it makes perfect sense to have absolute coordinate positioning of controls on Windows, the Web operates differently. Due to the nature of HTML and CSS, x/y coordinate positioning should be used sparingly. Instead, DataFlex offers three distinct ways of positioning controls inside a web interface: Panels, Flow Layout and Grid Layout.
Panels are often used as a top-level way of organizing and designing your interface. Inside containers (including Panels) you will then use either Flow or Grid Layout.
Panels
cWebPanel objects can be used to divide the layout of your view or dialog into regions: top, bottom, left, right and center. Set the peRegion property to determine which region a web panel will occupy.
The following image illustrates a web view that is divided into Top, Bottom, Left, Right and Center panels. Each panel then contains a single cWebLabel control.

The source code required to create this view is shown below:
Object oPanelView is a cWebView
Set psCaption to "Multi Panel View"
Set piHeight to 300
Set piWidth to 300
Object oTopPanel is a cWebPanel
Set peRegion to prTop
Set psBackgroundColor to "Blue"
Object oTopLabel is a cWebLabel
Set psCaption to "Top"
Set psBackgroundColor to "#AAAAFF"
Set peAlign to alignCenter
End_Object
End_Object
Object oCenterPanel is a cWebPanel
Set psBackgroundColor to "Orange"
Object oCenterLabel is a cWebLabel
Set psCaption to "Center"
Set psBackgroundColor to "#FFDDAA"
Set peAlign to alignCenter
Set pbFillHeight to True
End_Object
End_Object
Object oLeftPanel is a cWebPanel
Set peRegion to prLeft
Set psBackgroundColor to "#4343FB"
Set piWidth to 60
Object oLeftLabel is a cWebLabel
Set psCaption to "Left"
Set psBackgroundColor to "#AAAAFF"
Set peAlign to alignCenter
Set pbFillHeight to True
End_Object
End_Object
Object oRightPanel is a cWebPanel
Set peRegion to prRight
Set psBackgroundColor to "#4343FB"
Set piWidth to 60
Object oRightLabel is a cWebLabel
Set psCaption to "Right"
Set psBackgroundColor to "#AAAAFF"
Set peAlign to alignCenter
Set pbFillHeight to True
End_Object
End_Object
Object oBottomPanel is a cWebPanel
Set peRegion to prBottom
Set psBackgroundColor to "Blue"
Object oBottomLabel is a cWebLabel
Set psCaption to "Bottom"
Set psBackgroundColor to "#AAAAFF"
Set peAlign to alignCenter
End_Object
End_Object
End_Object
- Set the
piHeightproperty to set the height (in pixels) of top and bottom panels. - Set the
piWidthproperty to set the width (in pixels) of left and right panels. - Set the
pbResizableproperty toTruefor left, right, top or bottom panels to enable a “splitter” bar that allows the height of top/bottom panels or the width of left/right panels to be resized at run time.
Panel objects can contain one or more control objects (such as cWebButton or cWebForm). The controls are contained within the panels and each panel organizes its controls into a separate Flow Layout.
Rules when using panels:
cWebPanelobjects cannot be siblings of web control objects such ascWebButtonorcWebForm. Place web controls inside yourcWebPanelobjects.- Each sibling
cWebPanelmust belong to a different region. For example, acWebViewcannot have two top panels or two bottom panels as direct child objects. - Each set of sibling
cWebPanelobjects must contain one (and only one) center panel (i.e.peRegion = prCenter). This ensures the panels can correctly divide and occupy all of the space provided by their parent container. Top, bottom, left and right panels are optional.
Sub Panels
You can create more complex panel layouts by declaring a set of cWebPanel objects inside an existing panel (sub-panels).
The following image illustrates the previous view where the right panel has been subdivided into right-top, right-center, and right-bottom.

The source code required to modify the right panel from the previous example:
Object oRightPanel is a cWebPanel
Set peRegion to prRight
Set piWidth to 60
Object oRightTopPanel is a cWebPanel
Set peRegion to prTop
Set psBackgroundColor to "Red"
Object oRTLabel is a cWebLabel
Set psBackgroundColor to "#FFAAAA"
Set psCaption to "RT"
Set peAlign to alignCenter
End_Object
End_Object
Object oRightCenterPanel is a cWebPanel
Set psBackgroundColor to "Red"
Object oRCLabel is a cWebLabel
Set psBackgroundColor to "#FFAAAA"
Set psCaption to "RC"
Set peAlign to alignCenter
Set pbFillHeight to True
End_Object
End_Object
Object oRightBottomPanel is a cWebPanel
Set peRegion to prBottom
Set psBackgroundColor to "Red"
Object oRBLabel is a cWebLabel
Set psBackgroundColor to "#FFAAAA"
Set psCaption to "RB"
Set peAlign to alignCenter
End_Object
End_Object
End_Object
The same rules that apply when dividing a view into panels also apply when dividing a panel into sub-panels. There is no technical limit to how many layers of sub-panels you can create; however, more than two levels of sub-panel division is usually of little practical use.
Flow Layout
Within Flow Layout, controls flow naturally from the top-left to the bottom-right of a container. The order of your controls within a container is the order in which they appear in your code.
Columns in Flow Layout
To regulate the size and flow-positioning of controls, a container can be divided into any number of equal-width columns. Each child control will be positioned in its designated column and the control’s width will occupy one or more column widths.
Columns provide a fast and simple way to vertically align controls and to ensure that control widths line up evenly to fixed positions.
The following image illustrates a view where the horizontal position and widths of cWebForm controls fit into a view’s column layout.

Column Count
Set the piColumnCount property of the cWebView, cWebPanel or any other container object to determine how many columns it is divided into.
- Fewer columns make it easier and faster to reorganize layout.
- More columns provide more choices for precise position and size.
- Best practice: a column count of 12 provides a good balance of configurability and simplicity.
Control Position and Width
- Set
piColumnIndexto determine which column the control occupies. Column numbering starts at 0. By default each control'spiColumnIndexis 0 (left-most column). - Set
piColumnSpanto determine the width of a control (and its label) as the number of layout columns it spans. By default, most controls'piColumnSpanis 0, which means it spans all available columns. - For controls with a label (e.g.
cWebForm), the width of the control includes the width occupied by its label. UsepiLabelOffsetto adjust the amount of space occupied by a control’s label (in pixels). SetpiLabelOffset < 120to reduce the label width, or> 120to increase the label width.
Example code for the column layout shown above:
Object oColumnLayout is a cWebView
Set piWidth to 600
Set psCaption to "Column Layout View"
Set piColumnCount to 3
Object oWebForm1 is a cWebForm
Set piColumnSpan to 1
Set psLabel to "Web Form 1:"
Set piLabelOffset to 90
End_Object
Object oWebForm2 is a cWebForm
Set piColumnSpan to 1
Set piColumnIndex to 1
Set psLabel to "Web Form 2:"
Set piLabelOffset to 90
End_Object
Object oWebForm3 is a cWebForm
Set piColumnSpan to 1
Set piColumnIndex to 2
Set psLabel to "Web Form 3:"
Set piLabelOffset to 90
End_Object
Object oWebForm4 is a cWebForm
Set piColumnSpan to 1
Set psLabel to "Web Form 4:"
Set piLabelOffset to 90
End_Object
Object oWebForm5 is a cWebForm
Set piColumnSpan to 2
Set piColumnIndex to 1
Set psLabel to "Web Form 5:"
Set piLabelOffset to 90
End_Object
Object oWebForm6 is a cWebForm
Set piColumnSpan to 3
Set psLabel to "Web Form 6:"
Set piLabelOffset to 90
End_Object
End_Object
Notes and rules:
- The
piColumnIndexof a control cannot exceed the number of columns in the parent view or panel. RememberpiColumnIndexis 0-based (e.g. forpiColumnCount = 9, validpiColumnIndexis 0–8). - If two consecutive controls have the same
piColumnIndexthey will occupy the same column; flow layout rules determine whether one is above the other based on declaration order. - To place two consecutive controls on the same row, set the second control's
piColumnIndexto a value >= the first control’spiColumnIndex + piColumnSpan.
When you display a web view in the Studio’s WebApp Designer and select a web object in the Code Explorer, you can see the column index and column span occupied by that object.

Grid Layout
Introduced in DataFlex 2023, Grid Layout leverages CSS Grid to provide more control over vertical positioning. Controls position themselves on a grid that you configure at container level. Controls can be assigned specific rows and columns, granting fine-grained control over their exact positions.
Setting up your grid: rows and columns
Switch a container to Grid Layout by setting peLayoutType to ltGrid. This exposes additional properties for configuring rows and columns.
Row-related properties
piRowCount-
Sets the minimal number of rows to display in the container. If controls span more rows than specified, additional rows are automatically generated.
-
psRowHeights - Format:
ROWINDEX/VALUE ROWINDEX/VALUE ... - Example:
1/75 3/1fr 4/20% - Allows custom row heights to be specified, overriding the default row height.
- Accepted values:
- Exact pixel values (e.g.
50) - Percentages (e.g.
20%) - Fractions (e.g.
1fr,4fr) - Advanced clauses (e.g.
minmax(),max-content) — see CSS Grid documentation for more details: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout
- Exact pixel values (e.g.
-
Note: CSS Grid is 1-based in standard CSS, but the DataFlex Grid Layout implementation is 0-based.
-
piDefaultRowHeight - Default:
20(pixels) - Sets the default minimum row height for rows not specified via
psRowHeights. Default-height rows claim this minimum pixel height and can grow according to their content. - Accepted formats: pixels, percentages, fractions, and advanced CSS Grid clauses (see above).
Column-related properties
piColumnCount-
Works the same as in Flow Layout.
-
psColumnWidths - Format:
COLUMNINDEX/VALUE COLUMNINDEX/VALUE ... - Example:
1/75 3/1fr 4/20% -
Allows custom column widths to be specified, overriding the default column width. Accepted values are the same types as for rows (pixels, percentages, fractions, advanced CSS Grid clauses).
-
psDefaultColumnWidth - Default:
1fr - Sets the default width value for columns not specified via
psColumnWidths. The default1frcauses each unspecified column to be the same width (similar to Flow Layout). Accepted formats: pixels, percentages, fractions, advanced CSS Grid clauses.
Refer to the CSS Grid documentation for advanced sizing options: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout
Placing Your Controls
After configuring the grid, position controls by assigning them to specific cells. The relevant properties:
piRowIndex- Default:
-1 -
Positions the control at the specified row index on the grid. If not set, CSS Grid will attempt to fill gaps automatically. Note: DataFlex Grid Layout is 0-based.
-
piRowSpan -
Causes a control to span multiple rows. Whether the control visibly fills the spanned rows depends on its height or
pbFillHeight. -
piColumnIndex - Default:
-1 -
Positions the control at the specified column index on the grid. If not set, CSS Grid will attempt to fill gaps automatically. Note: DataFlex Grid Layout is 0-based.
-
piColumnSpan -
Causes a control to span one or more columns. Unlike Flow Layout where
0can mean "span remaining space", in Grid Layout0causes the control to occupy one column (use explicit span values to span more). -
pbFillHeight - If
True, the control attempts to size its height to its allocated rows (fills the assigned rows). CombinepbFillHeightwith rows defined as fractions (e.g.1fr) to achieve fill behavior similar to Flow Layout. - If
False, the control attempts to retain its natural height, determined by CSS,piHeight,piMinHeight, or a combination.
Grid or Flow?
Both Grid and Flow have their place:
Use Flow when you: - Want controls to flow naturally from top-left to bottom-right as ordered in code - Want containers to dynamically size to their content (useful with fill-height controls) - Want gaps in layout to fill naturally when showing/hiding controls or for mobile displays
Use Grid when you: - Want more control over vertical positioning - Want controls to align horizontally by respecting row heights - Want to dictate exact control positions
You can mix Flow and Grid. For example, a View can use Flow Layout and contain groups that each use Grid Layout.
Visual WebApp Designer
A visual designer is available for Flow, Grid and Panels. The WebApp Designer can be shown/hidden via the Studio's View menu or by pressing F7.
- Controls are selected by clicking; the selected control is highlighted with a blue outline.
- In Flow Layout, moving controls shows a black marker indicating the drop position. Controls can be moved inside the designer or dragged from the class palette onto the designer.
- In Grid Layout, a Grid Overlay icon appears in the top-right of the container selection box. The overlay lets you set up and configure the container’s grid. When moving a control over a Grid container, the overlay highlights the cells the control will claim.
- In Grid Layout, controls have a different selection box. Move using the drag handle; drop to update
piColumnIndexandpiRowIndex. Resize via the bottom-right icon to updatepiColumnSpanandpiRowSpan.
For more on the designer, see: WebApp Designer
Previous Topic: Web Application Flow
Next Topic: Managing Web Control Visibility