DEV Community

Cover image for UI Layout: Natural versus dependent size
edA‑qa mort‑ora‑y
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.

This article is part of a series on Writing a UI Engine.

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
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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.

Read more articles about writing a UI Engine. Follow me on Twitter or Facebook, and to keep me writing, consider becoming a patron.

Discussion (7)

Collapse
johannesvollmer profile image
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.

Collapse
mortoray profile image
edA‑qa mort‑ora‑y Author

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.

Collapse
johannesvollmer profile image
Johannes Vollmer

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

Collapse
nestedsoftware profile image
Nested Software • Edited on

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."

Collapse
mortoray profile image
edA‑qa mort‑ora‑y Author

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.

Thread Thread
johannesvollmer profile image
Johannes Vollmer • Edited on

Okay, I must confess, a library probably shouldn't prohibit using absolute sizes (but it should not promote them).

But all UI engines allow absolute sizing, so you won't make progress by implementing absolute resizing, just as every other engine already does. :D

Thread Thread
mortoray profile image
edA‑qa mort‑ora‑y Author

Don't worry, I'll be talking lots about responsive layout.