Skip to content

02 Basic Element Positioning

ZenonSeth edited this page Jun 12, 2025 · 2 revisions

Element properties

Every physical element has 6 basic properties that determine its position and size:
The 4 sides : Top, Bottom, Start, End and its width and height.

Aligning to parent

By default, if no horizontal or vertical alignments are specified, elements assume toStart and toTop of parent:

respec.Form({
    ver = 5, w = 6, h = 4, paddings = 0.1,
  }, {
    elem.Button {
      text = "This button is aligned\ntoTop, toStart"
      -- with no horizontal or vertical alignment, the button assumes toStart and toTop to be the defaults
      -- this is the same as defining:
      -- toTop = true, toStart = true
    },
  })

Results in:

image

And if we add specific alignments:

respec.Form({
    ver = 5, w = 6, h = 4, paddings = 0.1,
  }, {
    elem.Button {
      text = "This button is aligned\ntoBottom, toEnd",
      toBottom = true, -- aligns the bottom of this button to the bottom of the parent container
      toEnd = true, -- aligns the end of this button to the end of the parent container
    },
})

We get:

image

Ordering elements

Elements can also be positioned relative to each other. In order to do that, the element to which you need to align needs to have an id set, which must be unique.

Elements can be ordered by specifying these values in their specification:

  • below = "other_id" - aligns the top of this element to the bottom of "other_id"
  • above = "other_id" - aligns the bottom of this element to the top of "other_id"
  • after = "other_id" - aligns the start (left side) of this element to the end (right side) of "other_id"
  • before = "other_id" - aligns the end of this element to the start of "other_id"

For example:

  elem.Button { id = "btn_topstart", -- this is important - id is used below to align. IDs also have other uses
    text = "This button is aligned\ntoTop, toStart"
  },
  elem.Button { id = "btn_below",
    text = "This button is aligned\nbelow the top-start button",
    below = "btn_topstart"
  },
  elem.Button { id = "btn_after",
    text = "This button is aligned\nafter the top-start button",
    after = "btn_topstart"
  },

Results in:

image

Note that horizontal and vertical alignments are separate. If for example, in the above we change the 3rd button to be after the 2nd button, like so:

  elem.Button { id = "btn_after",
    text = "This button is aligned\nafter the below button",
    after = "btn_below" -- changed!
  },

We get:

image

Note that the 3rd button's start is now aligned horizontally with the end of the 2nd button, but vertically the 3rd button still assumes alignment to top.

Aligning elements

What if we wanted to align the 3rd button form above vertically with the 2nd (the "below") button too? That's where alignments come in.

  • alignTop = "other_id": Aligns the top of this element with the top of "other_id"
  • alignBottom = "other_id": Aligns the bottom of this element with the bottom of "other_id"
  • alignStart = "other_id": Aligns the start (left) of this element with the start of "other_id"
  • alignEnd = "other_id": Aligns the end (right) of this element with the end of "other_id"

So if we also add alignTop to the third button like so:

  elem.Button { id = "btn_after",
    text = "This button is aligned\nafter the below button",
    after = "btn_below", alignTop = "btn_below",
  },

We now get:

image

Element Margins

Lastly, each element can also have margins around itself. Note that the above elements are practically touching each other (their bounds actually are, but buttons are drawn slightly inwards, so visually it doesn't look like it. We can add margins to each element using one or more of the following properties:

  margins = 4, -- sets all margins to 4
  marginsHor = 5, -- sets both start and end margins to 5
  marginsVer = 3, -- sets both top and bottom margins to 3
  marginStart = 1, -- sets start margin to 1
  marginEnd = 1, -- sets the end margin to 1
  marginTop = 1, -- sets the top margin to 1
  marginBottom = 1, -- sets the bottom margin to 1

In addition to that, instead of specifying margins per-element, we can also specify defaultElementMargins in the form's config to apply to all elements within the form:

  defaultElementMargins = 3, -- sets all four default margins to 3
  defaultElementMargins = { hor = 4, ver = 2 } -- sets before/after margins to 4 and above/below ,margins to 2
  defaultElementMargins = { before = 3, after = 3, above = 3, below = 4 } -- sets the default margins to given values

For example, taking the same code as before, but adding this to the Form's config:

  defaultElementMargins = { hor = 0.2, ver = 0.1 }

We get:

image

Note that if any element has specific margins set, they will be used instead of the defaultElementMargins

Clone this wiki locally