Layout Properties
Each component has a particular visual appearance by default; this default display is often the best the component can have in a particular context.
However, as you change an application's layout, you may need to change some visual properties of components.
Layout properties allow you to set up the visual appearance of components on a component instance basis.
This code snippet renders a text:
<App>
<Text>I'm a Text without explicit layout properties</Text>
</App>
This sample explicitly sets a few layout properties of Text:
<App>
<Text
backgroundColor="cyan"
width="320px"
padding="2rem">
I'm a Text with explicit layout properties
</Text>
</App>
In this article, you will learn about available layout properties. Before treating them, learn how to use layout properties correctly to avoid unnecessary maintenance chores.
Proper Use of Layout Properties
Layout properties are easy to use; adding simple property values can quickly change the visuals of a particular component.
However, this ease comes at a high price: the more individual layout properties there are, the more tedious the application maintenance is if you need to change the app's appearance.
Whenever possible, avoid using layout properties on component instances. If you use them frequently, maintaining them may lead to a nightmare, as you might need to change many occurrences of a particular layout property value in the app. XMLUI offers straightforward tools to avoid the maintenance nightmare: use reusable components and themes.
In this section, you will learn how to use this toolset.
App with Layout Properties
In the following example, all properties of the HStack
and CHStack
components are layout properties. Some of them set dimensions; others set colors or other style elements:
<App>
<HStack height="100%">
<CHStack border="1px dotted blue" color="black" width="80px" height="40px">Black</CHStack>
<CHStack backgroundColor="red" color="white" width="80px" height="40px">Red</CHStack>
<CHStack backgroundColor="blue" color="white" width="80px" height="40px">Blue</CHStack>
<CHStack backgroundColor="purple" color="white" width="80px" height="40px">Purple</CHStack>
<CHStack backgroundColor="green" color="white" width="80px" height="40px">Green</CHStack>
</HStack>
</App>
Also, the height
property of HStack
is a layout property. However, its "100%" value represents a layout constraint (use the full application height for the stack), so it is not likely to change.
If you need to change the dimensions of boxes (80 x 40 pixels is not the right size), you need to modify the width
and height
properties for all CHStack
instances.
App with Reusable Components
Reusable components may help such maintenance nightmares. You can extract the common style traits of individual components into a reusable component.
To remove the pain of setting all width
and height
occurrences in the previous example (when using layout properties), define a reusable component instead. This new component will be called MyBox
with preset dimension values. However, border and color values are allowed to be changed from the outside via properties:
<Component name="MyBox">
<CHStack
border="{$props.border}"
backgroundColor="{$props.bgColor}"
color="{$props.color}"
width="80px" height="40px">
<Slot />
</CHStack>
</Component>
Now, with the MyBox
component, the previous UI declaration is more straightforward:
<App>
<HStack height="100%">
<MyBox border="1px dotted blue" color="black">Black</MyBox>
<MyBox bgColor="red">Red</MyBox>
<MyBox bgColor="blue">Blue</MyBox>
<MyBox bgColor="purple">Purple</MyBox>
<MyBox bgColor="green">Green</MyBox>
</HStack>
</App>
Let's assume, we need to change the dimensions from 80x40 to 60x60 pixels. Altering the width
and height
properties within MyBox
has its effect on all boxes:
<Component name="MyBox">
<CHStack
border="{$props.border}"
backgroundColor="{$props.bgColor}"
color="{$props.color ?? 'white'}"
width="60px" height="60px">
<Slot />
</CHStack>
</Component>
App with Theme Variables
XMLUI uses themes. A theme is a set of theme variables with their actual values, which influence an app's appearance. A single app can be shipped with multiple themes; users can select their current theme from the available ones.
You can extract the values of layout properties into theme variables. For example, the hard-wired dimensions of MyBox
can be put into theme variables:
<Component name="MyBox">
<CHStack
border="{$props.border}"
backgroundColor="{$props.bgColor}"
color="{$props.color}"
width="$width-MyBox"
height="$height-MyBox">
<Slot />
</CHStack>
</Component>
A $
prefix in a layout property value indicates that the value will be obtained from a theme variable.
Here, $width-MyBox
and $height-MyBox
declare two theme variables. When you build and deploy an app, you can set these theme variables in a theme definition. When you change that definition, the app will update the layout properties referencing the altered theme variables.
Changing the dimensions of MyBox
is pretty straightforward by setting the appropriate theme variables:
{
// ... Other theme props omitted
"themeVars": {
// ...
"width-MyBox": "100px",
"height-MyBox": "30px"
// ...
}
}
Dimensions
When the engine renders particular components, it determines their dimensions according to the type of a particular component and its explicitly set dimension properties.
Specifying Dimensions
You can explicitly specify several dimensions of a particular component with the width
, height
, minWidth
, minHeight
, maxWidth
, and maxHeight
layout properties.
The dimension properties use size values, which contain a value and a unit that together determine the actual size. Here are a few examples of size values:
12px
0.25rem
50%
0
125mm
The XMLUI percentage value is relative to the size of the viewport a parent container offers for a particular child element. Here is an example to demonstrate how percentage values are used:
<App>
<HStack>
<Stack width="20%" height="36px" backgroundColor="red" />
<Stack width="40%" height="36px" backgroundColor="green" />
<Stack width="20%" height="36px" backgroundColor="blue" />
</HStack>
<HStack gap="1rem">
<Stack width="20%" height="36px" backgroundColor="red" />
<Stack width="33.3%" height="36px" backgroundColor="green" />
<Stack width="10%" height="36px" backgroundColor="blue" />
</HStack>
</App>
Component Width and Height
You can change the default component width and height with these layout properties:
Prop | Description |
---|---|
width | The width (horizontal dimension) of the component. |
height | The height (vertical dimension) of the component. |
minWidth | The minimum width of an element. It prevents the current value of the width property from becoming smaller than the value specified. |
minHeight | The minimum height of an element. It prevents the current value of the height property from becoming smaller than the value specified. |
maxWidth | The maximum width of an element. It prevents the current value of the width property from becoming larger than the value specified. |
maxHeight | The maximum height of an element. It prevents the current value of the height property from becoming larger than the value specified. |
The following sample demonstrates the width-related properties.
<App>
<VStack width="50%" height="36px" backgroundColor="red" />
<VStack width="30%" minWidth="200px" height="36px" backgroundColor="green" />
<VStack width="75%" minWidth="200px" maxWidth="300px" height="36px" backgroundColor="blue" />
</App>
Resize the screen to see how the sizes of colored boxes change.
Overflow
A component may not fit into the area its parent provides. This is called overflow.
XMLUI provides a few properties to define how a particular component should behave in situations like these.
Individual components, such as Text
, Heading
, and others, provide further techniques to handle overflow.
Property | Description |
---|---|
overflowX | This property defines the overflow strategy when a component horizontally overflows the UI its parent provides. |
overflowY | This property defines the overflow strategy when a component vertically overflows the UI its parent provides. |
Horizontal Overflow
The following example demonstrates how the horizontal overflow property works:
<App>
<VStack width="180px" height="40px" backgroundColor="cyan" overflowX="hidden">
<Text maxLines="1">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
<VStack width="180px" height="40px" backgroundColor="lightgreen" overflowX="scroll">
<Text color="purple" width="1000px">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
<VStack width="180px" height="40px" backgroundColor="silver">
<Text color="purple">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
</App>
Observe the second text's width, which is set to 1000px, to ensure it won't be trimmed and closed with ellipses.
Due to the overflowX="scroll"
setting, you can see a horizontal scrollbar at the bottom of the light green box. The last text has no overflowX
value or width
constraint, so the engine breaks it into multiple lines. As it has no overflowY
value, the engine lets it flow out of its container.
Vertical Overflow
The following example demonstrates how the vertical overflow property works:
<App>
<VStack width="180px" height="40px" backgroundColor="cyan" overflowY="hidden">
<Text maxLines="1">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
<VStack width="180px" height="40px" backgroundColor="lightgreen" overflowY="scroll">
<Text color="purple">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
<VStack width="180px" height="40px" backgroundColor="silver">
<Text color="purple">
This is a long text that probably won't fit entirely in a single line.
</Text>
</VStack>
</App>
Each of the three text fragments is enclosed in a box with a fixed size (180 x 40 pixels). Observe the effect of different overflowY
values. The last box uses no overflowY
, which has the same effect as overflowY="visible"
.
The Box Model
Most components use a rectangular space (or box) their parent container provides. Several layout properties define how the component should use this rectangular space. These properties follow the so-called box model which comes from the CSS model of the same name.
This model works with the following boxes nested in each other (see an example for each underneath the list):
- Component box: The area the parent provides for the component (the size of this box depends on the rendering logic of the parent).
- Margin box: Within the component box, the component may define a margin that surrounds the other boxes of the component. The margin box displays the background (background color) the parent component provides.
- Border box: Within the margin box, the component may have a border with a particular width. Depending on the border pattern (for example, in the case of a dashed or dotted), the component background may be visible under the border.
- Padding box: The component may define a padding surrounding its content. The background of the padding box is set to the component background.
- Content box: This is the rectangular area where the component will render its child components.
The engine defines several layout properties to set up the box model of a particular component. Here is an example:
<App height="100%" backgroundColor="cyan">
<VStack height="85%"
backgroundColor="red"
margin="20px"
padding="60px"
border="8px dashed blue">
<VStack width="100%" height="100%" backgroundColor="green" />
</VStack>
</App>
The point of interest in the code snippet is the red rectangle; the markup contains styling to showcase all parts of the box model:
App
has a cyan background and encompasses the whole app area because its height is set to 100%
and being a block level element, it fills in the available horizontal space as well.
The child with the red background has a margin of 20px
and is smaller than its parent (its height is also 85% of its parent). This child also has a dashed border (border="8 dashed blue"
), and has a padding of 60px
that squishes its own child to occupy less space inside of it (the one with the green background).
Finally, the VStack
with the green background fills in the available content area defined by its parent with the red background.
Margin
Using both margins and paddings complicates layout arrangements due to side effects (such as margin collapse applied by HTML). Though you can use margins when creating your components, use them as a last resort. For most layouts, paddings must be enough.
You can use these properties to define component margins:
Property | Description |
---|---|
margin | Sets the size of the margin area; uses the same value for the left, top, right, and bottom margins. |
marginHorizontal | Sets the size of the horizontal margins (left and right) to the specified value. |
marginVertical | Sets the size of the vertical margins (top and bottom) to the specified value. |
marginLeft | Sets the size of the left margin to the specified value. |
marginTop | Sets the size of the top margin to the specified value. |
marginRight | Sets the size of the right margin to the specified value. |
marginBottom | Sets the size of the bottom margin to the specified value. |
When you decorate a component with multiple properties setting the same margin, the most specific one prevails. For example, marginLeft
overrides marginHorizontal
and margin
.
Border
You can use these properties to define component borders:
Property | Description |
---|---|
border | Sets the value of the border area; uses the same value for the left, top, right, and bottom borders. |
borderLeft | Sets the value of the left border to the specified one. |
borderTop | Sets the value of the top border to the specified one. |
borderRight | Sets the value of the right border to the specified one. |
borderBottom | Sets the value of the bottom border to the specified one. |
When you decorate a component with multiple properties setting the same border segment, the most specific one prevails. For example, borderLeft
overrides border
.
You can also define the rounding of the border through a set of properties:
Property | Description |
---|---|
borderRadius | This property rounds the corners of a component's outer border edge according to the specified value. |
radiusTopLeft | This property rounds the top-left corner of a component's outer border edge according to the specified value. |
radiusTopRight | This property rounds the top-right corner of a component's outer border edge according to the specified value. |
radiusBottomLeft | This property rounds the bottom-left corner of a component's outer border edge according to the specified value. |
radiusBottomRight | This property rounds the bottom-right corner of a component's outer border edge according to the specified value. |
If you set borderRadius
and any other properties, the others overwrite borderRadius
for the particular corner.
Padding
You can use these properties to define component paddings:
Property | Description |
---|---|
padding | Sets the size of the padding area; uses the same value for the left, top, right, and bottom paddings. |
paddingHorizontal | Sets the size of the horizontal padding (left and right) to the specified value. |
paddingVertical | Sets the size of the vertical paddings (top and bottom) to the specified value. |
paddingLeft | Sets the size of the left padding to the specified value. |
paddingTop | Sets the size of the top padding to the specified value. |
paddingRight | Sets the size of the right padding to the specified value. |
paddingBottom | Sets the size of the bottom padding to the specified value. |
When you decorate a component with multiple properties setting the same padding, the most specific one prevails. For example, paddingLeft
overrides paddingHorizontal
and padding
.
Component Appearance
Several layout properties determine the visual appearance of a particular component.
Colors
The engine supports these layout properties to set component colors:
Property | Descrition |
---|---|
backgroundColor | Sets the background color of a component. |
background | (Same as backgroundColor ) |
color | Sets the foreground color of a component's text and text decorations. |
opacity | This property sets the opacity of an element. Opacity is the degree to which the content behind an element is hidden. The value is a number in the range 0.0 to 1.0, inclusive, or a percentage from 0% to 100%. |
Note: Besides these colors, borders and shadows also can declare their display colors.
<App>
<H2 backgroundColor="green" color="white">The Power of Green Economy</H2>
</App>
<App>
<H2 backgroundColor="green" color="white" opacity="0.5">
The Power of Green Economy
</H2>
</App>
Font and Text Properties
Several properties allow you to set the appearance of text elements displayed in the UI:
Property | Descrition |
---|---|
fontFamily | This property specifies a prioritized list of one or more font family names and/or generic family names for the selected component. |
fontSize | This property sets the size of the font. Changing the font size also updates the sizes of the font size-relative length units, such as em, ex, and so forth. |
fontWeight | Sets the weight (or boldness) of the font. The weights available depend on the fontFamily that is currently set. |
fontStyle | This property sets whether a font should be "slanted" using the following values: normal, italic, or oblique. |
letterSpacing | This property sets the horizontal spacing behavior between text characters. This value is added to the natural spacing between characters while rendering the text. Positive values cause characters to spread farther apart, while negative values bring characters closer together. |
textDecoration | This property sets the appearance of decorative lines on text. |
textTransform | This property specifies how to capitalize an element's text. |
userSelect | This property controls whether the user can select text. |
lineHeight | This property sets the height of a line as a number relative to the normal height. For example, 0.5 means half-height; 2 is twice the normal height. It's commonly used to set the distance between lines of text. |
textAlign | This property sets the horizontal alignment of the inline-rendered content (e.g., text) inside its block-rendered parent. |
textAlignLast | This property sets how the last line of a block or a line, right before a forced line break, is aligned. |
<App>
<Text fontFamily="'Courier New', monospace">
This should be monospace
</Text>
<Text fontWeight="bold">
This is bold text!
</Text>
<Text fontStyle="italic" textDecoration="green wavy underline">
This is italic with decoration!
</Text>
</App>
Shadow
You can add shadow effects around a component's frame and set up one or more shadow effects.
<App>
<VStack width="200px" padding="20px" border="2px solid #202020"
boxShadow="12px 12px 5px orangered" >
<Text>This is a box with a shadow around it.</Text>
</VStack>
</App>
Other Layout Properties
A few layout properties are used for miscellaneous purposes.
Content Alignment
Components that lay out their children according to their strategy (such as Stack
, FlowLayout
, and others utilize these properties to influence the rendering logic.
Property | Description |
---|---|
horizontalAlignment | Specifies the horizontal alignment of child component within its parent. |
verticalAlignment | Specifies the vertical alignment of child component within its parent. |
Direction
This property sets the direction of text, table columns, and horizontal overflow. Use rtl
for languages written from right to left (like Hebrew or Arabic), and ltr
for those written from left to right (like English and most other languages). By default, the prop's value is ltr
.
<App>
<Text width="300px" backgroundColor="cyan">
This goes from left to right
</Text>
<Text width="300px" backgroundColor="cyan"
direction="rtl">
This goes from right to left
</Text>
</App>
Gap
Layout components use this property to define the size of space separating child components.
Cursor
This layout property sets the mouse cursor, if any, to show when the mouse pointer is over a particular component.
Orientation
This property specifies a particular component's orientation when displaying its child components.
Z-Index
This layout property sets the z-order of a positioned component and its children. Overlapping components with a larger z-index cover those with a smaller one.