How to achieve layout composition in React

Rate this content
Bookmark

Using CSS in this age of components is difficult. Many tools have been created to help us with this problem, but they all fall short in the one problem that tooling can never solve: Which component should be in charge of which styles? In this talk, we will go over strategies on how to build layouts in a composable way.

This talk has been presented at React Summit 2022, check out the latest edition of this React Conference.

FAQ

Travis Waithmer works for Plex, an online streaming platform that allows users to stream personal media and curated video on demand.

The Bedrock Layout Primitives is a layout library created and maintained by Travis Waithmer, designed to simplify web layout composition in React applications.

CSS layout can be componentized in React by using layout primitives such as stack, inline, split, cover, and frame components, which help in achieving efficient layout composition through reuse and modularization.

Travis Waithmer mentioned several layout components including stack, inline, split, cover, and frame. These components are designed to manage specific layout needs like stacking elements, aligning items inline, and controlling aspect ratios.

More information about Bedrock Layout Primitives can be found at the website bedrocklayout.dev.

The inline cluster component in React is used to arrange navigation items in a row that automatically adjusts to clustering when the width doesn't allow all items to stay in a single row, mimicking text wrapping behavior.

The cover component improves card layout design by allowing specific alignment of elements like headings and images while ensuring descriptions are vertically centered, maintaining a consistent and visually appealing structure across cards.

Travis Waith-Mair
Travis Waith-Mair
8 min
21 Jun, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This talk discusses achieving layout composition in React using Bedrock Layout Primitives. By componentizing CSS layout, complex layouts can be achieved and reused across different components. The talk also covers the challenges of achieving complex layouts, such as card lineups, and provides solutions for maintaining alignment and responsiveness. The BedrockLayout primitive library simplifies web layouts and offers flexibility in composing layouts.

1. Achieving Layout Composition in React

Short description:

Hello, React Summit! In this talk, I will discuss achieving layout composition in React using Bedrock Layout Primitives. By componentizing CSS layout, we can create layout primitives like stack, inline, split, cover, and frame. These components can be combined to achieve complex layouts, and can be reused across different components. The BedrockLayout primitive library simplifies web layouts and offers flexibility in composing layouts. Check out bedrocklayout.dev for more information.

Hello, React Summit, and welcome to my talk on how to achieve layout composition in React. My name is Travis Waithmer, and you can find me at Twitter, at Travis Waithmer, all in my account on Canvas, or on my blog at non-traditional.dev.

Now, a little bit about myself, I work for Plex, which is an online streaming platform that allows you to stream both your video from your personal media as well as video on demand that we curate for you. And we're hiring, of course, Plex.tv slash careers. I'm also the creator and maintainer of Bedrock Layout Primitives. It's a layout library designed to make your React apps easier to layout on the web. And that's the point of this talk, how do we achieve layout composition? How do we use React's composition model in our web layout?

Well, let's look at this hero layout. This is probably something all of us have made some time in our career. Now, a naive way to approach this is to approach this at the component level. We have a hero container, we have a hero top, left, right, and so on. And this is the way we're taught to write our CSS, from the top down, with an exception-based approach. Now, this, unfortunately, gets really hard to scale across our applications, so we start reusing our components. Now, we can have CSS methodologies that assist us, but they only get us so far. They help us manage our style sheets at scale, but when we approach each component and, specifically, the layout of each component, as something unique, we're missing a fantastic opportunity for layout reuse. So what if I told you CSS layout could be componentized? What if we created some layout primitives? For example, what if we had a stack component that stacked things on top of each other? An inline that put things in line with spaces in between? A split component that split things from just the left and the right-hand side, evenly across the parent's width? What if we had a cover component that covered an area and vertically-centered the children inside? And a frame component that took things like media, or images, or any of its children and forced it into an aspect ratio? Now, these individually can only do one unique thing each. But when we put them together, we can achieve that same hero layout. We can have an inline, a couple stacks, a cover, frame, split. Through careful composition, we've now achieved that hero layout. But that's not all. We can put it under JSX like this and just use the React composition. And then we can go ahead and use that in our other components, such as a signup form, a blog post feed, a feature page. All of these can use those same exact components, those same exact layouts, but just composed in different ways to achieve their individual layouts. And that's exactly what the BedrockLayout primitive library is designed to do. It's the low dash of web layouts. We can then take... And if you want to find out more, it's at bedrocklayout.dev. But let's take, for example, just a simple stack component. We probably all have something like this, where we need to put some consistent spacing on top of other items. Well, using just one of the layout components from Bedrock, the stack, for example, we can achieve this subscribe component. Now, another common pattern is we need to do things kind of like the way our paragraph works on the web.

2. Achieving Complex Layouts in React

Short description:

Whereas we run out of room, our words will automatically wrap to the next row according to the justification that we set. The inline cluster component comes in handy for inline content that automatically wraps. For more complex layouts like a card lineup, we need to ensure that each card takes up the full height of the row, while maintaining aligned images and headings. The description should always be vertically centered. Images should maintain an aspect ratio and be cut off if necessary. Cards should be in a responsive grid with a minimum column width, wrapping and adjusting columns as needed.

Whereas we run out of room, our words will automatically wrap to the next row according to the justification that we set. So that's where the inline cluster component comes in handy. We can have things inline. But as we run out of room, it will automatically wrap according to the justification.

And here's what that looks like in code. We have our menu component that obviously composes that right-hand side inside of it. And we just use an inline cluster to put all of our navigation items in a row, and then they will cluster once the width doesn't allow it to all stay in one single row.

So what about something much more complicated like a card lineup? This seems pretty simple at first, but there's some gotchas to this. Each one of these cards needs to take up the full height of the row that it's in, but the image and headings for all the cards need to line up. But the description, no matter how big or small, needs to still be vertically centered inside each of these cards.

Now besides that, all the images need to maintain an aspect ratio, and the images need to be cut off to maintain that aspect ratio. And then finally, each of these cards needs to be in a responsive grid, they need to maintain a minimum column width, and if they can't maintain that column width and keep them all in the same row, we need to start wrapping in and adjusting the columns accordingly.

So in the code, we could write our card component using a cover, which allows us to specify the top and the bottom. In this case, the top is an h3 and the bottom is using a frame component to force the aspect ratio to be at a 16 by 9, and then we have our description which will be vertically centered inside that cover. And then we're setting that height to be 100% so that way it will always be the full height of the row that it's in. And then we will use all these cards inside of a grid and we can set the minimum item width to 40 ch so that way the columns will be as wide as they possibly can to get everything inside. But if they can't fit them all in and without having at least a 40 ch column, it will then start wrapping and optimize that.

Now that's all the time I have for you today. You can check out more at bedrock-layout.dev or you can go to my course over at newline.co where I teach you more about composing layouts in React.