Evolving from implicit intent to explicit design rules (2024)

It’s time to come to terms with what we’re actually doing when we design websites, native and web apps, why it’s important, and where the future of our design environments is headed.

In this article, I’ll dive into what explicit design rules are, how to think about them in various scenarios, how different tools afford to explicitly state your intent, and where the future of our design environments is headed.

To answer this, it’s helpful to start with a question that every product designer can relate to: “How do I get these items over there to align like this and respond like that to changes in screen width?”.

Depending on the design tools you’re using, you can find a solution in one of two ways. You can design examples and variations that express implicit intent, which is common in vector-based tools like Sketch or Figma. Alternatively, you can declaratively design the rules from which infinite examples might arise, a capability primarily found in code or code-like tools such as Webflow, Framer, or Jux.io. This distinction highlights that while both approaches aim to fulfill your desired intent, code-like tools offer much more intelligent, responsive, and granular ways to express that intent through actual design rules. In the following sections, I’ll be walking through real and practical examples to show you exactly what I mean.

Let’s say I want to space five objects out horizontally inside a box, and I want all of them to be spread out evenly from the left to the right side of the box.

If I describe the distance of each element from the top left corner I would be able to get my result visually, but I would be doing it by expressing a lot of specific information about each object.

Evolving from implicit intent to explicit design rules (3)

The downside here is that it doesn’t scale. For example, if the amount of objects increases by one or decreases by one, all but the first item of information I used to describe my layout wouldn’t be relevant. If my box was to grow by 100px — same deal — I’d have to provide new measurements all over again.

Evolving from implicit intent to explicit design rules (4)

The solution to this problem is getting to the broader, bigger picture intent of the action, like: “no matter the size of the box or the amount of elements, space them out evenly from left to right”. To make this intent true, you could use something like auto-layout (in the canvas tools), Flexbox in CSS, or code-like tools.

For auto-layout, it would be: ‘auto’ in the gap field. In Flexbox, it would be ‘justify: space-between

Evolving from implicit intent to explicit design rules (5)

In this case, no matter the width of the screen or the number of items inside the box — the implicit intent correlates perfectly with the explicit rule.

Plot twist: Designers love the ability to directly manipulate elements across the canvas, effortlessly moving, rotating, and placing them exactly where desired. This practice enables us to envision concrete examples of how the system might appear if all variables were fixed. From childhood, we’re conditioned to perceive ‘artboards’ as static and finite, similar to posters. However, this mindset conflicts with the reality of designing products, which entails accommodating various screen resolutions, often with unpredictable amounts of content and variations.

So, how should these conflicting approaches be resolved?

One solution is to let designers have a stage where they can play around, moving and resizing things until at least some key states of the system look decent. Only then would they move to the second stage, where they would try to find the best explicit rules for the result they reached while experimenting, this time across all the possible states.

The second approach would be to expect designers to slowly become so familiar with all the rule-based mechanics that they become intuitive enough for quick experimentation, completely bypassing the need to roam free.

Both are two ends of the spectrum, with every designer intuitively finding the most comfortable place, somewhere in the middle.

The good news is that with the right tools and application, it doesn’t have to be all or nothing. To understand how explicit rules can be beneficial, it’s helpful to first divide them into two categories:

  • Self-related, independent visual properties: This can be things like color, border, text properties etc. They tend to not change and not be responsive to screens, resolutions and amount of user data. Therefore we will not be dealing with this kind of properties in the article.
  • Relationship-dependent properties: This can be things like placement inside a parent object, width, height, gap between objects etc. These are the properties this article is going to deal with.

To better explain how these types of properties work, I’ll narrow our focus to the web, showcasing examples across three creation environments:

  1. Vector-based tools, such as Figma, Sketch, and Adobe XD, which most designers use for designing websites and web applications.
  2. Code-based web design tools like Framer and Webflow.
  3. Code-based web application design tools like Plasmic, Henosia, Subframe and Jux.
  4. CSS

It might be tempting to always specify precise and fixed measurements for the width and the height of elements. But it’s probably only the right approach when you’re certain the element won’t change. For example, if we need the button to grow in width based on the length of its text field, we have to make the width ‘dynamic’.

Evolving from implicit intent to explicit design rules (7)

Let’s look at how we’d do this in different tools.

In Figma: This would mean switching the button frame to have auto-layout and choosing ‘hug content’ for width.

In Sketch: You’d have to set the button to have ‘smart layout’ with horizontal resizing.

In Jux and Webflow: You’d set the width field as ‘auto’.

In Framer: You’d have to select ‘fit content’ in the dropdown before the auto becomes accessible.

In CSS: You would set it to ‘width: auto

Evolving from implicit intent to explicit design rules (8)

Note that the dynamic ‘undefined’ value for the width of the button is the explicit rule here that will work for all the infinite cases of text.

Explicit rules, help you match input or commands with your implicit intent. Let’s look at four different situations, where the ability to design with greater flexibility, thanks to explicit rules for width and height of parent and children elements that reside in them, proves beneficial:

Use case 1

I want to have a cap on the width of my button: Let’s say you want to guardrail against a case where the labels on a button are completely out of your control and are user- dependent. Or for example, you don’t want the ‘OK’ button to be as short. In all three platforms, it would make sense to use min-width and max-width. Our implicit intent is now more nuanced: have a width of however is needed, but not less than X and not more than Y.

Evolving from implicit intent to explicit design rules (9)

Use case 2

I want to place the button inside a modal, at the bottom:
In this case, the implicit intent would be: “always stretch side to side, no matter what label it has”. To achieve this in Figma, you can use fill-container on the button, provided that the modal itself is set to auto-layout. In Jux, you can do it in a couple of ways, either by specifying 100% on the width of the button, or even better — selecting ‘flex’ for the modal and ‘stretch’ in the align selection. In CSS, you can use percentage or flexbox.

Evolving from implicit intent to explicit design rules (10)

Use case 3

I want to limit the modal from being taller than 80% of the height of the viewport: In this case, the implicit intent would be: “Grow height up to fit the content until you hit 80% of the viewport height and then stop”. Viewports come in many sizes. In Vector tools — you’re out of luck. There’s nothing you can specify as an explicit rule.. In code-like tools, you can specify an 80VH (viewport height) unit on the max-height of the modal, while leaving the height itself on auto.

Evolving from implicit intent to explicit design rules (11)

Use case 4

I want the modal to be divided up into 3 columns with different ratios of their widths: Here, the implicit intent would be something like: “Divide into three columns, make the width of the first column 30%, the second 50% and the third 20% of the container width, and a 16px gap between them”. In this case the width of each column cannot be fixed, but it also cannot be ‘auto’.

Evolving from implicit intent to explicit design rules (12)

To specify an explicit rule in Sketch, Xd, or Figma, there’s really nothing you can do for that to work responsively. In Framer, for example, you can use a percentage unit on the width of each column by choosing relative in the dropdown. In Webflow, you can use Flexbox on the modal and specify the ratio using flex: grow number on the columns to adjust the ratios.

Evolving from implicit intent to explicit design rules (13)

In CSS and in both Framer and Webflow you can also use grid on the modal and specify each column’s ratio using the FR unit (which stands for fraction), all while keeping the width of the modal on auto. Either of these solutions is a nuanced but powerful explicit design rule.

Evolving from implicit intent to explicit design rules (14)

All of these examples show that objects indeed can have their width and height be a factor of either dynamic content or changes to their parent containers and still remain flexible. You just need to find a way to match implicit intent with explicit rules.

Adopting a rule-based approach is necessary within layout decisions as well, and layout considerations happen when objects are contained within another object. In this scenario, two sets of rules are relevant:

  1. Rules that dictate how the parent object should order and position it’s children
  2. Rules that specify how each child element should relate or override the parent-imposed rules

I’ll be providing a number of examples below that put these rules into practice.

Example 1: Wrapping cards inside containers

Let’s say that you want to lay out five different cards from left to right, from top to bottom, where only three cards fit the container in its current width:

Evolving from implicit intent to explicit design rules (15)

There are a couple of ways to go about it, depending on the design tool. In Figma, the best way would be by assigning ‘auto-layout’ to the parent frame and setting it to ‘wrap’, aligned top left. In Jux as in CSS, you would use Flexbox on the parent frame, activating ‘wrap’, selecting ‘start’ in the align, and ‘start’ in the justify options.

The implicit intent in this case would be: “Regardless of the width of the parent container, keep laying more items until there’s no more space to place another one, then move to the next row and continue from left to right”.

Evolving from implicit intent to explicit design rules (16)

Example 2: Changing card position while maintaining layout

Now, consider the following intent: “Upon hover, each card ‘jumps up’ 20px without disturbing any other card.” In vector tools, there’s no way to express the concept of changing something’s position without affecting the layout. This is only possible if there’s a positioning mechanism like in CSS that allows for ‘position: relative’ on the hover state of the card, while still reserving the space occupied by the card. Code-based tools like Jux, Webflow can support this, but strangely, Framer does not.

Evolving from implicit intent to explicit design rules (17)

Interestingly, Figma supports another positioning option, ‘absolute’, even within ‘auto-layout’-ed frames. This feature is particularly useful when you want to position an object (like a notification) on the top-right corner of an expandable button and the object will always be pinned in the same place. Moreover, in standard, non-’auto-layout’-ed frames, all constraints are variations of ‘position: absolute’ even without explicit selection.

In code-based tools like Framer, Webflow, and Jux, you can simply select the type of positioning to be ‘absolute’, regardless of the layout decision. However, in Webflow and Jux this is not the default setting.

Below, you can see how the initial desired intent aligns with the explicit rule in Framer:

Evolving from implicit intent to explicit design rules (18)

Example 3: Child item independence

What if you want most of the items inside a container to stretch, while one item aligns center? For example, when laying out a narrow container with a title and several paragraphs, you may want the title to be center-aligned, but the paragraphs, due to their multiple rows of text, should align left while filling the width of the container.

The implicit rule could be summarized as follows: “Make all these items stretch but this item align to the center, regardless of the parent’s width and the number of items I add”.

Below, you can see the explicit rule mechanics in Webflow:

Evolving from implicit intent to explicit design rules (19)

For this use case, Webflow is the easiest tool. This is because you can use the ‘Flex child’ module to override the general alignment that was set by the parent container — so you don’t need empty containers, just the title and paragraphs in one parent container.

Meanwhile, in Figma, it’s more complicated because you can’t override the auto layout’s alignment setting for a specific child element. Therefore, you’d need to create another frame to contain the title and set it to center alignment.

Example 4: Stacking order

Let’s imagine you’re designing an avatar group widget, where the avatars overlap each other. Your design intent is as follows: “When hovering over any avatar, it should appear above all others, regardless of its position in the idle state”.

Evolving from implicit intent to explicit design rules (20)

To achieve this effect, we need to use a concept called ‘z-index’. However, in Figma, doing this would mean giving up the auto layout of the avatars’ container. Figma’s auto layout allows you to specify whether elements are arranged ‘first on top’ or ‘last on top,’ but this feature is primarily geared towards establishing the initial stacking order. It doesn’t provide the flexibility to dynamically adjust the ‘z-index’ of individual elements. The good news is that in CSS and code-like tools, you can specify that in hover state, the ‘z-index’ will change. This means that in the idle state, the avatars maintain their default ‘z-index’ order based on the flexbox layout, but upon hovering, the ‘z-index’ of the hovered avatar is increased, causing it to be above all other avatars

Example 5: Padding and margin

The position of children elements inside a parent container is also influenced by two important properties of the box model: padding and margin.

Padding: A top-left padding of 10px will push any child element 10 pixels from the left and the top sides of the parent container, even if the alignment is to the left. You can think of padding as a short explicit variation to the implicit intent of: “Make sure nothing comes closer than 10px from the left and top sides, regardless of its size or any other rule it has”.

Evolving from implicit intent to explicit design rules (21)

In Figma, padding only exists for frames with auto-layout turned on; ordinary frames don’t have this ability. In CSS, however, padding can be applied in all cases and situations, regardless of the display type. It is worth noting though, that when the child element has ‘position: absolute’ it completely ignores padding. Similarly, when it has ‘position: relative’, its visual placement ignores padding (although its original placement does respect the padding).

Margin: Margins are also useful for defining ‘safe’ space on each side of an object or creating space between objects, especially when the spacing is irregular (and using the gap feature in auto-layout / flexbox is not enough). Now, it’s important to note that neither Figma nor any other vector tool out there supports margins. So, the only way to ‘fake a margin’ is to wrap an element with a frame and set the frame’s padding equal to desired margin distance. But this is problematic because it leads to unnecessary bloat of frames that are only present due to the inability to use margins. In Jux (and of course CSS), margins are freely available for use in all directions and cases.

So basically, when you create a 30px margin from the bottom of a component, your implicit intent would be: “No matter what, always act as if you take up 30px more space on the bottom”. This ensures that all instances of that component (or class in CSS) will respect the explicit rule, for any other objects they’ll encounter throughout the design.

Evolving from implicit intent to explicit design rules (22)

There is a quirk worth mentioning with margins known as ‘margin collapse’. This occurs when two block-level elements (like a div) have margins. For example, say the top one has a margin-bot: 30px and the bottom has margin-top: 50px, the resulting space between the elements will be the larger of the two, not their sum (o 50px, not 80px.)

Apart from this, the explicit rule aligns well with the implicit intent.

After all of the examples in this article, I hope you can see that the mechanics of expressing implicit intent really depend on the design tool. Some will support fewer options, some will support many more. Code will probably support more than any design tool, but it’s inaccessible to most designers (Including me! I know my way around HTML and CSS but I don’t feel comfortable just coding in a code editor. I always prefer to use a UI as a helpful abstraction between myself and actual code).

This means that the tools that allow the most expressive and intelligent mechanics will be the ones that attract the designers that want to have the most expressive power. And with apps getting more and more dynamic and smart, screen sizes and viewports multiplying in numbers and content being more tailored to every user — I doubt designers can afford not to have the most expressive toolset at their fingertips. My prediction is that future-proof product design tools will be those that gravitate towards an ever-growing ‘coverage’ of the layout capabilities of code. They will perhaps never truly cover everything, but the tools that come the closest — will be the ones most worthy of our attention.

I hope this was an eye-opening, or at least somewhat thought-provoking read and if you’re interested, I encourage you to learn much more about the design options you have. Here’s a great list of resources for you to check out, at your own pace:

  1. Christine Vallaure gives an excellent deep dive into Flexbox and CSS grid for designers
  2. Brad Frost, the author of atomic design, discusses grids as a concept between design and development
  3. Jen Simmons shows in many different video tutorials how to implement flexbox and css grid creatively
  4. The most incredible interactive guides for Flexbox and CSS grid by Josh Comeau
  5. Webflow has one of the best academy video tutorials series out there
  6. Framer has an academy series as well
Evolving from implicit intent to explicit design rules (2024)
Top Articles
Latest Posts
Article information

Author: Jonah Leffler

Last Updated:

Views: 6075

Rating: 4.4 / 5 (65 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Jonah Leffler

Birthday: 1997-10-27

Address: 8987 Kieth Ports, Luettgenland, CT 54657-9808

Phone: +2611128251586

Job: Mining Supervisor

Hobby: Worldbuilding, Electronics, Amateur radio, Skiing, Cycling, Jogging, Taxidermy

Introduction: My name is Jonah Leffler, I am a determined, faithful, outstanding, inexpensive, cheerful, determined, smiling person who loves writing and wants to share my knowledge and understanding with you.