A presentation at Pixel Pioneers in in Bristol, UK by Michelle Barker
Modern CSS Layout is Awesome!
Senior Front End Developer at
💖 The web’s most beautiful language
css-irl.info
🤕 fi Tables Floats Clear xes
🤕 fi Tables Floats Clear xes 🙂 Flexbox Grid Multi-column Viewport units Custom properties
“Material honesty” Jeremy Keith (Resilient Web Design)
🤕 fi Tables Floats Clear xes 🙂 Flexbox Grid Multi-column Viewport units 🤯 min(), max(), clamp() Logical properties and values Container queries Subgrid :has() Intrinsic sizing…
It’s time to re-learn CSS layout!
“Be the browser’s mentor, not its micromanager” Andy Bell
You might have missed…
Aspect-ratio
Before ☹ .aspect-box { position: relative; } .aspect-box::before { display: block; content: ”; width: 100%; padding-bottom: calc(100% / (var(—-aspect-ratio, 3 / 2))); } .aspect-box > :first-child { position: absolute; top: 0; right: 0; bottom: 0; left: 0; } After ☺ .aspect-box { aspect-ratio: 3 / 2; }
codepen.io/michellebarker/pen/bGLpzjd
codepen.io/michellebarker/pen/bGLpzjd
Flex gap
The problem
The problem
The problem
The solution ul { gap: 1em 0.5em; }
New and improved viewport units
The problem
The problem
The solution 100svh 100svh
The solution 100lvh 100lvh
The solution 100dvh 100dvh
Overlaying elements (Putting things on top of each other)
figcaption { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
figcaption { position: absolute; inset: 0; }
figcaption { position: absolute; inset: 50% 50% 0 0; }
figcaption { position: absolute; inset-block: 50px; }
figcaption { position: absolute; inset-inline: 50px; }
figcaption { position: absolute; inset: auto -2rem -2rem auto; }
- { grid area: 1 / 1; } }
fi Intrinsic sizing min-content max-content t-content
div { width: 300px; }
div { width: min content; }
div { width: min content; }
div { width: max content; }
i div { width: f t content; }
i div { width: f t content; }
Subgrid
.card { grid-row: span 3; display: grid; gap: 0; grid-template-rows: subgrid; }
.card { grid-row: span 3; display: grid; gap: 0; grid-template-rows: subgrid; }
Responsive layouts
.card grid { display: grid; gap: 1rem; grid template columns: repeat(auto f ll, minmax(18rem, 1fr)); }
.card grid { display: grid; gap: 1rem; grid template columns: repeat(auto f ll, minmax(min(18rem, 100%), 1fr)); }
Container queries
main, aside { container: layout / inline size; }
@container layout (inline size > 700px) { .card grid { grid template columns: repeat(2, 1fr); } }
@container layout (inline size > 1200px) { .card grid { grid template columns: repeat(3, 1fr); } }
@container layout (inline size > 1200px) { .card grid { grid template columns: repeat(3, 1fr); } }
li { container: card / inline size; }
@container card (inline size > 450px) { .card { display: grid; grid template columns: 1fr 1fr; } }
@container card (inline size > 450px) { .card { display: grid; grid template columns: 1fr 1fr; } }
@container card (inline size > 450px) { .card { display: grid; grid template columns: 1fr 1fr; } }
}
_ _ }
Container-relative units cqw query container width cqh query container height cqi query container inline size cqb query container block size cqmin smallest of ‘cqi’ or ‘cqb’ cqmax largest of ‘cqi’ or ‘cqb’
Browser support
container-query-poly ll fi fi github.com/GoogleChromeLabs/container-query-poly ll
codepen.io/michellebarker/pen/yLxKPYW
utopia.fyi
:has()
.grid blockquote { grid-column: 2 / span 4; grid-row: 2 / span 2; text-align: center; }
.grid:has(img) img { grid-row: 1 / span 2; grid-column: 1 / span 3; } .grid:has(img) blockquote { grid-row: 2 / span 2; grid-column: 3 / span 4; text-align: left; }
Anchor positioning
/ < . . . / < / <
<div class=”wrapper”> <button> button> <div class=”tooltip”> … div> div>/ < . . . / < .wrapper { position: relative; } / <
<div class=”wrapper”> <button> button> <div class=”tooltip”> … div> div>/ < . . . / < .tooltip { position: absolute; } / <
<div class=”wrapper”> <button> button> <div class=”tooltip”> … div> div>Anchor Any other element
button { anchor name: } anchor_1;
.tooltip { position: absolute; position anchor: anchor_1; }
.tooltip cite { position: absolute; position anchor: anchor_1; inset }
.tooltip { position: absolute; top: anchor( anchor_1 bottom); right: anchor( anchor_1 right); }
.tooltip { position: absolute; top: anchor( anchor_1 150%); right: anchor( anchor_1 -150%); }
@position try pos right { left: anchor(var( anchor name) left); }
@position try pos right { left: anchor(var( anchor name) left); }
@position try pos right { left: anchor(var( anchor name) left); }
.tooltip { position try options: pos right, pos left; position try order: most width; }
.tooltip { position try options: pos right, pos left; position try order: most width; }
codepen.io/michellebarker/pen/jOomKRE
youtube.com/watch?v=XaO2mZnIOzs
codepen.io/michellebarker/pen/pomWryN
codepen.io/michellebarker/pen/pomWryN
codepen.io/michellebarker/pen/pomWryN
Masonry
shorturl.at/LpCUW
Let’s start building creative layouts again.
💖 Thank you css-irl.info
The past few years have brought us a tonne of new CSS features to help solve common layout challenges. In this session, we’ll delve into some real-world use cases for new features like container queries and the :has() pseudo class.
We’ll explore how to combine these with more familiar features in order to build robust, flexible and creative layouts that respond to both content and context, and take a peek into the near future to see what’s coming next for CSS layout.