The Science of Building a UI: Building a Layout (Part 1)

Danielle Cohen
ASICS Digital
Published in
8 min readNov 8, 2019

This blog post is the first of a two-part series that was adapted from a tech talk given to NEU’s WIT group. ADI often engages with the local college community and hires both interns and coops — not just from NEU, so please apply! We also try to participate in programs that serve underrepresented groups in tech, like Hack Diversity and She Geeks Out. If you’re interested in learning more about ASICS Digital, check us out here: https://www.asicsdigital.com/

Software engineering is sometimes broken into two types: “frontend” and “backend.” Frontend engineering involves building User Interfaces (UIs), the screens that end users see and interact with, whereas backend engineering often means building the logic and data layers under the hood.

I’ve occasionally heard people dismiss frontend engineering for a couple reasons:

  • It’s too easy — the backend work is more systems-oriented and thus “technical” than aesthetics-based frontend engineering.
  • Also, it’s too hard — right when you fix the layout on one screen resolution and aspect ratio, it breaks on another. Frontend engineering is more art than science.

Both these reasons are flawed. Not only is frontend engineering very systems-based, it’s also very much a science. Like any other system-based science, frontend engineering can be broken down into components and is guided by well-defined, repeatable rules. The three components of frontend engineering are the layout, the content, and the style.

Layout vs Content vs Style

The layout is where content is arranged on the screen. For example, most blog posts (like this one) have a title anchored at the top of the page. The existence and positioning of this title constitute the layout.

Meanwhile, content is what a user sees. UI content often falls into two categories:

  • Copy: the words
  • Assets: the images

For example, the content of this blog post’s title is “The Science of Building a UI.”

Lastly, the style is how the content is rendered. Style can include:

  • Colors and opacity
  • Font family, size, and weight
  • Shapes (e.g. are the buttons rounded?)
  • Decorations (e.g. are there shadows?)
  • Spacing, padding and margins

For example, the title of this blog post is styled in size 42px Georgia font.

To summarize, if the layout is where content is arranged on a screen, then content is what information a user sees and the style is how it renders.

Layout: “This button goes here.” Content: “This button should say lorem ipsum.” Style: “The button should be pink.”
UI instruction categorized

The Layout

When building a UI, the first thing you’ll need to do is to deconstruct your design into a layout. There are three rules to deconstructing a layout:

  1. Everything is an element.
  2. Elements have relationships to one another.
  3. Elements each need a size and a position.

1. Everything is an element

When looking at a design or mock-up, every distinct thing is an element. For the example pictured below, the background is its own element. The buttons are their own elements. The title is its own elements. The text blocks are their own elements. The carousel that contains the title and text block is also its own element.

Pro-tip #1: pretend every element is a rectangle!

A splash screen is highlighted to show that the buttons, title, and text can be conceptually simplified to be rectangles.

By simplifying your mental model of the design into a series of rectangles next to one another and within one another, you can reduce the noise that would otherwise distract you from constructing the layout itself.

2. Elements have relationships to one another.

There are two kinds of relationships that elements can have to one another:

  1. Parent-child relationships
  2. Sibling relationships.

In parent-child relationships, one element is inside of another. If the element you’re examining has something in it, then it’s a parent element, and if it’s inside of something else, then it’s a child element. In the first example below, the Carousel is inside of the Background, so the Carousel is the child and the Background is the parent.

Elements can be both a child to one element and a parent to another. In this second example, the Carousel contains the Title. Thus, while the Carousel is still a child to the Background, it is also a parent to the Title.

A simplified layout showing that the carousel is a child of the page and that the title is in turn a child of the carousel.

The second kind of element relationship is a sibling relationship. In sibling relationships, the two elements have the same parent. In the example below, Title and Text Block both have Carousel as a parent, so they’re siblings with each other.

In this second example, Buttons 1 and 2 both have Background as a parent, so they are siblings. Even though the Carousel is fundamentally different than the buttons, it also has the Background as its parent, so the Carousel is also a sibling to these buttons.

A simplified layout showing that the carousel and buttons are all siblings of one another.

Pro-tip #2: represent these hierarchies with bullets and indents!

By representing these hierarchies as a bulleted list, you can easily visualize how elements relate to one another. Furthermore, many frameworks and UI Builders use hierarchies like this to actually model the layout.

For example, XAML-based WPF files (used for Windows application development), XML-based Android layout files (used for Android development), and HTML files (used for web development) all use indented, hierarchical XML formatting to show these relationships. Likewise, even iOS uses XML under the hood, and Xcode’s Interface Builder visualizes element relationships in bulleted lists.

In the example below, the layout previously shown is represented as a bulleted list.

First level: Background. Second level: Carousel, Buttons 1 and 2. Third level (under Carousel): Title and Text Block.

3. Elements each need a size and a position.

There are only two layout definitions that elements absolutely need: size and position.

Size describes how large or small an element is and can likewise be defined with two attributes: width and height. In the example below, the Button’s size is defined in two ways:

  • Width = the full width of the parent (minus some margin)
  • Height = a constant value

There is more than one way to define a size attribute. The three common ways to define both width and height are as follows:

As a constant, where the width or height have a fixed value. Examples:

  • width = 50px;
  • layout_height = “200dp”

Relative to the parent, sibling, or child element.

Explicitly articulated:

  • width = 65%;
  • layout_height=”match_parent”

Intrinsically based on content (i.e. the child size or children’s sizes):

  • child element is full width and aligned to horizontal edges
  • layout_height=”wrap_content”

Meanwhile, position describes where an element is rendered on the UI. The two common attributes for position are horizontal positioning (i.e. where an element is positioned on the x-axis) and vertical positioning (i.e. where an element is positioned on the y-axis). However, in some cases, a third z-axis positioning is defined, which tells the UI which elements should hide or be obscured by one another. In the example below, the button’s position is:

  • Centered horizontally in its parent
  • Aligned to the bottom of its parent

As with size, there are multiple ways to define positioning, and often positions are defined relative to the element’s parent. Some examples include:

Horizontally

  • Leading (left) edges
  • Trailing (right) edges
  • Centering on the horizontal axis

Vertically

  • Top edges
  • Bottom edges
  • Centering on the vertical axis

Pro-tip: manually verify that you’ve defined x, y, height, and width for each element!

Elements need both their size and position defined, sizes need both their width and height defined, and positions need both their X and Y values defined. This boils down to four distinct attributes that must be defined for layout:

  • Width
  • Height
  • X-position
  • Y-position

In the first example below, the layout is not complete because the height isn’t defined.

Example layout annotated to show that height isn’t explicitly defined.

This second example illustrates that there is more than one way to define the same layout.

Example layout annotated to show that there is more than one way to define the same layout.

How to start defining a layout

When building a layout, at which element do you start first? If there’s more than one way to define layout, how do you choose? One straightforward heuristic is to adjust your approach depending on whether or not the layout scrolls. A layout is considered non-scrolling if its viewport (i.e. all you see on the screen at once) is equal to the layout size. If the layout size is larger than the viewport, then the layout is considered scrolling.

If the layout does not scroll

  1. Define the layout of “anchored” elements. These are the elements that will always be aligned to an edge or will always be centered.
  2. Define all other elements relatively. Start with the elements positioned relative to the anchored elements, and then move onto the elements positioned relative to those.
  3. Consider screen sizes. To accommodate multiple screen sizes and aspect ratios, element sizes are often better defined relative to their parents so that they can grow and shrink.

Pro-tip: test your layouts on extreme screen sizes!

It would be extremely cumbersome to test your layout on every possible screen size and aspect ratio. That being said, a good heuristic that will ensure your layout works but will also save you time is to test your layout on the edge case screen sizes (i.e. the “extremes”). These will include:

  • Tiny screens
  • Wide screens
  • Tall screens
A visualization of a layout being expanded and shrunk both vertically and horizontally.

If the layout does scroll

  1. Define the layout of the “first” elements. For horizontal scrolling, this will be the left-most or right-most element. For vertical scrolling (like most webpages), this will be the top-most or bottom-most element.
  2. Generally, use constant or intrinsic values for scrolling dimensions. For example, on a vertically scrolling screen, heights should generally not be defined as a percentage of the whole layout. Rather, you should define the height with a constant value (e.g. 100px), relative to the content it contains (e.g. layout_height=”wrap_content”), relative to its width (i.e. maintain its aspect ratio), or relative to the viewport (which is something many websites do to have the first-loading content take up most of the screen but still allow for scrolling).
  3. Defining sizes and positions relatively is fine for non-scrolling dimensions. For example, it’s okay to define a relative width or X-position on a vertically scrolling layout.

Layouts: a summary

Everything is an element.

A screenshot of how Interface Builder shows every element as a rectangle.
Pro-tip: use rectangles to conceptualize!

Elements have relationships.

A screenshot of how Interface Builder shows every element within a hierarchy.
Pro-tip: use bullets to conceptualize!

Elements need size and position.

A screenshot of how Interface Builder shows height, width, X position, and Y position of an element.
Pro-tip: manually verify x, y, height, and width for each element!
A screenshot of how Interface Builder lets you preview your layout in various screen sizes.
Pro-tip: test your layouts on extreme screen sizes!
A screenshot of how a layout can be represented in Interface Builder.

Let’s recap

Frontend engineering is more than making things “look pretty,” and layout is the first major component to consider while engineering a UI. Part two, Adding Content and Applying the Style, will cover how to finish building your UI by defining what a user sees and how what they see is rendered.

--

--

ASICS Digital
ASICS Digital

Published in ASICS Digital

Fitness, technology, and how we see the world.

Danielle Cohen
Danielle Cohen

Written by Danielle Cohen

software engineer with a healthy love for running and an unhealthy love for cats.