View Margins And Paddings

Each view can have margins and paddings. They help manage spaces between views and inside their content, which makes layouts look neat and visually appealing. To have a better understanding lets describe them visually.

Margins and paddings

Margin determines the outer indent from the view to its neighbors. While the padding sets the padding from the border of the view to its content. View can't have children by itself therefore these attributes play a big role when we start using a container views.

Below is the list of properties responsible for adjusting margin and padding values.

Property Description
"margin" Describe all margins
"padding" Describe all paddings
"margin-left" Left margin
"margin-right" Right margin
"margin-top" Top margin
"margin-bottom" Bottom margin
"padding-left" Left padding
"padding-right" Right padding
"padding-top" Top padding
"padding-bottom" Bottom padding

The main properties are "margin" and "padding." Other properties adjust the values of these two. We can specify one or multiple values for these properties to set all margins and paddings at once. When using a single value, it will apply to all sides of the view, typically the value has SizeUnit type:

Examples

Setting all margins and paddings to the same value from code.

Go

// Setting margins
view.Set(rui.Margin, rui.Px(8))

// Setting paddings
view.Set(rui.Padding, rui.Px(4))

Setting margins and paddings in the view description file.

RUI

ListLayout {
    content = [
        TextView {
            text = "Item 1",
            margin = 8px,
            padding = 4px,
        },
        TextView {
            text = "Item 2",
            margin = 8px,
            padding = 4px,
        },
    ],
}

Another way of setting margins and paddings is to provide multiple values for these properties. In this case properties will hold the value of BoundsProperty interface. To create such interface we use rui.NewBoundsProperty() or rui.NewBounds() global functions. The interface holds four properties of SizeUnit type:

Property Description
"left" Left value
"right" Right value
"top" Top value
"bottom" Bottom value

Example

Setting margins and paddings from code.

Go

view.Set(rui.Margin, rui.NewBoundsProperty(rui.Params {
    rui.Left:   "@leftMargin", // Setting the value by referring to the constant
    rui.Right:  "1.5em",       // Setting the value as a text representation of SizeUnit type
    rui.Top:    rui.Px(8),     // Setting the value in pixels using SizeUnit type
    rui.Bottom: rui.Inch(0.3), // Setting the value in inches using SizeUnit type
}))

view.Set(rui.Padding, rui.NewBoundsProperty(rui.Params {
    rui.Left:   "@leftPadding",  // Setting the value by referring to the constant
    rui.Right:  "0.5em",         // Setting the value as a text representation of SizeUnit type
    rui.Top:    rui.Px(4),       // Setting the value in pixels using SizeUnit type
    rui.Bottom: rui.Inch(0.1),   // Setting the value in inches using SizeUnit type
}))

view.Set(rui.Margin, rui.NewBounds(
    rui.Px(8),     // Top margin, setting the value in pixels using SizeUnit type
    rui.Em(1.5),   // Right margin, setting the value Em using SizeUnit type
    rui.Inch(0.3), // Bottom margin, setting the value in inches using SizeUnit type
    10,            // Left margin, setting the value in pixels using int type
))

view.Set(rui.Padding, rui.NewBounds(
    rui.Px(8),     // Top padding, setting the value in pixels using SizeUnit type
    rui.Em(1.5),   // Right padding, setting the value Em using SizeUnit type
    rui.Inch(0.3), // Bottom padding, setting the value in inches using SizeUnit type
    10,            // Left padding, setting the value in pixels using int type
))

The BoundsProperty interface has its own text representation, which can be used when describing the view from a resource file, it has the following format:

RUI

_{
    left = <value>,
    right = <value>,
    top = <value>,
    bottom = <value>,
}

where <value> could be a text representation of SizeUnit type or a reference to a constant.

Example

Setting margins and paddings from view description file.

RUI

ListLayout {
    content = [
        TextView {
            text = "Item",
            margin = _{
                top = 8px,          // Setting value in pixels
                left = @leftMargin, // Referring to a constant
                right = 1.5em,      // Setting value in em
                bottom = 0.3in,     // Setting value in inches
            },
            padding = _{
                top = 4px,           // Setting value in pixels
                left = @leftPadding, // Referring to a constant
                right = 0.5em,       // Setting value in em
                bottom = 0.1in,      // Setting value in inches
            },
        },
    ],
}

A convenient way of getting "margin" an "padding" properties value is to use a dedicated global functions GetMargin() and GetPadding():

Go

marginBounds := rui.GetMargin(rootView, viewId)
paddingBounds := rui.GetPadding(rootView, viewId)

The values will be returned in a form of the Bounds structure:

Go

type Bounds struct {
    Top, Right, Bottom, Left SizeUnit
}

We can also use a well known Get() method of the view but remember that we have to perform a type conversion and resolve constants manually in this case. To grab the values from BoundsProperty we can use its Bounds() method:

Go

if value := view.Get(rui.Margin); value != nil {
    margin := value.(BoundsProperty)
    values := margin.Bounds()
    // Do something with the values
}

if value := view.Get(rui.Padding); value != nil {
    padding := value.(BoundsProperty)
    values := padding.Bounds()
    // Do something with the values
}

Properties beginning with "margin-" or "padding-" have a SizeUnit type and can also accept constants or text representations of the SizeUnit type.

When setting such properties library will first check for existence of "margin" or "padding" properties, create them when needed and update their values based on supplied values in "margin-..." or "padding-..." properties.

Examples

Setting margins and paddings in the view description file.

RUI

ListLayout {
    content = [
        TextView {
            text = "Item 1",
            margin-left = 8px,
            margin-right = 8px,
            padding-top = 4px,
            padding-bottom = 4px,
        },
        TextView {
            text = "Item 2",
            margin-left = 8px,
            margin-right = 8px,
            padding-top = 4px,
            padding-bottom = 4px,
        },
    ],
}

Setting margins and paddings from code.

Go

// Setting margins
view.Set(rui.MarginLeft, rui.Px(8))
view.Set(rui.MarginRight, rui.Px(12))

// Setting paddings
view.Set(rui.PaddingTop, rui.Px(4))
view.Set(rui.PaddingBottom, rui.Px(4))

Margins are not part of the view shape, which is defined by the "width" or "height" properties. To illustrate this, let's assume that we want to place a view inside a container and create some space between the container's border and the child view. We can achieve this by setting the "margin" property of the child view and specifying its "width" and "height" as 100%:

RUI

GridLayout {
    width= 300px,
    height = 200px,
    content = EditView {
        edit-view-type = multiline,
        // Setting child dimensions
        width = 100%,
        height = 100%,
        margin = 1em, // Setting child margin
    }
}

Since margin does not affect the border or shape of the view we'll have something similar to this:

Margins example 1

Notice that the child view has the same width and height as a parent container but exceeds the parent's dimensions because of the margins. To overcome this issue, we have to somehow specify correct dimensions for the child view that include its margin. The right way to do this is to utilize a function that subtracts margins from these 100% values of the container's width or height:

RUI

GridLayout {
    width= 300px,
    height = 200px,
    content = EditView {
        width = "sub(100%, 2em)", // Subtracting two margins from the parent's width
        height = "sub(100%, 2em)", // Subtracting two margins from the parent's height
        edit-view-type = multiline,
        margin = 1em, // Setting margin
    }
}

This will fit our child view inside the container nicely without any overflow.

Margins example 2

We can use functions like sub() and others to specify property value from the source code as well.

Go

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:  rui.Px(300),
    rui.Height: rui.Px(200),
    rui.Content: rui.NewEditView(session, rui.Params{
        rui.EditViewType: rui.MultiLineText,
        rui.Width:        rui.SubSize(rui.Percent(100), rui.Em(2)), // Subtracting two margins from the parent's width
        rui.Height:       rui.SubSize(rui.Percent(100), rui.Em(2)), // Subtracting two margins from the parent's height
        rui.Margin:       rui.Em(1),                                // Setting margin
    }),
})

For more information on how to use such functions please refer to SizeUnit and SizeFunc reference documentation.

There is also another way to achieve the same result: we can set paddings in the parent container, as padding participates in the width or height calculations of the child view:

RUI

GridLayout {
    width= 300px,
    height = 200px,
    padding = 1em,
    content = EditView {
        width = 100%, // Width of the parent's content area(excluding paddings)
        height = 100%, // Height of the parent's content area(excluding paddings)
        edit-view-type = multiline,
    }
}