Love Frontend
Community of frontend developers
RU

What is it «Media Placeholder» and how to make it on web site? [ru]

Publication date: 02.07.2019

Media Placeholder is a (stub, empty place) for video or photo. And your media file will load in place of this stub. In this article, we will look at how to make simple placeholder with colored background and then with blurred photo on the background. What is it for?

When users read your article by mobile and they have a slow network connection, absence of media placeholder will be irritating.

User can start reading a text, but suddenly load an image, that brake all layout and reading text harshly scroll down.

animation of downloading article (preview) animation of downloading article

To analyze how to loading your article with a slow network connection, you can use Chrome dev tools. Tabs: Network -> Throttling and choose Slow 3G. So you can emulate a slow network.

screenshot of dev tools (preview) screenshot of dev tools

If you use a photo isn't in <img> tag, then you can make placeholder just writing two URL of photos in CSS property: background-image, a first small image, that will be load firstly, and then the original big picture:

CSS#image {
background-image: url("small-image.png"), url("big-image.png");
}

However, you should remember, that all photos inserted without <img> tag are affect semantics. Your images will not be index by search bots in the right way.

So let's consider the most common option of media placeholder.

For making placeholder we need to create a block element, that will have the same dimensions (width and height) as loaded later image. To see firstly this element, and then the big image will load in this block and it doesn't break the layout and doesn't move text. It's really simple:

HTML<div class="placeholder">
<img src="{{ url }}" />
</div>
CSS.placeholder {
width: 600px;
height: 300px;
background-color: darkseagreen;
}

But in the real world, we often need to image contain all allowed width and save aspect ratio of itself regardless of screen width. I.e when we read an article by different screen width, the image has to contain a certain width and stretch in height by correct aspect ratio. Animated example:

Note. No matter what width will be. The image is always saved its aspect ratio and the correct height. To make this trick, all you need to know is the aspect ratio of your photo.

You can easily make stretching block by CSS. You need to set absolute position to wrapper block, absolute position to image and use property: padding-bottom: {{ height / width }}

For example, if you have photo (900px × 600px) then aspect ratio is: 3:2 = 2 / 3 = 66.66%.

4:3 = 3 / 4 = 75% (800px × 600px)

1:1 = 1 / 1 = 100% (Square image, for example 500px × 500px)

You can use our simple form to calculate padding-bottom of parent (wrapper) block:

CSS .placeholder {
position: relative;
width: 100%;
height: 0;
padding-bottom: 66.66%;
background-color: darkseagreen
}

.placeholder img {
position: absolute;
width: 100%;
top: 0;
left: 0;
}

Also you can use CSS property calc: padding-bottom: calc(width / height)

As a result, we have something like this:

I specially made smooth animation, in real case image will be load sharply (by fragments).

Image and its parent block stretch and shrink to any width and always have the correct height.

But of course, it would be much nicer to see a preview photo before the original big image will be loaded. Note. Important thing. The preview image placeholder has to be very small-sized and has to has the same aspect ratio as the original big image. The smaller the image size, the faster it will be loaded. An example of this article small image weighs 822 bytes and has size: 28px × 19px. It's enough to make a nice background preview while the user waiting for a big image. It seems like this:

html<head>
<style>
.placeholder {
display: block;
position: relative;
width: 100%;
height: 0;
padding-bottom: 66.66%;
}
.placeholder img {
position: absolute;
width: 100%;
top: 0;
left: 0;
}
.placeholder .small-img {
background-size: cover;
filter: blur(10px);
}
</style>
</head>
<body>
<picture class="placeholder">
<img src="{{ url маленькой картинки }}" class="small-img">
<img src="{{ url большой картинки }}" class="big-img">
</picture>
</body>

In example we blurred photo by CSS property filter: blur(10px). The value of blur property can be any unit, for example, it can be percent. The larger the value, the greater the blur. Negative numbers are not allowed. CSS property filter is badly supported by browsers, however, this task justifies using this property because users with the old browser just will see not blurred preview images.

Also, you should remember, that these styles of parent block have to be loaded firstly on the page. So to the point, you can use a trick, that known as critical CSS. I.e the most important styles, that needed to the first painting of layout, will not be loaded in separate files. These styles should inserted inside <head> tag.

Also, there are small gotchas. When we use filter: blur() then blur goes beyond of borders. It seems like this:

To fix it you can simply set overflow: hidden to wrapper block. Also, you can meet solutions when developers add negative margins. For example, margin: -10px. Value is an equal blur.

Of course, the best solution is using backend libraries for images, that can generate small images for preview with the same aspect ratio.

Example image was made by Pexels, Pixabay

Enter your email to subscribe on news