This video is available to students only

The Frame Component

In this lesson, we will build the Frame primitive, which frames out a visual media, like an image or video, and forces it into the aspect ratio needed for the design without distorting the image.

Images on the web are surprisingly tricky. A whole course could be devoted to best practices for images on the web, but from a layout point of view, one of the more difficult parts to deal with is the size and aspect ratio. The images we use are rarely the same size and aspect ratio as our web page's design. This problem is compounded by the need to support multiple viewports that our image will need to load. We typically deal with the size issue by making the image size responsive - we can set the max-width of the image to 100%, which we did in our CSS Reset.

However, dealing with aspect ratios is not as simple. Images have an intrinsic aspect ratio based on the actual width and height of the image file. If we try to force the image into a box of a different aspect ratio, then the image becomes skewed and deformed.

We need a way to not just control the size, but also the aspect ratio, by cropping the image where it is too tall or too wide for the aspect ratio we need.

In this lesson, we will build the Frame primitive, which frames out a visual media, like an image or video, and forces it into the aspect ratio needed for the design, without distorting the image.

The problem: the New Arrivals#

In this lesson, we are going to build a "New Arrivals" card, like this:

New arrivals red-line

In the above widget, the image is cropped at a 1:1 aspect ratio, or in other words, a square. It also needs to be responsive to the size of the parent container by growing or shrinking accordingly.

The solution#

Here is how our code starts out. You can follow along at the starter project over at

And this is how it looks:

New arrivals step-0

So let's start building our Frame primitive:

It may seem like a lot is going on here, but it isn't. First, we are setting the Frame primitive to have a relative position and setting the width and height to 18rem. These settings will give us an 18rem by 18rem square box.

Next, we are selecting all the direct children, setting the position to be absolute, and setting the top, bottom, left, and right properties to 0. Zero is one of those unique values in CSS that you never have to give the unit of. That is because zero of any unit, be it rem, px, or vw, will always still be zero. The value you set to each of these properties is how much you want to offset from the top or bottom, for example. By setting these properties to zero, we are effectively pinning the children to the outer div element, ensuring the child will be the same size as the outer div that is wrapping the image. Then we are setting the width and height to be 100% to force any media object to fit in the box.

Now we just need to wrap our img tag with our Frame primitive, like this:

And our New Arrivals component looks like this:

New arrivals step-1

We have a square now, but the image is distorted as we've forced it into a square box. The image is also too small in this view. In other views it will be too large. What we need is a way to keep the aspect ratio, without hard-coding the size itself.


This page is a preview of Composing Layouts in React

Start a new discussion. All notification go to the author.