Spacing Foundation

With a modern layout using flex and grid, I see margin becoming a more explicit and incidental property for a specific use case. In general, I've stopped using margins to control positioning an element. This allows me to revisit the spacing model I use for design systems.

I consider two types of spacing:

  • Layout
  • Content

I apply these types of spaces across four layers in a document.

  1. Context level
    :root and :host
  2. Body or top-level element
    Elements like an app or a main layout container
  3. Layout and content containers
    section, main, header, footer, cards, etc.
  4. Content elements
    buttons, headings, list items, labels, inputs, etc.

Context level

The context refers to the root of the light or the host of the shadow DOM. Do not touch either. Only, if needed, reset and normalise. Also, I do not touch the border-box. Including padding in the width of an element has now become our friend. The context host is also where I set all the base font styles. I do not set any sizing values on the body.

Top level

The top-level control the layout for the rest of the page and sets its dimensions in VW, VH, and DVH. This can be the body element, but in many cases, I only need to add a flex or grid to control the position of the underlying containers. I can also omit a top-level wrapping container with a subgrid based on the body to give a layout of nested elements. That would be one div less. The top-level container always uses REM units for padding and gap values. However, I do not use logical values, as the reading direction isn't relevant here.

Container level

Containers have two types: layout and content containers. The Layout containers are actually outer content elements like section, header, main and footer. These form the basis of any modern web page. Like the top-level container, directional padding (top, right, bottom, left) and gap with REM units are used. Content containers like Cards, Modals, notifications, menubars, etc. I treat them on the whole like layout containers. Depending on the amount of text, they may have exceptions to their spacing properties. Otherwise, they are still part of the visual structure and not a type of content.

Content level

The content-level elements always use a mix of values based on reading directionality. I use the logical 'block' and 'inline' properties here. For the rows and the block direction, EM or EX is used, and for columns and inline CH is appropriate.

So, why all the fuss?

Well, the ability to use container queries further enables the autonomy of components. To have a genuinely autonomous feature, we should avoid reaching beyond the element visually with margin like we shouldn't reach for parent elements beyond the component.

Posted on: December 25th, 2022

Previous Post

Root Cause

The "62.5% sizing' hack is nifty but has one problem. It hampers external themes to use root based sizing.