# StackFrameLayout Distribution Modes in FrameLayoutKit: .top, .center, .bottom, and .fill Explained

> Explore StackFrameLayout distribution modes in FrameLayoutKit: .top, .center, .bottom, and .fill. Learn how to control cross-axis alignment for your UI layouts.

- Repository: [Nam Kennic/framelayoutkit](https://github.com/kennic/framelayoutkit)
- Tags: deep-dive
- Published: 2026-03-05

---

**StackFrameLayout distribution modes control cross-axis alignment, where `.top`, `.center`, and `.bottom` position children at the start, middle, or end of the perpendicular axis, while `.fill` stretches each child to occupy the full cross-axis dimension.**

The `StackFrameLayout` class in the [kennic/framelayoutkit](https://github.com/kennic/framelayoutkit) repository provides the foundation for `HStackLayout` and `VStackLayout`. Understanding the `distribution` property and its four primary modes—`.top`, `.center`, `.bottom`, and `.fill`—is essential for controlling how child views align across the axis perpendicular to the stack's direction.

## Understanding StackFrameLayout Distribution

### The NKLayoutDistribution Enum

The distribution modes are defined in [`FrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayout.swift) as the `NKLayoutDistribution` enum. This enum is consumed by `StackFrameLayout` during its `layoutSubviews()` pass to compute the final `targetFrame` for each child. The enum values map directly to the alignment behavior applied to the cross-axis coordinate.

### How Distribution Affects Layout

When `StackFrameLayout` performs layout, it first calculates the primary axis position (left-to-right for `HStackLayout`, top-to-bottom for `VStackLayout`). The `distribution` property then dictates the cross-axis coordinate:

- For **horizontal stacks**, distribution controls **vertical** alignment.
- For **vertical stacks**, distribution controls **horizontal** alignment.

This axis-specific behavior means the same enum value produces different visual results depending on whether the stack flows horizontally or vertically.

## Distribution Mode Reference

### .top Alignment

The `.top` mode aligns children to the leading edge of the cross-axis.

- **Horizontal stack**: Each child's `targetFrame.origin.y` is set to `containerFrame.minY`, pinning the view to the top of the stack.
- **Vertical stack**: Each child's `targetFrame.origin.x` is set to `containerFrame.minX`, pinning the view to the left.

In [`StackFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/StackFrameLayout.swift), the `.top` case simply assigns the minimum edge coordinate without modifying the child's size.

### .center Alignment

The `.center` mode centers children along the cross-axis.

- **Horizontal stack**: The origin is calculated as `containerFrame.minY + (containerFrame.height - targetFrame.height) / 2`.
- **Vertical stack**: The origin is calculated as `containerFrame.minX + (containerFrame.width - targetFrame.width) / 2`.

This ensures equal padding on both sides of the child view, placing it exactly in the middle of the available cross-axis space.

### .bottom Alignment

The `.bottom` mode aligns children to the trailing edge of the cross-axis.

- **Horizontal stack**: `targetFrame.origin.y = containerFrame.maxY - targetFrame.height`, placing the view at the bottom.
- **Vertical stack**: `targetFrame.origin.x = containerFrame.maxX - targetFrame.width`, placing the view at the right.

The implementation uses `isInvertedAlignment` to handle the `.bottom` and `.right` cases consistently, flipping the origin calculation to the container's maximum edge.

### .fill Expansion

The `.fill` mode overrides the child's cross-axis dimension to match the container's full extent.

- **Horizontal stack**: `targetFrame.origin.y = containerFrame.minY` and `targetFrame.size.height = containerFrame.height`.
- **Vertical stack**: `targetFrame.origin.x = containerFrame.minX` and `targetFrame.size.width = containerFrame.width`.

Unlike the alignment modes, `.fill` modifies the child's size rather than just its position, ensuring every child stretches to fill the available cross-axis space.

## Implementation Details

### layoutSubviews Logic

The core logic resides in `StackFrameLayout.layoutSubviews()`. The method iterates over `frameLayouts` and, based on the current `axis` and `distribution`, computes `targetFrame` for each child.

For example, the `.top` case for a horizontal axis:

```swift
case .top:
    targetFrame.origin.y = containerFrame.minY

```

And the `.fill` case:

```swift
case .fill:
    targetFrame.origin.y = containerFrame.minY
    targetFrame.size.height = containerFrame.height

```

### Axis-Specific Behavior

The same `NKLayoutDistribution` value produces different visual results depending on `axis`:

- **Horizontal axis** (`HStackLayout`): Distribution controls **vertical** positioning.
- **Vertical axis** (`VStackLayout`): Distribution controls **horizontal** positioning.

This is why `.top` in a horizontal stack aligns to the top edge, while in a vertical stack it aligns to the left edge (the "top" of the cross-axis).

## Code Examples

```swift
import FrameLayoutKit

// 1. Top-aligned horizontal stack (items pinned to top)
let topStack = HStackLayout {
    $0.distribution = .top          // ⇢ each item’s top edge touches the stack’s top edge
    $0.spacing = 8
    $0.add(UIView()) // item 1
    $0.add(UIView()) // item 2
}

// 2. Center-aligned horizontal stack (items vertically centered)
let centerStack = HStackLayout {
    $0.distribution = .center
    $0.spacing = 8
    $0.add(UIView())
    $0.add(UIView())
}

// 3. Bottom-aligned horizontal stack (items pinned to bottom)
let bottomStack = HStackLayout {
    $0.distribution = .bottom
    $0.spacing = 8
    $0.add(UIView())
    $0.add(UIView())
}

// 4. Fill distribution (items stretch to full height)
let fillStack = HStackLayout {
    $0.distribution = .fill
    $0.spacing = 8
    $0.add(UIView()) // height will match stack height
    $0.add(UIView())
}

// Vertical stack example – distribution controls horizontal alignment
let vStack = VStackLayout {
    $0.distribution = .center // items centered horizontally
    $0.spacing = 12
    $0.add(UILabel())
    $0.add(UIButton())
}

```

All four horizontal stacks behave identically in the primary direction (left‑to‑right). The only visual difference comes from the chosen `distribution` mode.

## Summary

- **StackFrameLayout distribution modes** determine cross‑axis alignment for children in `HStackLayout` and `VStackLayout`.
- **`.top`** pins children to the start of the cross‑axis (top for horizontal stacks, left for vertical stacks).
- **`.center`** centers children along the cross‑axis with equal padding on both sides.
- **`.bottom`** pins children to the end of the cross‑axis (bottom for horizontal stacks, right for vertical stacks).
- **`.fill`** stretches each child to occupy the entire cross‑axis dimension, modifying the child’s size rather than just its position.

## Frequently Asked Questions

### What is the default distribution mode for StackFrameLayout?

The default value for the `distribution` property is `.top` (or its axis‑appropriate equivalent). This means that unless you explicitly set a different mode, children will align to the top edge in a horizontal stack or the left edge in a vertical stack.

### Does the .fill distribution respect a child view’s intrinsic content size?

No. When you set `distribution = .fill`, `StackFrameLayout` explicitly overrides the child’s cross‑axis dimension to match the container’s full height or width. The child’s intrinsic size is ignored for that axis, although the primary‑axis size (width for horizontal stacks, height for vertical stacks) may still be determined by the child’s content or explicit constraints.

### How does distribution differ from alignment in FrameLayoutKit?

In FrameLayoutKit, **distribution** is a property of `StackFrameLayout` that controls the cross‑axis positioning of multiple children relative to the stack’s bounds. **Alignment** (often handled by individual `FrameLayout` instances or the `alignment` property) typically refers to how a single view’s content is aligned within its own frame. Distribution operates at the stack level; alignment operates at the individual frame level.

### Can I mix distribution modes within the same StackFrameLayout?

No. The `distribution` property is applied uniformly to every child in the stack. If you need different cross‑axis alignments for specific items, you should wrap those items in a nested `FrameLayout` or use a `ZStackLayout` with manual positioning, or compose multiple `StackFrameLayout` instances with different distributions.