Navigation

Stack

<oblyx-stack> is a one-dimensional flex layout: a row or a column of children with a token-based gap between them. Set direction to switch axis;align and justify always mean the cross axis and the main axis respectively, in both directions, so there's no separate horizontal/vertical pair to keep track of.

Basic stack

First
Second
Third
HTMLKotlin
<oblyx-stack gap="2">
  <div class="docs-demo-box">First</div>
  <div class="docs-demo-box">Second</div>
  <div class="docs-demo-box">Third</div>
</oblyx-stack>
oblyxStack(gap = OblyxStackGap._2) {
  div(classes = "docs-demo-box") { +"First" }
  div(classes = "docs-demo-box") { +"Second" }
  div(classes = "docs-demo-box") { +"Third" }
}

Direction

direction defaults to vertical. Setting it to horizontal flips the flex axis; align and justify keep their meaning, they just apply to the other axis now.

Horizontal stack

First
Second
Third
HTMLKotlin
<oblyx-stack direction="horizontal" gap="2">
  <div class="docs-demo-box">First</div>
  <div class="docs-demo-box">Second</div>
  <div class="docs-demo-box">Third</div>
</oblyx-stack>
oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._2) {
  div(classes = "docs-demo-box") { +"First" }
  div(classes = "docs-demo-box") { +"Second" }
  div(classes = "docs-demo-box") { +"Third" }
}

Gap

gap is a step on the spacing token scale, the same scale oblyx-grid and oblyx-layout use. Unset means no gap at all, not a default value. Two of the steps,0 and 0-5, can't be valid Kotlin enum constant names as written (a Kotlin identifier can't start with a digit), so the generated Kotlin API prefixes every step with an underscore: OblyxStackGap._0 and OblyxStackGap._0_5.

Stack gap

gap="0-5"

A
B
C

gap="4"

A
B
C

gap="10"

A
B
C
HTMLKotlin
<oblyx-stack gap="6">
  <div>
    <p class="docs-demo-label">gap="0-5"</p>
    <oblyx-stack direction="horizontal" gap="0-5">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">gap="4"</p>
    <oblyx-stack direction="horizontal" gap="4">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">gap="10"</p>
    <oblyx-stack direction="horizontal" gap="10">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
</oblyx-stack>
oblyxStack(gap = OblyxStackGap._6) {
  div {
    p(classes = "docs-demo-label") { +"gap=\"0-5\"" }
    oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._0_5) {
      div(classes = "docs-demo-box") { +"A" }
      div(classes = "docs-demo-box") { +"B" }
      div(classes = "docs-demo-box") { +"C" }
    }
  }
  div {
    p(classes = "docs-demo-label") { +"gap=\"4\"" }
    oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._4) {
      div(classes = "docs-demo-box") { +"A" }
      div(classes = "docs-demo-box") { +"B" }
      div(classes = "docs-demo-box") { +"C" }
    }
  }
  div {
    p(classes = "docs-demo-label") { +"gap=\"10\"" }
    oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._10) {
      div(classes = "docs-demo-box") { +"A" }
      div(classes = "docs-demo-box") { +"B" }
      div(classes = "docs-demo-box") { +"C" }
    }
  }
}

Cross-axis alignment

align positions children along the cross axis (horizontal, for the default vertical direction) when they don't already fill it.

Stack align

align="start"

A
BB

align="center"

A
BB

align="end"

A
BB
HTMLKotlin
<oblyx-stack gap="4">
  <div>
    <p class="docs-demo-label">align="start"</p>
    <oblyx-stack align="start" gap="2" class="docs-demo-frame" style="width: 220px;">
      <div class="docs-demo-box" style="width: 60px;">A</div>
      <div class="docs-demo-box" style="width: 120px;">BB</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">align="center"</p>
    <oblyx-stack align="center" gap="2" class="docs-demo-frame" style="width: 220px;">
      <div class="docs-demo-box" style="width: 60px;">A</div>
      <div class="docs-demo-box" style="width: 120px;">BB</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">align="end"</p>
    <oblyx-stack align="end" gap="2" class="docs-demo-frame" style="width: 220px;">
      <div class="docs-demo-box" style="width: 60px;">A</div>
      <div class="docs-demo-box" style="width: 120px;">BB</div>
    </oblyx-stack>
  </div>
</oblyx-stack>
oblyxStack(gap = OblyxStackGap._4) {
  div {
    p(classes = "docs-demo-label") { +"align=\"start\"" }
    oblyxStack(align = OblyxStackAlign.START, gap = OblyxStackGap._2) {
      classes = setOf("docs-demo-frame")
      style = "width: 220px;"
      div(classes = "docs-demo-box") { style = "width: 60px;"; +"A" }
      div(classes = "docs-demo-box") { style = "width: 120px;"; +"BB" }
    }
  }
  // align="center" and align="end" follow the same shape.
}

Main-axis alignment

justify distributes children along the main axis when they leave extra space.start, center, end, between,around and evenly are all available; the example below shows a representative three.

Stack justify

justify="start"

A
B
C

justify="between"

A
B
C

justify="evenly"

A
B
C
HTMLKotlin
<oblyx-stack gap="4">
  <div>
    <p class="docs-demo-label">justify="start"</p>
    <oblyx-stack direction="horizontal" justify="start" gap="2" class="docs-demo-frame" style="width: 320px;">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">justify="between"</p>
    <oblyx-stack direction="horizontal" justify="between" gap="2" class="docs-demo-frame" style="width: 320px;">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
  <div>
    <p class="docs-demo-label">justify="evenly"</p>
    <oblyx-stack direction="horizontal" justify="evenly" gap="2" class="docs-demo-frame" style="width: 320px;">
      <div class="docs-demo-box">A</div>
      <div class="docs-demo-box">B</div>
      <div class="docs-demo-box">C</div>
    </oblyx-stack>
  </div>
</oblyx-stack>
oblyxStack(gap = OblyxStackGap._4) {
  div {
    p(classes = "docs-demo-label") { +"justify=\"start\"" }
    oblyxStack(direction = OblyxStackDirection.HORIZONTAL, justify = OblyxStackJustify.START, gap = OblyxStackGap._2) {
      classes = setOf("docs-demo-frame")
      style = "width: 320px;"
      div(classes = "docs-demo-box") { +"A" }
      div(classes = "docs-demo-box") { +"B" }
      div(classes = "docs-demo-box") { +"C" }
    }
  }
  // justify="between" and justify="evenly" follow the same shape.
}

Wrap

wrap="wrap" lets children flow onto additional lines instead of overflowing or shrinking past their content size. Defaults to nowrap, matching upstream.

Stack wrap

One
Two
Three
Four
HTMLKotlin
<oblyx-stack direction="horizontal" wrap="wrap" gap="2" class="docs-demo-frame" style="width: 220px;">
  <div class="docs-demo-box">One</div>
  <div class="docs-demo-box">Two</div>
  <div class="docs-demo-box">Three</div>
  <div class="docs-demo-box">Four</div>
</oblyx-stack>
oblyxStack(direction = OblyxStackDirection.HORIZONTAL, wrap = OblyxStackWrap.WRAP, gap = OblyxStackGap._2) {
  classes = setOf("docs-demo-frame")
  style = "width: 220px;"
  div(classes = "docs-demo-box") { +"One" }
  div(classes = "docs-demo-box") { +"Two" }
  div(classes = "docs-demo-box") { +"Three" }
  div(classes = "docs-demo-box") { +"Four" }
}

Stack item

<oblyx-stack-item> is an optional per-item wrapper for children that need their own grow or alignment behavior. It's not required: plain content and oblyx-stack-item children compose freely inside the same stack.size="fill" lets one item grow to absorb remaining space along the main axis while the rest stay pinned to their content size.

Stack item size

Static Fill (grows) Static
HTMLKotlin
<oblyx-stack direction="horizontal" gap="2" class="docs-demo-frame" style="width: 320px;">
  <oblyx-stack-item class="docs-demo-box">Static</oblyx-stack-item>
  <oblyx-stack-item size="fill" class="docs-demo-box">Fill (grows)</oblyx-stack-item>
  <oblyx-stack-item class="docs-demo-box">Static</oblyx-stack-item>
</oblyx-stack>
oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._2) {
  classes = setOf("docs-demo-frame")
  style = "width: 320px;"
  oblyxStackItem { classes = setOf("docs-demo-box"); +"Static" }
  oblyxStackItem(size = OblyxStackItemSize.FILL) { classes = setOf("docs-demo-box"); +"Fill (grows)" }
  oblyxStackItem { classes = setOf("docs-demo-box"); +"Static" }
}

align-self overrides the parent stack's align for one item only.

Stack item align-self

Default align-self="end"
HTMLKotlin
<oblyx-stack direction="horizontal" gap="2" class="docs-demo-frame" style="height: 80px;">
  <oblyx-stack-item class="docs-demo-box">Default</oblyx-stack-item>
  <oblyx-stack-item align-self="end" class="docs-demo-box">align-self="end"</oblyx-stack-item>
</oblyx-stack>
oblyxStack(direction = OblyxStackDirection.HORIZONTAL, gap = OblyxStackGap._2) {
  classes = setOf("docs-demo-frame")
  style = "height: 80px;"
  oblyxStackItem { classes = setOf("docs-demo-box"); +"Default" }
  oblyxStackItem(alignSelf = OblyxStackItemAlignSelf.END) { classes = setOf("docs-demo-box"); +"align-self=\"end\"" }
}

Reference

<oblyx-stack>

AttributeTypeDefaultDescription
directionhorizontalverticalverticalFlex axis.
gap00-511-523456810Gap between children, as a spacing-token step. Unset means no gap.
alignstartcenterendstretchCross-axis alignment.
justifystartcenterendbetweenaroundevenlyMain-axis alignment.
wrapnowrapwrapwrap-reversenowrapFlex-wrap.

<oblyx-stack-item>

AttributeTypeDefaultDescription
sizestaticfillstatic'static' (default) pins the item to its content size (no grow, no shrink); 'fill' lets it grow to absorb remaining space along the main axis. Mirrors upstream StackItemSize.
align-selfstartcenterendstretchPer-item override of the parent stack's cross-axis alignment. Mirrors upstream StackItemCrossAlignSelf. Unset defers to the parent's own align.