The Stack

This layout is for any kind of stacked items that have whitespace between them. The only purpose is to insert vertical margins correctly.

Instead of putting a margin-bottom on each child element (creating extra space after the last element), you can use "owl" syntax: .stack > * + * (or .stack * + * to apply the margin recursively) with margin-block-start set to the preferred line-height. (They tend to prefer 1.5rem.)

They mention an interesting selector that targets all classes that begin with "stack": [class^='stack'] > *. If the spacing is uneven (because you didn't use a CSS reset on margins), you can use that selector to set margin-block: 0 and then set the spacing for child elements like .stack-large > * + * and .stack-small > * + *, where the large might be spacing between something like form fields, and the small might be spacing between a field's label, input, and validation text.

It says that CSS is "exception-based" and links to an article about Managing Flow and Rhythm with CSS Custom Properties. See the example here.

Flexbox for Auto-Margins

The card footer text is pushed to the bottom of the stack due to the CSS rule:
margin-block-end: auto
targeting:
.stack-1 > :nth-child(2)
(meaning target the element after the 2nd element). They use a prop named splitAfter to set the value of the :nth-child selector. They also set .stack:only-child to block-size: 100%

Card Title

Card body. Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum perspiciatis, nam dolorem commodi fugit esse totam cumque est quidem ex iusto quasi delectus dicta, iste nihil a consequuntur? Incidunt, quae.

Cat 1
This is the card footer that has been pushed to the bottom by the split-after technique described on this page.

Stack Summary

To summarize, a Stack has the following CSS:

  1. Flex: The .stack parent element has:
    • display: flex
    • flex-direction: column
    • justify-content: flex-start
  2. Margins: The margins are removed from immediate children with .stack > * set to margin-block: 0
  3. Owl selector: The spacing between children is set with .stack > * + * (or .stack * + * to apply the margin recursively) with margin-block-start set to the preferred line-height (typically 1.5rem).
  4. Stack footer: if the footer needs to be pushed down, set .stack:only-child to block-size: 100% and use the .stack > :nth-child(n) with margin-block-end: auto technique.

Their custom web component implementation takes three props:

One last thing they mention is that you can make things more accessible by adding role="listitem" to each element in the stack if you want screen-reading software to recognize the list.