{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-314", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/314", "wordCount": 1589, "segments": [{"start": 7.0, "text": "Hi, I'm Brandon, an engineer on the Safari team."}, {"start": 11.0, "text": "Today, I'm excited to share CSS Grid Lanes,"}, {"start": 15.0, "text": "a new layout mode for the web."}, {"start": 17.0, "text": "If you've ever wanted a design,"}, {"start": 18.0, "text": "where items of any size flow naturally into the space available,"}, {"start": 23.0, "text": "I'm going to show you how to build it — in just a few lines of CSS."}, {"start": 28.0, "text": "You may already know this pattern by another name: masonry layout."}, {"start": 32.0, "text": "Think of a waterfall — content flows naturally down the page in columns,"}, {"start": 37.0, "text": "each item settling into place beneath the last."}, {"start": 41.0, "text": "Flip the direction and it becomes a brick wall"}, {"start": 44.0, "text": "where items flow across the page in rows."}, {"start": 47.0, "text": "And the best part: you don't have to wait for it."}, {"start": 50.0, "text": "Grid Lanes is available today in Safari 26.4"}, {"start": 54.0, "text": "and behind a flag in other browsers."}, {"start": 57.0, "text": "If you've ever tried to build this layout, you know it's not straightforward."}, {"start": 61.0, "text": "You've probably reached for a JavaScript library,"}, {"start": 63.0, "text": "or improvised with floats or Flexbox"}, {"start": 66.0, "text": "that almost works — until it doesn't."}, {"start": 69.0, "text": "CSS Grid Lanes is built for exactly this."}, {"start": 73.0, "text": "To understand Grid Lanes, it helps to zoom out"}, {"start": 76.0, "text": "and think about what a layout mode actually does."}, {"start": 79.0, "text": "Every layout mode answers the same two questions:"}, {"start": 83.0, "text": "where do items go, and how much space do they get?"}, {"start": 86.0, "text": "Flexbox and Grid each answer those questions differently."}, {"start": 90.0, "text": "Grid Lanes is a new mode that fits somewhere in between."}, {"start": 94.0, "text": "Here's what I mean by that:"}, {"start": 96.0, "text": "Flexbox, for example, gives you one axis"}, {"start": 99.0, "text": "and a single lane of items flowing along it."}, {"start": 102.0, "text": "When items wrap, they continue flowing in the same direction."}, {"start": 106.0, "text": "You choose that direction: row or column,"}, {"start": 110.0, "text": "and items are placed one after another."}, {"start": 113.0, "text": "Switch to column, and the same rule applies —"}, {"start": 116.0, "text": "items flow top to bottom, wrapping into the next column over."}, {"start": 121.0, "text": "Grid takes a different approach."}, {"start": 124.0, "text": "Where Flexbox gives you one axis, Grid gives you two: columns and rows."}, {"start": 130.0, "text": "Grid places items into cells at the intersection of those tracks."}, {"start": 134.0, "text": "But when items have different aspect ratios,"}, {"start": 137.0, "text": "you end up with large empty areas where shorter items don't fill their cells."}, {"start": 142.0, "text": "Now, if these boxes were images, we've really only got three options,"}, {"start": 147.0, "text": "and none are great."}, {"start": 149.0, "text": "We could stretch each image to fill its cell,"}, {"start": 151.0, "text": "but that distorts them."}, {"start": 153.0, "text": "Or you could zoom in and fill the space,"}, {"start": 157.0, "text": "but now the image is overflowing the bounds of its container."}, {"start": 161.0, "text": "You may also crop the image,"}, {"start": 163.0, "text": "but you risk losing important information."}, {"start": 167.0, "text": "That's where Grid Lanes comes in."}, {"start": 169.0, "text": "It sits between Grid and Flex."}, {"start": 171.0, "text": "Instead of structuring across two dimensions like Grid,"}, {"start": 174.0, "text": "it structures just one, and leaves the other free."}, {"start": 178.0, "text": "But unlike Flex, where content flows in a single lane and wraps down the page,"}, {"start": 183.0, "text": "Grid Lanes distributes content across multiple lanes."}, {"start": 188.0, "text": "The result is a tightly packed, staggered layout"}, {"start": 191.0, "text": "that preserves each item's natural proportions."}, {"start": 195.0, "text": "Items are placed one by one, and each one lands"}, {"start": 198.0, "text": "in whichever column leaves it closest to the top."}, {"start": 201.0, "text": "That's why earlier items sit higher up, and later items fill in below."}, {"start": 207.0, "text": "So far, everything's been images."}, {"start": 209.0, "text": "But Grid Lanes isn't picky, it works with any kind of content."}, {"start": 214.0, "text": "Try adding some text."}, {"start": 215.0, "text": "Each block wraps to fit its column, and the browser sizes the heights for you."}, {"start": 220.0, "text": "And if something needs to stand out, like a headline,"}, {"start": 223.0, "text": "you can span it across columns."}, {"start": 226.0, "text": "And it doesn't matter what you change - different shapes, different sizes,"}, {"start": 231.0, "text": "or a totally different design."}, {"start": 232.0, "text": "Grid Lanes handles it."}, {"start": 235.0, "text": "So you've seen what Grid Lanes can do."}, {"start": 237.0, "text": "Now, let's build one."}, {"start": 239.0, "text": "We start with a new display type — grid-lanes."}, {"start": 242.0, "text": "Then we define the columns."}, {"start": 244.0, "text": "grid-template-columns sets the number of tracks"}, {"start": 247.0, "text": "and how wide each track becomes."}, {"start": 249.0, "text": "You'll notice the fr unit here."}, {"start": 251.0, "text": "fr stands for 'fractional unit'."}, {"start": 254.0, "text": "It tells the browser to take the available space in the container"}, {"start": 257.0, "text": "and divide it up into fractions."}, {"start": 259.0, "text": "So, this piece of code says to divide the space,"}, {"start": 262.0, "text": "into three equal fractions,"}, {"start": 264.0, "text": "creating three columns all equally sized."}, {"start": 267.0, "text": "And add a gap of 10px, just like you do with Grid."}, {"start": 271.0, "text": "Want to flip this into a brick wall instead?"}, {"start": 274.0, "text": "Just swap the columns for rows."}, {"start": 278.0, "text": "Replace the grid-template-columns property with grid-template-rows"}, {"start": 282.0, "text": "and watch the layout turn into a brick wall."}, {"start": 285.0, "text": "The only catch: you pick one direction - not both."}, {"start": 289.0, "text": "That's Grid Lanes in three lines of CSS."}, {"start": 292.0, "text": "But those three lines give you more control than you might expect."}, {"start": 297.0, "text": "Let me show you what I mean."}, {"start": 299.0, "text": "I start here with three equal columns."}, {"start": 302.0, "text": "But my columns don't have to be equal."}, {"start": 304.0, "text": "Here, the center column"}, {"start": 306.0, "text": "takes up twice the space of the left and right columns."}, {"start": 309.0, "text": "Now, instead of picking the number of columns yourself,"}, {"start": 313.0, "text": "let the browser decide."}, {"start": 315.0, "text": "auto-fill creates as many columns as will fit."}, {"start": 318.0, "text": "minmax() says each one should be at least 200 pixels,"}, {"start": 322.0, "text": "but can grow to fill the space."}, {"start": 324.0, "text": "Take that same idea,"}, {"start": 325.0, "text": "but now with a repeating pattern of narrow and wide columns."}, {"start": 330.0, "text": "Honestly, what I love most is how much you can do"}, {"start": 333.0, "text": "with just a few lines of CSS."}, {"start": 336.0, "text": "Once you start exploring, I think you'll be amazed too."}, {"start": 340.0, "text": "So that's the layout."}, {"start": 341.0, "text": "But Grid Lanes also lets you shape individual items."}, {"start": 345.0, "text": "Let's start again with a simple grid-lanes container"}, {"start": 348.0, "text": "with 3 equally sized columns."}, {"start": 351.0, "text": "I'd love to give the orange colored item more space."}, {"start": 353.0, "text": "With Grid Lanes, I can do that using properties that already exist in Grid."}, {"start": 359.0, "text": "With grid-column: span 2; the item stretches across two columns,"}, {"start": 363.0, "text": "and the rest of the layout adjusts around it."}, {"start": 367.0, "text": "Or, place it exactly where you want it."}, {"start": 370.0, "text": "Here I set the item to start in column 2, spanning columns 2 and 3."}, {"start": 375.0, "text": "Notice you can control column placement, but not row."}, {"start": 379.0, "text": "Grid Lanes decides the row for you."}, {"start": 383.0, "text": "I've turned one of our items into a recipe card that spans two columns."}, {"start": 387.0, "text": "Inside the card is an image and some text,"}, {"start": 391.0, "text": "neither of which participate in the Grid Lanes layout."}, {"start": 395.0, "text": "Add display: grid-lanes and grid-template-columns: subgrid to the card,"}, {"start": 399.0, "text": "and its contents join the parent layout as their own items."}, {"start": 403.0, "text": "The image takes one column, the text takes the other,"}, {"start": 406.0, "text": "each sized to its content."}, {"start": 409.0, "text": "And you can nest them however you like."}, {"start": 412.0, "text": "A regular grid inside a Grid Lanes container,"}, {"start": 415.0, "text": "or the other way around."}, {"start": 417.0, "text": "The same tools and syntax you already know carry over,"}, {"start": 421.0, "text": "so Grid Lanes just fits right in."}, {"start": 424.0, "text": "Grid Lanes places each item in whichever column is the shortest."}, {"start": 428.0, "text": "Most of the time, that looks great."}, {"start": 431.0, "text": "But sometimes… it doesn't quite feel right."}, {"start": 435.0, "text": "That's where flow tolerance comes in."}, {"start": 437.0, "text": "The browser normally picks the shortest column for the next item."}, {"start": 441.0, "text": "Flow tolerance is the dial that loosens or tightens that rule."}, {"start": 445.0, "text": "I'll break that down."}, {"start": 447.0, "text": "Looking at this layout,"}, {"start": 449.0, "text": "the two items in a row here are almost the same height, but not quite."}, {"start": 453.0, "text": "That second item is a few pixels shorter than item 1."}, {"start": 457.0, "text": "That means the area under item 2 is closer to the top of my container,"}, {"start": 462.0, "text": "so the second column is where the browser will place my next item,"}, {"start": 466.0, "text": "and item 4 will fill in the first column."}, {"start": 470.0, "text": "This makes our item layout go from left-to-right on the first row,"}, {"start": 473.0, "text": "and right-to-left on our last row."}, {"start": 476.0, "text": "The difference between tab order and how the content appears visually"}, {"start": 479.0, "text": "will impact accessibility for people and can create a confusing experience."}, {"start": 484.0, "text": "Now turn flow-tolerance on."}, {"start": 487.0, "text": "We're back to two items in two columns, but flow-tolerance changes the rules."}, {"start": 492.0, "text": "For each new item, the browser asks the same question:"}, {"start": 495.0, "text": "is the taller column less than the shorter column plus flow-tolerance?"}, {"start": 500.0, "text": "For item 3, yes - the gap is within tolerance,"}, {"start": 504.0, "text": "so it fills column 1."}, {"start": 506.0, "text": "But now column 1 is even taller."}, {"start": 509.0, "text": "For item 4, the gap is too big to ignore,"}, {"start": 512.0, "text": "so it drops into the shorter column: column 2."}, {"start": 516.0, "text": "By default, Grid Lanes uses a flow-tolerance of 1em."}, {"start": 521.0, "text": "Try different flow-tolerance values to find what works for your content."}, {"start": 526.0, "text": "Flow-tolerance is great when it works for your content,"}, {"start": 529.0, "text": "but the flip side of giving the browser flexibility"}, {"start": 532.0, "text": "is that sometimes the result may surprise you."}, {"start": 535.0, "text": "And when that happens,"}, {"start": 537.0, "text": "pop open Web Inspector to figure out what's going on."}, {"start": 540.0, "text": "The good news is, Web Inspector has full support for Grid Lanes."}, {"start": 544.0, "text": "You get lines showing your columns and rows."}, {"start": 547.0, "text": "You get order numbers projected right over each item,"}, {"start": 550.0, "text": "so you can see exactly how items are placed."}, {"start": 553.0, "text": "And it even draws in the gaps between items."}, {"start": 556.0, "text": "All of that, just by turning on the overlay."}, {"start": 561.0, "text": "CSS Grid Lanes gives you a layout that used to require JavaScript"}, {"start": 565.0, "text": "in just a few lines of CSS."}, {"start": 568.0, "text": "It builds on what you already know from Grid,"}, {"start": 570.0, "text": "and it adapts to your content, not the other way around."}, {"start": 574.0, "text": "It's a great addition to the web platform,"}, {"start": 576.0, "text": "and I can't wait to see what you build with it."}, {"start": 580.0, "text": "Check out the Grid Lanes Field Guide the WebKit team created for you"}, {"start": 583.0, "text": "for detailed walkthroughs and interactive demos"}, {"start": 586.0, "text": "where you can experiment with every property we covered today."}, {"start": 590.0, "text": "Try grid-lanes in your own projects."}, {"start": 592.0, "text": "It's been available since Safari 26.4,"}, {"start": 595.0, "text": "and we think it can genuinely change how you approach image-heavy layouts."}, {"start": 600.0, "text": "And share your feedback."}, {"start": 602.0, "text": "We'd love to hear how grid-lanes is working for you"}, {"start": 604.0, "text": "and what you'd like to see next."}, {"start": 607.0, "text": "To learn about all of the other features coming to Safari, be sure to check out"}, {"start": 611.0, "text": "\"What's new in WebKit for Safari 27\"."}, {"start": 613.0, "text": "Thanks for watching and have a great WWDC!"}]}