« resources

Company Workshop

Layouts

Distributing content, and providing structure

workshops.oddbird.net/kc24/layout/

Cmd/Ctr-K for Controls

Flow Is ‘Normal

  • Flow is so ‘default’ we don’t see it as ‘layout’
  • This is just ‘how text works’
  • And the underlying boxes tend to disappear
  • Creating a unified ‘document’

Flex and Grid Designed For Layout

  • We think of flexbox and grid as being for layout
  • helping us move content around a page,
  • And providing visual structure
  • But they have very different approaches to that,
  • And both rely on another concept…

Box Alignment

distributing extra space

  • Box alignment
  • Proposed/implemented along side flexbox, also works in grid
  • Often considered ‘part of’ these layout methods
  • But that was never the intent
  • The spec also describes how it should work in
  • ‘block’ and ‘absolute positioned’ layouts
  • And now browsers are starting to add that support!
Alignment in absolute position [present, debug]
  • Absolute position maybe the simplest to see
  • Just moving one element around in the positioning context
  • Alignment helps us place an element in relation to extra space

Place Self

Block axis comes first

  • Place self is the shorthand
  • An item setting it’s own alignment
  • Block axis comes first (always for logical props)

Shorthand for… Align-Self & Justify-Self

Which axis are we manipulating?

  • We can target each axis individually
  • justify-* props apply to the ‘inline’ axis
  • (Think about justifying paragraphs)
  • align-* props apply to the ‘block’ axis
  • (Think about aligning text and icons)
  • (This assignment changes based on flex-direction)

Fill space With stretch

Set position start | center | end

  • We can position boxes on either axis
  • To the start, center, or end
  • Based on the writing mode of the container
  • That way they always match, even if…

Set position self-* | flex-*

  • Rarely, we might have nested writing modes
  • (Different on container and items)
  • We can change which one we’re aligning based on
  • With self-start & self-end (for items own writing mode)
  • Or flex-start & flex-end (for the flex direction)
Safe & Unsafe Alignment [present, debug]
  • Sometimes alignment can move overflow to scroll start
  • Dangerous, because we can’t scroll before the start
  • safe ‘clamps’ alignment at the start
  • Don’t want to lose content

Details differ Across Layout Contexts

See CSS Box Alignment
  • From here, details differ a bit
  • Depending on the layout mode
  • Which we’ll see as we dig in,
  • Starting with flexbox…

display: flex Content Sharing Space

or inline-flex
  • Similar to ‘normal flow’ layout
  • Flexbox is highly content-driven approach
  • But with more options for alignment
  • And more… flexible boxes?
  • Allowing us to not just move things around in extra space
  • But also have items shrink & grow in different ways
  • Not just based on content or parent size, but siblings!
Flexbox is inline-ish [present, debug]
  • Items flow along a primary axis, forming ‘flex lines’
  • Optional line-wrapping at the edge
  • Control -direction and -wrap (or -flow)
  • Add gutters with gap on container
  • Intrinsic sizing, shrink, don’t grow
  • Align-self within the line (stretch by default)
  • Align-items for container-defined default
  • Can’t justify individually (justify to what?)
  • Place (align/justify) content!
  • Distribution values (between, around, evenly)

On containers… Align-Items as Default

(each item can still align-self to override)

Content distribution space-between | -around | -evenly

css…
.defaults {
  flex-basis: auto; /* starting width */
  flex-shrink: 1; /* distribution factor */
  flex-grow: 0; /* distribution factor */
}
Flex Items
  • We also control how the item boxes flex
  • When there is extra space,
  • or not enough space
  • There are three underlying controls: basis, shrink, and grow
  • By default, starting from their auto content size
  • All items shrink equally (factor of 1)
  • Don’t grow at all (factor of 0)

Four flex Shorthand Values

initial | auto | none | <grow>

shorthand values designed to handle the majority of use-cases
  • Often don’t need that level of detail
  • Four shorthands to cover most common cases

Initial Shrink, If Necessary

Same as 0 1 auto

  • Initial, the default
  • Same as basis auto, no growth, shrink as needed
  • Great for distribution around/between elements

Auto Shrink or Grow

Same as 1 1 auto

  • Auto, to distribute space into elements
  • Adds the ability for them to grow into extra space

None Don’t Flex

Same as 0 0 auto

  • None, still auto-sizing
  • But no flexibility

<number> Share Space Equally

Same as <number> 1 0

  • A single number, setting growth
  • Fully flexible, with no content basis

Use the Firefox Flex Inspector

Flexbox is inline-ish [present, debug]
  • initial
  • auto
  • none
  • <grow>
screenshot
[teacupgorilla.com]
  • Flex values can add up to less than one!

Generally… I Avoid Flex-Basis

Not a strict rule, just a hint!

  • Generally I avoid explicit flex-basis
  • Not because it’s bad to use, go for it!
  • (there are always exceptions!)
  • But if I want more control over sizing…

You probably Want Grid Instead

  • I probably want grid instead

Poll… Do You Use CSS Grid?

  • ✅ regularly
  • ⚠️ sometimes
  • ❌ rarely

IM(H)O… The Best of CSS 🏆

  • Flexbox and grid are both excellent
  • I use them all the time, for different things
  • But grid may be my favorite tool in CSS

display: grid Container Defined Layout

  • And if you want to create a specific layout
  • Instead of letting the content figure it out
  • Grid usually the tool for the job
  • Can still use intrinsic sizing from items
  • But coordinated by rules on the container
A quick bit of grid [present, debug]
  • Block-like default
  • Container controls the gap
  • Auto-repeating gallery
  • Add a layout template, grid-areas
Grid Terminology [present, debug]
Implicit Grids [present, debug]
  • Implicit grid (turn on inspector)
  • The ‘grid’ is not the container
  • The ‘cell’ is not the item
  • Align self (in cells), or content (in container)
  • grid-column and grid-row for positioning
  • Control implicit tracks with auto
  • Positioning w/ start, end, and span

Implicit grids

Generate columns & rows as needed

Sizing implicit tracks… grid-auto-columns
grid-auto-rows

Explicit item placement grid-column & grid-row

Shorthand for grid-<axis>-start & grid-<axis>-end
Explicit Grids [present, debug]
  • grid-template often the right shorthand

Defining Templates grid-template: <rows> / <columns>;

Fluid & Fixed 20em 25% 200px

Fluid Until Fixed minmax(min-content, 1fr)

Fitted… fit-content(<limit>)

clamp(auto, max-content, <limit>)
Understanding 1fr [present, debug]
Stages of Squishiness [present, debug]
Named grid lines [present, debug]

Names Areas

with matching *-start & *-end names

Overlapping Named Lines [present, debug]

Subgrid

as column or row template

Subgrid Cards [present, debug]

So Much More Grid!

  • There’s a lot more to cover
  • We would need another full workshop
Headshot of Jen Simmons, smiling

Jen Simmons… Intrinsic Web Design

  • Truly Two-Dimensional Layouts
  • Nested Contexts
  • Combine Fluid & Fixed
  • Various Stages of Squishiness
  • Content Expands & Contracts
  • Media Queries*, As Needed
* And now Container Queries
  • We’re in a new era of web layout
  • (read the slide)

🤔 Nested Contexts ??

Content Expands & Contracts ??

Media vs Container [live code, present, debug]
Statue of The Thinker
with a scribbled thought bubble asking:
do containers know stuff? photo: Avery Evans

Container queries will never be possible on the web. They would cause infinite layout loops.

— Browsers, a paraphrase (circa 2020)

The pink box is now labeled
extrinsic size (imposed from outside),
and the oveflowing blue text
now has a dashed box and says
intrinsic size (from the content)
The intrinsic/extrinsic diagram
with red circles and arrows and question-marks
scribbled all over it
Support data from CanIUse.com on the css-container-queries feature
[Can I Use]
Media vs Container (Live Demo) [present, debug]
The thinker
with a red scribbled thought bubble:
how?!

*Some Restrictions Apply

We can’t affect The Container That We Query

Directly or indirectly

We Need to Turn Off Intrinsic Sizing

The intrinsic/extrinsic diagram
with the intrinsic content sizing
scribbled out

CSS Containment

contain: size | layout | style | paint;

Avoid internal impacts on external elements…
CSS is Rad [present, debug]

Block boxes get their inline-size from Context (extrinsic).

— Me, Monday

Block boxes get their block-size from Content (intrinsic).

— Me, Monday

👍🏼 Inline-Only Containment

Ancestor Layout Loops with Single-Axis Containment

👎🏼 Block-Only Containment

We can only Measure The Axis We Contain

Contain inline-size For Most Containers

Contain size For Scroll Containers

Containing Size [present, debug]

Also need to Contain Layout* & Style

*This is being relaxed!
Understanding containment [present, debug]
  • Containers should no longer apply layout containment!
  • Still create ‘formatting context’
  • Still contain counters

Since… Containment is Invasive

We create Explicit Containers

css…
container-type: inline-size;
contain: inline-size layout style;

Recommended… Name Your Containers

css…
main {
  container: layout main / inline-size;
}
container-name [/ container-type]?
css…
@container layout (min-width: 40em) {
  .conditional { /* … */ }
}

@container main (min-width: 40em) {
  .conditional { /* … */ }
}

Finding Containers

  1. For each matched element
  2. Find the nearest ancestor that has…
    • Any required container name
    • Any required container types

Containers Can’t Self-Query

(That would introduce loops!)

Always Measuring an Ancestor

(can’t change what you measure!)

Enter the 36 Chambers [present, debug]

Always Measuring an Element

Bonus! Container Queries Measure Actual Styles

Computed values on the container element
Size queries, relative/var units [present, debug]

Grid Tracks & Flex Sizing?

No element to measure…

Three mud turtles
on a small log
surrounded by water.
Flexbox cards, with Container Queries [present, debug]
Container Query Bookstore [present, debug]
Container Query Blinds v2 [present, debug]

For legacy reasons… No Default Containers

(we shouldn’t rely on body style propagation)
css…
body > :is(header, main, footer, aside) {
  container: layout / inline-size;
}

also… Container Query Units

cqw | cqh | cqi | cqb | cqmin | cqmax

Default unit container The Small Viewport

On an example phone,
the large viewport fills the full screen
with all browser chrome hidden -
the small viewport fills the remaining space
when top and bottom browser chrome are visible
The Large, Small, and Dynamic Viewports by Bramus Van Damme
cat in a box, thinking
'OMG I have so many questions for this damn box'
Photo by Sahand Babali on Unsplash
css…
@container style(--colors: invert) {}

Always Queries Direct Parent

Unless you query a specific container-name

No containment required
Style query button themes [present, debug]
Support data from CanIUse.com on the css-container-queries-style feature
[Can I Use]

Style Queries… Only Custom Properties*

* for now **
** but maybe forever?

State Queries (???)

CSSWG issue for state queries
css…
@container state(stuck) {}
@container state(snapped) {}
@container state(overflowing) {}
Chrome Explainer [present, debug]
« resources
Bring this workshop to your company.
Slide Controls

View:

Navigate slides using the arrow-keys.