Table of Contents

Layout directives

Layout directives are special attributes which can be used on template nodes in order to apply a specific layout behavior.

  • An invalid value is rejected when the template is generated. A bound value or a constant (@Constants.Class.Name) is not checked: giving a valid value is the responsibility of the developer. A bound value that becomes empty (null or '') removes the effect of its directive.
  • On an action or menu button, layout:visibility and the alignments apply to the whole control, the sizes, the padding and the margin to its buttons.
  • A directive written on the usage of a UI component (or of a UI view embedded with ui-view) applies to the root element of its template and replaces the same directive written there, including a size, an alignment or a visibility. A bound value of the usage that becomes empty leaves the value of the root. When the template has several root elements, or a repeat or a modal at its root, the directives of the usage apply to each of them, with a generation warning: wrap the content in a single layout.
  • The LayoutOverflowFix option of the cluster changes the effect of layout:width and layout:height.

Each directive below is described the same way: its values, then Rendering examples, a schema showing the same element with several values of the directive (written under each frame), then one or more Examples of templates, each followed by its Result when it helps. In the schemas, each dashed frame stands for the parent of the element (a horizontal-layout or a vertical-layout): the element with the directive is colored, its neighbors are grey.

Width

Sets the width of the element.

Directive name : layout:width

Values :

Value Effect
n Sets the width of the element to n pixels (n is an integer).
n% Sets the width of the element to n percent of the width of its parent (n can be decimal, e.g. 33.33%).
fill Adapts its width to fill the remaining horizontal space of its parent.
auto Adapts its width to its content.

Rendering examples, in a horizontal-layout:

A
B
80
A
B
50%
A
B
fill
A
B
auto

Example :

<form-field property-name="CustomerName" layout:width="250" />

In this example, the rendered form-field element should have a width of 250px.

Like a width in pixels, a width in percent is kept as is: the parent neither shrinks nor grows the element, even when the result is wider than the parent. This makes it possible, for example, to place two pages side by side in a strip twice as wide as the visible area. The strip needs space="none" and wrap="false": with the default space between the pages, the two halves no longer fit on one line and the second page wraps below the first.

<horizontal-layout space="none" wrap="false" layout:width="200%">
  <vertical-layout layout:width="50%">...</vertical-layout>
  <vertical-layout layout:width="50%">...</vertical-layout>
</horizontal-layout>

Min-Width

Sets the minimum width of the element.

Directive name : layout:min-width

Values :

Value Effect
n Set the minimum width of the element to n pixels (n is an integer).
n% Set the minimum width of the element to n percent of the width of its parent (n can be decimal, e.g. 33.33%).

The element is never narrower than this width, and grows beyond it when its content or its own layout:width needs more.

Rendering examples:

B
without
B
100: never narrower than 100 pixels

Example :

<form-field property-name="CustomerName" layout:min-width="200" />

In this example, the rendered form-field element should have at least a width of 200px.

Max-Width

Sets the maximum width of the element.

Directive name : layout:max-width

Values :

Value Effect
n Set the maximum width of the element to n pixels (n is an integer).
n% Set the maximum width of the element to n percent of the width of its parent (n can be decimal, e.g. 33.33%).

The element is never wider than this width: a text inside it goes to the next line instead.

Rendering examples:

A long name
without
A long name
60: never wider than 60 pixels

Example :

<form-field property-name="CustomerName" layout:width="fill" layout:max-width="400" />

In this example, the rendered form-field element fills the width of its parent, but never goes beyond 400px.

Height

Sets the height of the element.

Directive name : layout:height

Values :

Value Effect
n Sets the height of the element to n pixels (n is an integer).
n% Sets the height of the element to n percent of the height of its parent (n can be decimal, e.g. 33.33%).
fill Adapts its height to fill the remaining vertical space of its parent.
auto Adapts its height to its content.

Rendering examples, in a vertical-layout:

A
B
40
A
B
fill
A
B
auto

Example :

<form-field property-name="CustomerName" layout:height="40" />

In this example, the rendered form-field element should have a height of 40px.

Note

A height in percent only applies when the height of the parent does not depend on its content (a parent with a height in pixels, in percent, or fill). When the parent adapts its height to its content, the element behaves as if its height was auto.

Note

If the element height is set to fill and the element preferred size (i.g., the sum of all its children minimum size) is greater than the available space, a vertical scroll will be available.

Warning

If the element height is set to fill and its parent height is also set to fill, you should also add the layout:min-height directive on the element to be sure that its content will not be shrunk if there is not enough available space.

Min-Height

Sets the minimum height of the element.

Directive name : layout:min-height

Values :

Value Effect
n Set the minimum height of the element to n pixels (n is an integer).
n% Set the minimum height of the element to n percent of the height of its parent (n can be decimal, e.g. 33.33%).

The element is never lower than this height, and grows beyond it when its content needs more.

Note

Like a height in percent, a minimum height in percent only applies when the height of the parent does not depend on its content (a parent with a height in pixels, in percent, or fill). When the parent adapts its height to its content, the minimum is ignored: use a value in pixels instead.

Rendering examples:

A
B
without
A
B
56: never lower than 56 pixels

Example :

<vertical-layout layout:height="fill" layout:min-height="300">
  <datagrid />
</vertical-layout>

In this example, the rendered vertical layout fills the height of its parent, but never becomes lower than 300px, even in a small window.

Max-Height

Sets the maximum height of the element.

Directive name : layout:max-height

Values :

Value Effect
n Set the maximum height of the element to n pixels (n is an integer).
n% Set the maximum height of the element to n percent of the height of its parent (n can be decimal, e.g. 33.33%).

The element is never higher than this height. When its content needs more, the content goes past the bottom edge of the element and stays visible, over what follows it: add style:overflow to cut it (hidden) or to make it scroll (auto).

Note

Like a height in percent, a maximum height in percent only applies when the height of the parent does not depend on its content (a parent with a height in pixels, in percent, or fill). When the parent adapts its height to its content, the maximum is ignored: use a value in pixels instead.

Rendering examples:

A content on three lines of text
C
without
A content on three lines of text
C
30: the content goes past the edge
A content on three lines of text
C
30 with style:overflow="hidden"

Example :

<vertical-layout layout:max-height="200" style:overflow="auto">
  <repeat values="@Fields.Comments">
    <text>$Item.Text</text>
  </repeat>
</vertical-layout>

In this example, the rendered vertical layout grows with its comments up to 200px, then a scroll bar lets the user reach the following ones.

Margin

Sets the margin of the element.

Directive name : layout:margin

Values : none, extrasmall, small, medium, large, extralarge

Give 1 to 4 values separated with spaces, in the order of the CSS margin property: 1 value for all sides, 2 values for top and bottom then right and left, 3 values for top, then right and left, then bottom, 4 values for top, right, bottom then left. For example, layout:margin="small medium" sets a small margin on top and bottom and a medium margin on right and left.

The margin is an empty space around the element: it pushes away its neighbors and the edges of its parent. The actual size of each value comes from the theme: the sizes in the schemas below are only indicative.

Rendering examples, in a horizontal-layout:

A
B
C
none
A
B
C
medium
A
B
C
large none small none

Examples :

<form-field property-name="CustomerName" layout:margin="medium" />

In this example, the rendered form-field element should have medium margin on all sides.

<form-field property-name="CustomerName" layout:margin="large none small none" />

In this example, the rendered form-field element should have a large margin on top side, a small margin on bottom side, and no margin for the other sides.

Padding

Sets the padding of the element.

Directive name : layout:padding

Values : the same as layout:margin, 1 to 4 values in the order of the CSS padding property.

The padding is an empty space inside the element, between its edges and its content (shown with a dashed outline): the element grows around its content. As for the margin, the sizes in the schemas below are only indicative.

Rendering examples:

Content
none
Content
medium
Content
large none small none

Examples :

<form-field property-name="CustomerName" layout:padding="large" />

In this example, the rendered form-field element should have large padding on all sides.

<form-field property-name="CustomerName" layout:padding="large none small none" />

In this example, the rendered form-field element should have a large padding on top side, a small padding on bottom side, and no padding for the other sides.

Align self horizontal

Specifies the element's horizontal alignment if its parent is a vertical or horizontal layout.

Directive name : layout:align-self-horizontal

Values :

  • left : The element horizontally aligns to the left boundary of its parent (default).
  • right : The element horizontally aligns to the right boundary of its parent.
  • center : The element horizontally aligns at the center of its parent.
  • stretch : The element stretches horizontally to match its parent's width.

Rendering examples, in a vertical-layout:

A
B
left
A
B
center
A
B
right
A
B
stretch
Warning

In the large majority of cases, horizontal alignment must be set on the parent <vertical-layout> or <horizontal-layout>. The layout:align-self-horizontal directive must only be used in the very rare cases where one specific element inside a <vertical-layout> or <horizontal-layout> must be aligned in a different way than its siblings.

Example :

<group-box>
  <form-field property-name="CustomerName" />
  <form-field property-name="Address" layout:align-self-horizontal="right" />
  <form-field property-name="ZipCode" layout:align-self-horizontal="@Fields.ZipAlign" />
</group-box>

In this example, the CustomerName form field should stay left aligned whereas the Address form field should align to the right of the group box. The ZipCode form field should also align according to the ZipAlign field value.

In a canvas layout, this directive aligns a child differently from the default alignment of the canvas.

Align self vertical

Specifies the element's vertical alignment if its parent is a vertical or horizontal layout.

Directive name : layout:align-self-vertical

Values :

  • top : The element vertically aligns to the top boundary of its parent (default).
  • bottom : The element vertically aligns to the bottom boundary of its parent.
  • center : The element vertically aligns at the center of its parent.
  • stretch : The element stretches vertically to match its parent's height.

Rendering examples, in a horizontal-layout:

A
B
top
A
B
center
A
B
bottom
A
B
stretch
Warning

In the large majority of cases, vertical alignment must be set on the parent <vertical-layout> or <horizontal-layout>. The layout:align-self-vertical directive must only be used in the very rare cases where one specific element inside a <vertical-layout> or <horizontal-layout> must be aligned in a different way than its siblings.

Example :

<horizontal-layout>
  <form-field property-name="CustomerName" />
  <form-field property-name="Address" layout:align-self-vertical="bottom" />
  <form-field property-name="ZipCode" layout:align-self-vertical="@Fields.ZipAlign" />
</horizontal-layout>

In this example, the CustomerName form field should stay top aligned whereas the Address form field should align to the bottom of the horizontal layout. The ZipCode form field should also align according to the ZipAlign field value.

In a canvas layout, this directive aligns a child differently from the default alignment of the canvas.

Rendered size

Writes the size actually rendered for the element into a bound field, computed or property, and keeps it up to date on every layout change.

layout:width and layout:height state what the element should be. layout:rendered-size reports what the element actually is, once the layout has been computed.

Directive name : layout:rendered-size

The value must be bound. It designates what the size is written into, and must be of type GroupeIsa.Neos.Designer.UIAbstractions.IUIElementSize, which carries the rendered Width and Height of the element in pixels, as decimal values. The size is the element's border box: padding and border are included, margin is not.

Since the directive only writes into the value, the value must be assignable: binding it to a computed without setter, or to a UI view property that is not settable (nested property, or property with a getter and no setter), is a template validation error.

Example :

# UIViewFields
- Name: ContainerSize
  DotNetDataType: GroupeIsa.Neos.Designer.UIAbstractions.IUIElementSize?
<vertical-layout layout:width="fill" layout:padding="medium" layout:rendered-size="@Fields.ContainerSize">
  <datagrid />
</vertical-layout>

In this example, the ContainerSize field always holds the current size of the vertical layout, and the template can bind to @Fields.ContainerSize.Width or @Fields.ContainerSize.Height.

Result, in a window where the vertical layout is 160 pixels wide and 100 pixels high:

datagrid
ContainerSize.Width = 160, ContainerSize.Height = 100 (padding included)

To run UI code on every size change instead of only storing the size, use the event:resize directive. Both directives report the same size through the same mechanism, so an element uses one or the other, never both at once.

Warning

If the layout only needs to adapt to the viewport size and not to one specific container, prefer using @Viewport in UI template or Window.Current.Viewport in UI code.

Visible

Specifies the element's visibility.

Unlike the <if> node, the element will be mounted. If the visibility of the element can change frequently, it is better to use this directive instead of the <if> node for better performance.

This directive is equivalent to CSS display: none / display: block. When set to false, the element is completely removed from the layout and does not take up any space.

Directive name : layout:visible

Values :

  • true : The element is visible.
  • false : The element is hidden and removed from the layout (equivalent to CSS display: none).

Rendering examples, in a horizontal-layout:

A
B
C
true
A
C
false: C takes the place of B

Example :

<horizontal-layout layout:visible="false">
  <form-field property-name="CustomerName" />
  <form-field property-name="Address" />
  <form-field property-name="ZipCode" />
</horizontal-layout>

In this example, the horizontal layout is hidden and does not take up any space in the layout.

Visibility

Specifies the element's visibility behavior.

This directive provides fine-grained control over element visibility and layout behavior, offering three distinct modes.

Directive name : layout:visibility

Values :

  • visible : The element is visible and occupies space in the layout (default).
  • hidden : The element is invisible but still occupies space in the layout (equivalent to CSS visibility: hidden).
  • collapsed : The element is invisible and does not occupy space in the layout (equivalent to CSS display: none), even when layout:visible is true.

Rendering examples, in a horizontal-layout (the dashed outline shows the space kept by a hidden element, which is not drawn):

A
B
C
visible
A
B
C
hidden: B keeps its place
A
C
collapsed: C takes the place of B

Example :

<horizontal-layout>
  <form-field property-name="CustomerName" />
  <form-field property-name="Address" layout:visibility="hidden" />
  <form-field property-name="ZipCode" layout:visibility="collapsed" />
  <form-field property-name="Phone" layout:visibility="@Fields.PhoneVisibility" />
</horizontal-layout>

In this example:

  • CustomerName is visible (default behavior)
  • Address is hidden but still takes up space in the horizontal layout, creating a gap
  • ZipCode is collapsed and does not take up any space in the layout
  • Phone visibility is determined by the PhoneVisibility field value

Result, when PhoneVisibility is visible:

CustomerName
Address
Phone
Note

Relationship with layout:visible directive:

  • layout:visible="false" is equivalent to layout:visibility="collapsed"
  • layout:visible="true" is equivalent to layout:visibility="visible"

Use layout:visibility when you need the three-state behavior, or layout:visible for simple show/hide scenarios.

Warning

Do not use both layout:visible and layout:visibility on the same element. Using both directives simultaneously may result in unpredictable behavior. Choose one directive based on your needs.

Lazy visible

Specifies whether the element should be mounted only when it becomes visible for the first time.

Use this directive when the element is expensive to initialize and may stay hidden for a while. Unlike layout:visible, the element is not mounted until the value becomes true.

After the element has been mounted once, subsequent visibility changes behave like layout:visible: the element stays mounted and is shown or hidden without being recreated.

Directive name : layout:lazy-visible

Values :

  • true : The element is mounted and visible.
  • false : The element is not mounted yet. If it has already been mounted once, it is hidden and removed from the layout.

The rendering is the same as for layout:visible: only the moment the element is created changes.

Example :

<vertical-layout layout:lazy-visible="@Fields.ShowAdvancedSection">
  <form-field property-name="Address" />
  <form-field property-name="ZipCode" />
</vertical-layout>

In this example, the advanced section is not mounted until ShowAdvancedSection becomes true for the first time. After that first display, the section remains mounted and is only shown or hidden according to the field value.

Warning

layout:lazy-visible is not supported on elements rendered inside a repeat node. The directive is ignored in that context. Use layout:visible, layout:visibility, or <if> depending on whether you need toggling or conditional creation.

Note

Relationship with other visibility mechanisms:

  • Use layout:lazy-visible when initial rendering should be deferred until first display.
  • Use layout:visible or layout:visibility when the element should always be mounted and only toggled in the layout.
  • Use the <if> node when the element must be created and destroyed each time the condition changes.

See also