Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • CSS

    • CSS教程和技巧收藏
    • css块元素和行内元素
    • 盒子模型
    • BFC和IFC
    • 字体font-weight相关知识
    • CSS-function汇总
    • CSS3之has函数的使用
    • CSS3之transition过渡
    • CSS3之animation动画
    • css动画性能优化
    • flex布局语法
    • flex布局案例
    • Grid布局语法
    • flex布局和grid布局的区别
    • 「布局技巧」图片未加载前自动撑开元素高度
      • 一、为什么要“图片加载前撑开高度”?
      • 二、核心思路:根据“宽高比(Aspect Ratio)”预留空间
      • 三、几种实现方式
        • ✅ 方式一:CSS 固定比例占位(推荐🔥,最简洁)
        • 🧩 方式二:Padding 百分比占位法(兼容旧浏览器)
        • 🧩 方式三:在 HTML 中声明图片原始尺寸(纯 HTML 技巧)
        • 方式四:Vue 动态计算图片比例(适合懒加载)
      • 🧠 五、最佳实践总结
      • 六、面试简答模板
    • 文字在一行或多行时超出显示省略号
    • 水平垂直居中的几种方式-案例
    • 如何根据系统主题自动响应CSS深色模式
    • 工作中遇到的css问题记录
    • 今天总结一下用到的css吧
  • 页面
  • CSS
mamingjuan
2016-02-22
目录

「布局技巧」图片未加载前自动撑开元素高度

# 「布局技巧」图片未加载前自动撑开元素高度

这其实是一个经典的前端布局技巧,可以让图片还没加载出来之前,就能占住空间,避免页面抖动或“闪动跳位(Layout Shift)”。 👉 这类问题在图片列表、懒加载、骨架屏场景里非常常见。

下面我们一步步讲清楚思路 + 多种实现方案(含 Vue 实战)。


# 一、为什么要“图片加载前撑开高度”?

默认情况下,图片 <img> 在还没加载完成前,浏览器不知道其高度, 所以会把它的高度设为 0,等图片加载后再重新渲染。

💥 这样就会导致:

  • 页面内容抖动(Layout Shift)
  • 用户体验差(特别是懒加载或瀑布流中)

所以我们的目标是:

在图片加载之前,提前占位,保持布局稳定。


# 二、核心思路:根据“宽高比(Aspect Ratio)”预留空间

最关键的参数:图片的宽高比例(aspect ratio)。

假设图片宽高比是 16:9, 我们只要提前根据容器宽度,计算出对应高度并撑开空间即可。


# 三、几种实现方式

# ✅ 方式一: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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

📘 说明:

  • aspect-ratio 是现代 CSS 属性,自动按比例计算高度;
  • 图片加载前容器就有高度;
  • object-fit: cover 保证图片不变形。

✅ 优点:

  • 无需 JS;
  • 自动自适应;
  • 性能好;
  • 已被现代浏览器广泛支持(Chrome / Safari / Firefox / Edge)。

# 🧩 方式二:Padding 百分比占位法(兼容旧浏览器)

在 aspect-ratio 未被支持时,可以用经典的“padding 百分比”技巧。

<div class="img-wrapper">
  <img src="xxx.jpg" alt="">
</div>
1
2
3
.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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

📘 原理: padding-top 的百分比是根据容器宽度计算的, 所以可以动态撑出“固定比例”的盒子。

✅ 兼容性: 支持所有主流浏览器,包括老版本 IE。


# 🧩 方式三:在 HTML 中声明图片原始尺寸(纯 HTML 技巧)

如果你知道图片的原始尺寸,比如 800×600, 可以直接在 <img> 标签中声明 width / height:

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

📘 说明:

  • 浏览器会自动根据这两个属性计算出宽高比;
  • 图片加载前就能占位;
  • HTML 原生支持,性能最好。

✅ 优点:

  • 无需额外 CSS;
  • 与 aspect-ratio 原理一致;
  • Google Lighthouse 强烈推荐。

⚠️ 注意: width / height 是图片原始像素,不会影响最终显示大小,浏览器会按比例缩放。


# 方式四: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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

✅ 优点:

  • 适合懒加载 / 不规则图片;
  • 页面稳定,无闪动;
  • 图片加载后比例自动修正。

# 🧠 五、最佳实践总结

方案 优点 适用场景
aspect-ratio 简洁、现代、性能好 现代浏览器项目
padding-top 兼容性强 老项目 / IE
width+height 最原生、性能极佳 已知图片尺寸
Vue 动态计算 自动计算比例 懒加载、动态内容

# 六、面试简答模板

图片未加载前可以通过“固定比例占位”来避免页面抖动。 常见做法有三种: 一是使用 CSS 的 aspect-ratio 属性; 二是用 padding-top 百分比技巧模拟固定比例; 三是 HTML 中声明 width、height 来让浏览器提前计算布局。 在 Vue 或 React 中还可以根据图片实际尺寸动态计算宽高比,实现更精准的占位。


上次更新: 2025/11/25, 03:24:47
flex布局和grid布局的区别
文字在一行或多行时超出显示省略号

← flex布局和grid布局的区别 文字在一行或多行时超出显示省略号→

Copyright © 2015-2025 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式