Skip Navigation
Inside Sketch

Behind the feature: How we took Smart Layout beyond Symbols (Part 3)

In our final post of this behind the feature series, Paulo and Torsten explain how they broke Smart Layout free from the confines of Symbols and brought it to groups and Artboards.

In November 2023, we shipped a major upgrade to Smart Layout and in this series, we’re looking behind the scenes at how we made it happen. In the first post, the team set the scene for this this work. In the second, they described the process of fixing issues and improving reliability and predictability. In this final installment, they explain how they gave Smart Layout a new lease of life beyond Symbols.

After making Smart Layout a lot more reliable, the stage was set to work towards our ultimate goal: breaking it free from Symbols, and bringing it to groups and Artboards.

This wasn’t as easy as it may seem: we couldn’t simply make everything about Smart Layout work outside of Symbols just as it did inside of them, at the flick of a switch. This is due to two characteristics of groups and Artboards that makes them distinct from Symbols:

  1. They don’t impose any limitations on what people can edit within them.
  2. They lack the permanent point of reference that a Symbol source provides.

These aspects form the basis of most of the challenges we’d be facing in this project.

On top of this, we knew we also had to consider Smart Distribute, and introduce some much-needed quality-of-life updates to Smart Layout as a whole. But let’s first dig into those two challenging characteristics in a little more detail.

Let’s start by exploring challenge that each of these areas present.

Exploring the challenges

Challenge 1: Creative freedom outside of Symbols

For Smart Layout in Symbols, there are only two major actions that lead to a layout change that a designer can take:

  • Resizing layers indirectly (due to text overrides or swapping nested Symbols)
  • Hiding and un-hiding nested Symbols

With editing outside of Symbols having no limitations like these, we had to consider all the additional ways that layers may change that call for layout reflows, which fall into three familiar areas:

  1. Resizing layers — either directly, through resizing a layer or one of its ancestor groups, or indirectly, by changing individual text or line size properties, and more.
  2. Adding new layers — by inserting totally new layers, duplicating existing layers with D or -drag, or pasting copied or cut layers from the clipboard.
  3. Deleting layers — by the normal methods of deleting or cutting.

Challenge 2: Staying consistent without a source

One of our fundamental goals was to make the overall experience of Smart Layout consistent and predictable regardless of whether you use it inside a Symbol, group, or Artboard.

In particular, one foundational Smart Layout principle should still be valid when we apply it to groups: only changes in size will affect the layout, never changes in position.

But there’s an added difficulty: in contrast to Smart Layout in Symbols, there is no “source”, no original state to have a look at or take measurements from. As soon as someone makes a change to the child layers of a group, the original state is gone. There is no pristine copy like the Symbol source.

This difficulty is the main reason for some subtle inconsistencies in behavior. So, an operation like hiding a child layer won’t affect the layout, because the information to restore the layout of the adjacent child layers is missing (once the smallest of the adjacent spaces is removed via hiding and the layout is changed, there’s no way to get that information back).

To document the behavior and to make sure future changes don’t break it, most of our existing unit tests got a group-related counterpart, so the total number of unit tests related to Smart Layout almost doubled.

Responding to actions

After we identified our challenges, we started to tackle the three areas of changes that a designer might make to layers: resizing, deleting, and inserting. Let’s look at each of these in detail.

What happens when you resize a layer?

Smart Layout in Symbols has a single trigger: changing an override resulting in a size change of a layer (let’s leave out hiding and unhiding nested Symbols by overriding for this scenario).

For Smart Layout in groups, however, there are more triggers:

  • You can resize layers directly, either by dragging on the Canvas, setting a specific value in the Inspector, or by dragging on the W or H symbols in the size Inspector
  • You can resize layers indirectly (e.g. by changing the text contents or text attributes, including via in the Inspector)
  • You can size Symbol instances to fit
  • You can replace Symbol instances with another one.

So, there are more places where we needed to take a snapshot before any changes take place. Smart Layout already worked for groups inside Symbols, so for the Inspector, we “only” needed to show the same Smart Layout controls for regular groups as well.

Resizing, by dragging on the Canvas or on the Inspector controls, provided an additional challenge: we needed to decide when to take the snapshot before the change. We had two options: taking a single snapshot before the drag started (and treating all changes as relative to that snapshot) or treating each drag step as single change.

The main issue with the latter option is that the spatial relationships between the unchanged layer(s) and the changed layer along the layout axis can change, resulting in a behavior change while dragging. A layer previously unaffected by the changed layer can suddenly resize, too — that was too unpredictable, so we discarded it.

The following animation shows the difference between the two approaches:

Our two potential approaches to snapshots when dragging left us with a clear winner in terms of consistency and predictability.

What happens when you delete a layer?

Deleting a child layer of a group with Smart Layout is very similar to hiding a nested Symbol instance. So we went for the same behavior, including removing the smallest adjacent spacing.

Any overlapping (specifically: overlapping the trailing edge in the layout direction) unchanged sibling layers would be shortened by the width of the deleted layer. While this is desirable if the unchanged layer overlaps both edges, it can mess up a layout if the overlapping layer is smaller along the layout axis.

During development, this danger of messing up the layout by a seemingly harmless deletion lead to us introducing an option to pause Smart Layout. With this, a designer has the option to delete a layer without affecting the layout, and then resume Smart Layout after (more on this later). While this solved the issue, we wanted to make things smarter and not rely on pausing as a complete workaround.

In the end, we decided to let a deleted layer only affect unchanged layers if they completely wrapped the deleted layer along the layout axis. Partially overlapping layers are not affected. In the example below, deleting the grey background layer doesn’t shrink the partially overlapping layers to zero – they are now unaffected.

Deleting the grey background layer doesn’t affect the overlapping layers in the middle of it.

What happens when you insert a layer?

Inserting a new child layer to a group with Smart Layout is similar to unhiding a nested Symbol instance, but with one major difference: we don’t have any information on the new layer’s exact positioning and how far its new sibling layers need to move to accommodate it.

In contrast to hiding a nested Symbol instance, deleting always results in us losing information (how big is the smaller spacing which was just removed?) Inserting, as its counterpart, has no way to derive that information from the current layout. There’s only one way to solve that: the designer needs to decide where and how the new sibling layer should be positioned.

Our approach to inserting layers involves predicting possible insertion positions and showing a marker for these.

We provide three possible insertion positions: between two layers, touching the previous layer, or touching the next layer (along layout direction). While the touching positions just insert the layer and no additional space, the midway position also adds some space, so after the layer is inserted, it will be surrounded be the same space it was dropped into at the left and right (or top and bottom, respectively). In any case, it’s easy to freely reposition that layer if needed.

In addition to dropping in a new layer from outside the group, it’s also possible to insert a layer by duplicating or copy-pasting an existing child layer within the group.

Completing the experience

As we started to get things working inside groups and Artboards in our internal builds, we quickly realized we wanted to complete the Smart Layout experience in three main ways:

  • Setup — making it easy to enable, disable, and set direction without stopping your flow.
  • Pausing — making it possible to temporarily stop a layout from reflowing as you make changes inside a group or Artboard.
  • Stacks — including special accommodations for stack-like layouts (rows or columns of evenly-spaced layers), even if Smart Layout isn’t strictly limited to them.

Let’s tackle each of these in a bit more detail.

Speeding up setup

There are three steps to setting up a group with Smart Layout:

  1. Select some layers
  2. Group those layers
  3. Pick a Horizontal or Vertical layout for the group, and then (optionally) change its direction.

As separate actions, these felt a like a chore which broke the design flow. We wanted to compress them into something that felt like one swift action and avoid sending people to the Inspector in the process.

We started by solving step three, and naturally turned to keyboard shortcuts. But having six choices (2 axes × 3 orientations) plus the option to disable layout defied a standard keyboard shortcut.

We looked around for other actions with similar choices that have shortcuts, and alignment was a great parallel. For alignment, we use followed by either H or V. We liked how natural it felt to use those keys, but wanted to avoid having to use some combination of modifiers for the shortcut “base” that people would just have to remember without an obvious mnemonic.

So we decide to use what we called a “two-stage” shortcut in Sketch for the first time.

  • First, press and release L (L for Layout)
  • Then, press either H or V to set the layout direction
    • Or disable Layout by pressing L again (since that’s where your finger already is).

The two-stage shortcut for setting a layout and direction with your selection.

We found this super easy to get used to: you only have to remember L (easy enough), and the rest is just like alignment. Plus, despite being a two-stage shortcut, it felt like a single action that covered enabling layout, changing axis/direction, or disabling it altogether.

Finally, solving step two: grouping the layers. This was much easier: if your selection has non-grouped layers in it, when you hit L we’ll group those layers for you as a convenience.

In the end, we think we managed to compress those three distinct steps into something that feels easy to remember and swift to use: select your layers, press L, and pick a direction, carry on.

Allowing for pause

Managed layout systems can be a blessing and a curse. On one hand, they’re incredibly useful in automating things so the layout stays as you intended. On the other, that automation can sometimes come in when you don’t want it to, and inadvertently cause a bit of a domino effect.

This is particularly true of Smart Layout, because it reacts to changes made at any depth, and because it accommodates any layout arrangement, inviting designers to break away from evenly structured layouts.

In our internal builds, our designers soon found themselves wanting to do just that on occasion, only to find out that the system kept following them along, making it difficult to break away. We tried making it easier to disable Smart Layout, but that didn’t feel right, because designers often wanted the system to kick back in once they were done making an exceptional change.

So, we created a way to pause Smart Layout: press L and it’ll stop adapting to any changes you make. You can press it again to resume, but it’ll automatically resume once you clear your selection. So you know exactly when Smart Layout is paused, a toast at the bottom of the Canvas indicates this, which you can also dismiss to resume it.

There when you need it, but not when you don’t.

Working with Smart Distribute

As we noted in our first post, even though one of Smart Layout’s key principles is to support any layout arrangement, stack arrangements (evenly spaced single-file rows or columns of layers) are incredibly popular — so, we wanted to better accommodate them.

We’ve long had a Smart Distribute feature precisely to make it easier to work with stack layouts. It helps designers adjust the spacing between all layers of an evenly-spaced selection or group of layers, and also easily reorder those layers. Additionally, our Tidy feature creates an even stack arrangement with a single click, with options to easily change spacing.

Even if we did nothing, if a group with Smart Layout had its layers laid out as an even stack, our Smart Distribute features would also be available. We also knew that users wouldn’t necessarily be able to distinguish between the two features, nor should they have to — it should all just work. So, we looked to improve how the two features work together when they both naturally occur.

Smart Layout and Smart Distribute blend together seamlessly.

First, we made it easier to lay out stacks. Previously, if you wanted to evenly space layers using a specific horizontal or vertical spacing value, you’d have to press Tidy first, then adjust the value. We made it so you could directly enter a value, saving you that extra click.

Second, we made it easier to rearrange stacks and adjust their spacing. Previously, you’d only see on-Canvas handles for Smart Distribute in an evenly-spaced group if you selected the group itself. We knew that this would be annoying alongside Smart Layout, where you’d want to select a layer in a stack to resize it (and have the layout adapt) followed by adjusting its spacing and/or rearranging it in the stack. Now, when you select a layer in an evenly-spaced group, the on-Canvas Smart Distribute handles also appear, as well as the horizontal and vertical spacing values in the Inspector.

Finally, we made sure that Smart Layout would keep tidied things tidy. Smart Layout takes into account the stack’s spacing when adding layers into a stack, be it when duplicating or dropping them in from the outside. Additionally, adjusting the stack’s spacing causes the layout to adapt.

Shipping the update

Much like the release strategy we employed when we worked on making Smart Layout more reliable, we released Smart Layout in groups as an experimental feature as soon as we could. Even if it was imperfect, it gave designers the opportunity to use and give valuable feedback as we continued to build towards a public release.

Once again, as we’ve mentioned in previous posts, we owe a lot of thanks to the wonderful folks in our Community Forum who shared their experiences with us throughout the period that Smart Layout in groups was available as an experimental feature. That feedback helped us shape our final release and gave us invaluable gut checks on decisions along the way.

All told, it was a few months after our Experimental feature release that we shipped the final version of Smart Layout in groups. In that time, we worked through feedback, fixed bugs and gave it some all-important polish. Hopefully this trio of blog posts gives you a good idea of why we took our time to get things right. Moreover, we hope you enjoy it in practice!

You may also like

Try Sketch for free

Whether you’re new to Sketch, or back to see what’s new, we’ll have you set up and ready to do your best work in minutes.

Get started for free
Get started for free