const regions = getRegionsInOrder();

function flowContent() {

const regions = getRegionsInOrder();

let remainingBlocks = [...contentBlocks];

regions.forEach(region => {

let availableHeight = region.clientHeight;

let usedHeight = 0;

let fittedBlocks = [];

for (let block of remainingBlocks) {

const blockHeight = measureContent(block, region);

if (usedHeight + blockHeight <= availableHeight) {

fittedBlocks.push(block);

usedHeight += blockHeight;

} else {

break; // This block doesn't fit

}

}

// Render fitted content

region.innerHTML = fittedBlocks.map(renderBlock).join('');

// Remove fitted blocks from remaining

remainingBlocks = remainingBlocks.slice(fittedBlocks.length);

});

}

Creativity or Complexity?

A technical deep dive into recreating print journalism layouts with JavaScript, AI assistance, and a healthy dose of experimentation

I didn't expect to spend weeks reverse-engineering magazine layouts when I started this project. But with our current prototypes, we have a system that actually works. And the only reason it exists is because I had an AI coding partner who could write the complex JavaScript I definitely couldn't.

The Problem: CSS Regions Didn't Happen

The web was supposed to get magazine-style layouts. Back around 2014, there was this beautiful CSS specification called Regions. It would have let content flow naturally between different containers scattered across your page, exactly like text flows between columns in a magazine spread. But with vastly more creative control than just using CSS columns.

But browsers never fully adopted it. Safari supported it briefly. Chrome experimented with it. Then it got deprecated, and we were stuck with the same boring grid-based layouts that make every website look identical.

Meanwhile, print designers were creating these incredible, dynamic layouts where text could snake around images, flow between scattered text boxes, and create visual hierarchy that actually guided your eye through the story. The web felt static and lifeless in comparison. It certainly felt less aesthetic.

So I wondered: could we fake it with JavaScript? I didn't actually know if we could, or even how to do it, but I know how to ask questions. And that felt like a good place to start.

The Core Concept: Measuring and Flowing

The basic idea is deceptively simple. Instead of relying on CSS to flow text between regions, we use JavaScript to:

  1. Measure how much content fits in each container
  2. Fill containers progressively until they overflow
  3. Move the overflow to the next container
  4. Repeat until all content is placed
  5. Recalculate everything when the viewport changes

But the devil is in the details.

Technical Implementation

Content as Structured Data

First, we had to rethink how content works. Instead of writing HTML directly, we structure everything as JSON:

{
  "blocks": [
    {
      "id": "intro-1",
      "type": "paragraph",
      "text": "This is a paragraph...",
      "keepWithNext": false,
      "orphanProtection": 2
    },
    {
      "id": "heading-1",
      "type": "heading",
      "level": 2,
      "text": "A Bold Subheading",
      "keepWithNext": true,
      "breakBefore": false
    }
  ]
}

This structure gives us semantic control over how content breaks:

  • keepWithNext: Prevents orphaned headings
  • orphanProtection: Ensures minimum lines stay together
  • breakBefore: Forces content to start in a new region

The Measurement Challenge

The trickiest part was measuring text accurately. You can't just count characters, because different fonts, sizes, and line heights all affect how much space text actually takes.

The solution: ghost rendering. For each region, we create an invisible clone with identical styling, fill it with content, and measure the actual pixel height:

function measureContent(block, targetRegion) {
  // Create invisible test container
  const testDiv = document.createElement('div');
  testDiv.className = targetRegion.className;
  testDiv.style.visibility = 'hidden';
  testDiv.style.position = 'absolute';
  testDiv.style.width = getComputedStyle(targetRegion).width;

  // Render content and measure
  testDiv.innerHTML = renderBlock(block);
  document.body.appendChild(testDiv);

  const height = testDiv.scrollHeight;
  document.body.removeChild(testDiv);

  return height;
}

This gives us pixel-perfect measurements that account for real CSS styling, font loading, and responsive breakpoints.

The Flow Algorithm

Once we can measure content, the flow logic becomes manageable:

function flowContent() {
  const regions = getRegionsInOrder();
  let remainingBlocks = [...contentBlocks];

  regions.forEach(region => {
    let availableHeight = region.clientHeight;
    let usedHeight = 0;
    let fittedBlocks = [];

    for (let block of remainingBlocks) {
      const blockHeight = measureContent(block, region);

      if (usedHeight + blockHeight <= availableHeight) {
        fittedBlocks.push(block);
        usedHeight += blockHeight;
      } else {
        break;   // This block doesn't fit
      }
    }

    // Render fitted content
    region.innerHTML = fittedBlocks.map(renderBlock).join('');

    // Remove fitted blocks from remaining
    remainingBlocks = remainingBlocks.slice(fittedBlocks.length);
  });
}

The actual code to make it all work is surprisingly simple, but building it like this never occurred to me.

Responsive Reflow

The magic happens on window resize. When the viewport changes, we clear all regions and rerun the entire flow algorithm. Content automatically redistributes based on the new dimensions:

window.addEventListener('resize', debounce(() => {
  clearAllRegions();
  flowContent();
}, 100));

This means a three-column desktop layout can gracefully reflow to two columns on tablet, then a single column on mobile—all while maintaining the semantic integrity of headings and paragraphs.

Region Definition: The Layout Canvas

Regions are just HTML containers with a data-flow-order attribute:

<div class="region w-1/3 h-96" data-flow-order="1"></div>
<div class="region w-1/2 h-64" data-flow-order="2"></div>
<div class="region w-full h-48" data-flow-order="3"></div>

The beauty is that regions can be positioned anywhere on the page using any CSS technique—Flexbox, Grid, absolute positioning, whatever. The JavaScript just flows content through them in order, regardless of their visual arrangement.

Small Screen Complications

For responsive behavior, we had to get clever. On large screens, the JavaScript flow system kicks in. On smaller screens where magazine layouts become impractical, we disable the flow and fall back to traditional CSS layout:

/* Large screens: JS flow active */
@media (min-width: 1024px) {
  .region { height: var(--region-height); }
}

/* Small screens: traditional layout */
@media (max-width: 1023px) {
  .region {
    height: auto !important;
    display: block;
  }
}

I like to imagine Claude looks like Data from Star Trek: TNG. Also, I used Gemini to make this image, and Gemini doesn't know what Data looks like apparently.

What Did We Learn?

AI and human collaboration illustration

Like all good experiments, it's less about what you did and more about what you learned. The goal of this wasn't to do the thing, it was to learn if it was even possible, how it's possible, and how we can use what we learned in the future.

Here's the thing: I couldn't have built this alone. The JavaScript measurement and flow logic is genuinely complex—dozens of edge cases, browser quirks, and performance considerations I never would have anticipated.

But I had Claude.

Instead of spending weeks learning the intricacies of DOM measurement and text rendering, I could focus on

the creative vision and let AI handle the technical implementation. My process looked like this:

  • Describe the problem conceptually ("I want text to flow between scattered containers")
  • Iterate on solutions through conversation
  • Generate comprehensive code with detailed prompts
  • Debug and refine via prompting in Cursor

The AI could instantly generate robust solutions for problems like:

  • Binary search algorithms for finding text cutoff points
  • Debounced resize handlers for performance
  • Cross-browser CSS measurement techniques
  • Semantic content parsing and rendering

What would have been weeks of research and trial-and-error became hours of directed problem-solving.

The Results: Four Unique Experiments

Using this system, we built four completely different magazine-style layouts:

  • The Intro: Classic three-column flow with dramatic typography
  • Algorithm Sadness: Emotional, flowing narrative layout
  • Horizontal Scroll: Full-viewport horizontal storytelling
  • This Technical Deep-dive: Traditional but enhanced layout

Each page uses the same underlying flow system but with completely different visual treatments—different fonts, colors, spacing, and region arrangements. The content JSON stays semantic and clean while the CSS handles all visual styling.

The Experiment Was a Success

It actually works. Magazine-style layouts are possible on the web, even without CSS Regions. The performance is good, the responsive behavior is smooth, and the visual results feel genuinely different from typical websites.

AI development is transformative. Complex technical challenges that would normally require specialized expertise can be tackled through conversation and iteration with AI tools. The barrier to experimental development just got much lower.

Creative constraints breed innovation. Having to structure content as semantic blocks and think about region flow actually improved our writing and layout decisions.

But Was it Worth It?

That's the question, right? Did we actually learn anything valuable? Did we discover a new way to enhance creativity? I'm not sure sure.

The Broader Implications

While we proved this was doable, I don't know that I proved it was worth it. It took a lot of time, and responsiveness created a multitude of issues we had to work through. And, while we worked through them, it was about 200% more work than just creating any other "normal" site.

But that doesn't mean it isn't relevant. It's more of an edge case in my mind. I may still do it if I were creating a site that was creative for the sake of creativity. But, how often are any of us making those? How often do we just build a site for fun, with no care of concern on development time and usability?

Probably never.

But it was educational. Beyond the implications of writing code, I learned a lot more about working with AI. My prompts improved drastically, and my ability to understand when it needs context, and what that context should be, greatly improved. So, it was a valuable lesson. Just not the one I expected to learn.

This was more a lesson in AI, and the future of engineering websites and apps. The development process was rapid, and we could overcome complexities in a couple of short prompts. The way we work is changing forever.

In the end, though, I think I'll just continue building things the old fashioned way. I'm not trying to win any Awwwards any time soon. I'm just trying to do good work.

Thank you for coming to TED Talk.