Skip to content
Created: February 22, 2016

"Layout Tips" Automatically expand the element height before the image is loaded ​

This is actually a Classic front-end layout techniques , you can make the picture It will take up space before it is loaded. , to avoid page jitter or "layout shift". 👉 This type of problem is very common in image list, lazy loading, and skeleton screen scenarios.

Below we explain the ideas step by step + various implementation solutions (including Vue actual combat).

1. Why do we need to "expand the height before loading the image"? ​

By default, pictures <img> Before loading is complete, the browser Don't know its height , So its height will be set to 0, and it will be re-rendered after the image is loaded.

💥 This will result in:

  • Page content jitter (Layout Shift)
  • Poor user experience (especially in lazy loading or waterfall flow)

So our goal is:

Before the image is loaded, occupy the space in advance to keep the layout stable.

2. Core idea: reserve space based on “Aspect Ratio” ​

The most critical parameter: The aspect ratio of the image.

Assuming the image aspect ratio is 16:9, We just need to calculate the corresponding height based on the width of the container in advance and open up the space.

3. Several implementation methods ​

✅ Method 1: CSS fixed ratio space occupancy (recommended🔥, the simplest) ​

css
.img-box {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9; /* 撑开比例 */
  background-color: #f5f5f5; /* 占位底色 */
}

.img-box img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

📘 Description:

  • aspect-ratio is a modern CSS property that automatically calculates height proportionally;
  • The container has a height before the image is loaded;
  • object-fit: cover ensures that the image is not deformed.

✅ Advantages:

  • No JS required;
  • Automatically adapt;
  • Good performance;
  • Widely supported by modern browsers (Chrome/Safari/Firefox/Edge).

🧩 Method 2: Padding percentage occupancy method (compatible with old browsers) ​

When aspect-ratio is not supported, the classic "padding percentage" trick can be used.

html
<div class="img-wrapper">
  <img src="xxx.jpg" alt="">
</div>
css
.img-wrapper {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 9/16 = 0.5625 → 16:9 比例 */
  background: #f0f0f0;
}

.img-wrapper img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

📘 Principle: The percentage of padding-top is calculated based on the container width, Therefore, a box with a "fixed proportion" can be dynamically propped up.

✅ Compatibility: Supports all major browsers, including older versions of IE.

🧩 Method 3: Declare the original size of the image in HTML (pure HTML technique) ​

If you know the original size of the image, such as 800×600, You can declare width / height directly in the <img> tag:

html
<img src="xxx.jpg" width="800" height="600" alt="封面图">

📘 Description:

  • The browser will automatically calculate the aspect ratio based on these two properties;
  • The image can be occupied before loading;
  • HTML native support, best performance.

✅ Advantages:

  • No additional CSS required;
  • Consistent with the aspect-ratio principle;
  • Google Lighthouse is highly recommended.

⚠️ Note:width / height are the original pixels of the image and will not affect the final display size. The browser will scale it proportionally.

Method 4: Vue dynamically calculates image proportions (suitable for lazy loading) ​

When the image ratio is not fixed, it can be calculated dynamically:

vue
<template>
  <div
    class="img-box"
    :style="{ paddingTop: aspectRatio ? aspectRatio + '%' : '56.25%' }"
  >
    <img v-if="loaded" :src="src" @load="onLoad" alt="">
  </div>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({ src: String })
const loaded = ref(false)
const aspectRatio = ref(56.25) // 默认 16:9

const onLoad = (e) => {
  const { naturalWidth, naturalHeight } = e.target
  aspectRatio.value = (naturalHeight / naturalWidth) * 100
  loaded.value = true
}
</script>

<style scoped>
.img-box {
  position: relative;
  width: 100%;
  background-color: #f2f2f2;
}
.img-box img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

✅ Advantages:

  • Suitable for lazy loading/irregular images;
  • The page is stable without flickering;
  • The proportion of the image is automatically corrected after loading.

5. Summary of best practices ​

SolutionAdvantagesApplicable scenarios
aspect-ratioSimple, modern, good performanceModern browser project
padding-topStrong compatibilityOld project / IE
width+heightThe most native and excellent performanceKnown image size
Vue dynamic calculationAutomatic calculation of proportionsLazy loading, dynamic content

6. Interview short answer template ​

Before the image is loaded, you can use "fixed ratio occupancy" to avoid page jitter. There are three common approaches: One is to use the aspect-ratio property of CSS; The second is to use the padding-top percentage technique to simulate a fixed ratio; The third is to declare width and height in HTML to allow the browser to calculate the layout in advance. In Vue or React, the aspect ratio can also be dynamically calculated based on the actual size of the image to achieve more accurate positioning.