## DEV Community

edA‑qa mort‑ora‑y

Posted on • Originally published at mortoray.com

# UI Layout: Natural versus dependent size

Elements have either a natural size, a dependent size, or combination of the two. The size of an element influences its placement. The user and creator of a UI layout system must have shared expectations about sizing.

## A Rectangle

Let's work through the concepts first using a basic `Rectangle`. Without any other specification, a `Rectangle` doesn't have any size. If you were asked, what the natural size of it was, you wouldn't have an answer, or you might potentially answer zero.

Contrast now to a `Rectangle{Width=100 Height=50}`. This rectangle has a fixed size `100,50`. The layout engine can ask for its size, and it will get this value; it knows how big this rectangle is supposed to be.

A layout engine that required everything to have a fixed sized wouldn't be useful. We need a way to give the first plain `Rectangle` a size. Instead of saying it has no size, we define its size relative to its parent. Consider this basic UI tree:

``````Panel{Width=100 Height=100}
Rectangle
``````

We allow the rectangle to expand to the available space: the size of the parent. Our rectangle now has a size of `100,100`. The expanding child is an example of dependent sizing.

It's also convenient to have a partially dependent size, such as in this example:

``````Panel{Width=100 Height=100}
Rectangle{Width=50}
``````

We take the width from the rectangle properties, and the height from the parent, resulting in a size of `50,100`. This type of dependent sizing is common in layout. There is, of course, the issue of where to place that rectangle in the panel now, but we'll get to that later.

## An Image

An image is interesting as it can both have a natural size and a dependent size. Consider an image, `fun.png`, with the dimensions 200x100. The dimensions of the image seem like a reasonable natural size -- the UI engine can ask for the size of the image and get `200,100` as a response.

We have to be careful in interpreting what 200,150 means here. This is the source resolution, but does that line up with device points, pixels, millimetres, or something else? You may also have images suitable for different density displays. A 200x100 image is for a 1:1 pixel-to-point density, whereas a 400x200 may be intended for a 2:1 pixel-to-point density.

Images can also completely stretch to fill their parent.

``````Panel{Width=300 Height=200}
Image{File=fun.png}
``````

The `Image` element will have a size of `300,200`. Now, it's up to the image type itself to decide how to stretch the actual image to fill that area. The difference between an element's size, and the actual size of its contents, will be a recurring concept . (We'll get back to image sizing in a later article)

An image defines a ratio; our 200x100 image has a 2:1 size ratio. This is also good for defining partially dependent sizes. Consider stacking images in a `StackPanel`:

``````StackPanel{Width=300}
Image{File=fun.png}
``````

The parent has a width of 300, and the image is expected to fit inside. In this situation we use the size ratio of 2:1 to come up with a height of 150. This gives the image a reasonable size based on the parent and retains the aspect ratio -- as to not distort the image.

## Text

Text also has a fixed and dependent size, but the relationship is different than an image. Let's first consider a case that doesn't involve soft wrapping: long lines do not wrap around. Absent of wrapping text has a fixed natural size. Sure, it's dependent on the font, but that's part of the properties of the text, not the layout.

``````Text{Font=Arial FontSize=32 Value="Hello"}
``````

The string `Hello` has a fixed size using Arial font at point size 32.

Wrapped text has a dependent size. Consider this example:

``````Panel{Width=200}
Text{Font=Arial FontSize=32 Wrap Value="Welcome a bit longer text that might span multiple lines"}
``````

Given that the parent panel has a width of 200 we'd expect the text not to be wider than 200. When queried for its size the text element will use the knowledge of this width, calculate line wrapping, and come up with a height to cover all the lines.

## Moving on

It's critical to understand natural and dependent sizing to write a UI engine. Here we've only touched on the basic possibilities, defining what this means, and giving the basis for reasoning about size.

In later articles, we'll cover how an element gets its dependency information to calculate its size.

Johannes Vollmer

I think absolute sizes are not suited for layout at all. Allowing only relative sizes simplifies responsive design and encourages the use of layout constructs instead of hard coded dimensions.

edA‑qa mort‑ora‑y

Absolute sizes make sense for laying out things like icons, title bars, profile images, etc. These are things that have an expected size, and aren't expected to get bigger as the device gets bigger. A responsive display should handle other layouts, but as more space becomes available more content should be shown.

For example, you might have a chat bubble that shows a fixed size image (using points), but has a responsive size for the text content.

Or you may have a title bar with fixed icons on both sides, a fixed overall height, but the title text is centered in the remaining space. You wouldn't expect the icons to get bigger with larger screens, or for the title bar height to increase, only that the text remains centered.

Johannes Vollmer

Absolute sizes may make sense for title bars, but do title bars make sense? :P

Nested Software • Edited

This is probably a reasonable idea if you're developing an application, but I would say it's not reasonable if you're making a UI framework. You can be opinionated about your own specific app. But if you're making a framework, and a person using that framework has what they consider to be a valid use-case for absolute sizes, then they won't use your framework if you don't have some way to support what they want.

In general, a framework always has to find some kind of balance between the philosophy of the framework author and the demands of the actual users. I suspect making this work well is not easy in practice: If you're not opinionated enough, you create a kind of kitchen sink of technology that becomes messy and unpleasant to use; if you're too opinionated, you turn people off by telling them "sorry, I know better than you what you need."

edA‑qa mort‑ora‑y

Yes, an engine needs to allow people to be creative and experiment with UX. If it didn't allow this then no progress could ever be made in that area, and the apps would all end up the same, for better or for worse.

Like all frameworks, and languages, this allows people to create bad UI's. I fixed several issues in Fuse found by people doing things I considered a bad design. It's not my job to judge their approach though, rather to find the inconsistency and correct it. Features, of course, were priotized on known use-cases though.