下面给你一份 最完整、讲解清晰、含代码示例的《HTML5 响应式布局方法详解》,涵盖移动端适配、媒体查询、弹性布局(Flex)、网格(Grid)、百分比布局、VW/VH、rem/em、图片与视频响应式方式等。
适合教程、文档编写、学习使用。
⭐ HTML5 响应式布局方法(含完整示例)
响应式布局(Responsive Layout)指网页在 不同屏幕设备(PC / 平板 / 手机)上自动调整排版,保证良好的阅读体验。
HTML5 响应式布局离不开:
- CSS 媒体查询(Media Queries)
- 弹性盒子布局(Flexbox)
- CSS Grid 网格布局
- 百分比 / 自适应宽度
- 流式图片 / 视频
- viewport 设置
- rem / vw / vh 布局
下面逐一讲解并配合实际示例。
一、Viewport 设置(移动端响应式的第一步)
在 <head> 中加入以下标签:
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
作用:
✔ 页面宽度随设备宽度变化
✔ 禁止用户自动缩放(可选)
✔ 解决手机上字体变大/缩小问题
二、CSS 媒体查询(Media Queries)响应式核心
用于根据设备宽度应用不同 CSS。
示例:基础媒体查询
/* PC */
body { background: #e8f5ff; }
/* 平板(≤ 1024px) */
@media (max-width: 1024px) {
body { background: #ffe7e7; }
}
/* 手机(≤ 600px) */
@media (max-width: 600px) {
body { background: #e7ffe7; }
}
示例:响应式两栏布局
<style>
.container {
display: flex;
gap: 10px;
}
.left { width: 70%; background: #b3d9ff; }
.right { width: 30%; background: #ffd6d6; }
/* 手机变为上下布局 */
@media (max-width: 768px) {
.container {
flex-direction: column;
}
.left, .right {
width: 100%;
}
}
</style>
<div class="container">
<div class="left">左侧内容</div>
<div class="right">右侧栏</div>
</div>
三、Flexbox 弹性布局(最常用)
Flex 是响应式布局的主力军。
例子:自动换行 + 自适应宽度
<style>
.box {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.item {
flex: 1 1 200px; /* 最小宽度200px,自动换行 */
background: #def;
padding: 20px;
}
</style>
<div class="box">
<div class="item">内容1</div>
<div class="item">内容2</div>
<div class="item">内容3</div>
<div class="item">内容4</div>
</div>
特点:
✔ 自动换行
✔ 每列最小宽度 200px
✔ PC 4列,iPad 2列,手机 1列(自适应)
四、CSS Grid 网格布局(最强大的响应式方案)
Grid 让响应式布局更简单。
例子:不写媒体查询的自适应卡片布局
<style>
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
}
.card {
background: #f0f0f0;
padding: 20px;
}
</style>
<div class="grid">
<div class="card">卡片1</div>
<div class="card">卡片2</div>
<div class="card">卡片3</div>
<div class="card">卡片4</div>
</div>
优势:
✔ 不需要媒体查询
✔ 宽度不足自动换行
✔ 最少 200px,每行自动排列
五、百分比布局(最经典响应式方式)
.left { width: 70%; }
.right { width: 30%; }
@media (max-width: 768px) {
.left, .right {
width: 100%;
}
}
简单直观,适合旧项目。
六、VW / VH(根据视口大小计算)
1vw = 1% 的视口宽度1vh = 1% 的视口高度
示例:标题随屏幕宽度缩放
h1 {
font-size: 5vw;
}
手机 / PC 自动缩放。
七、rem / em + 媒体查询(常用移动端等比缩放)
html { font-size: 16px; }
@media (max-width: 600px) {
html { font-size: 14px; }
}
.box {
width: 20rem; /* 根据根字体大小缩放 */
}
适合 APP 端 / 大项目。
八、响应式图片(流式图片)
方式 1:max-width: 100%(最常用)
img {
max-width: 100%;
height: auto;
}
方式 2:picture(根据设备加载不同图片)
<picture>
<source media="(max-width: 600px)" srcset="small.jpg">
<img src="large.jpg" alt="">
</picture>
九、响应式视频
.video-wrapper {
position: relative;
padding-top: 56.25%; /* 16:9 */
}
.video-wrapper iframe {
position: absolute;
width: 100%;
height: 100%;
}
十、综合完整案例:响应式三栏布局(PC → 平板 → 手机)
<style>
.container {
display: flex;
gap: 10px;
}
.left, .middle, .right {
padding: 20px;
background: #def;
}
/* PC 三栏 */
.left { flex: 1; }
.middle { flex: 2; }
.right { flex: 1; }
/* 平板变成两栏 */
@media (max-width: 1024px) {
.right { display: none; }
}
/* 手机变一栏 */
@media (max-width: 600px) {
.container { flex-direction: column; }
}
</style>
<div class="container">
<div class="left">左侧</div>
<div class="middle">中间</div>
<div class="right">右侧</div>
</div>
结果:
✔ PC:3栏
✔ 平板:2栏
✔ 手机:1栏
✅ 总结:响应式布局的常用方法
| 方法 | 特点 |
|---|---|
| viewport | 基础适配,必须设置 |
| 媒体查询 | 精确控制不同分辨率的样式 |
| Flex | 弹性盒子,移动端布局主流 |
| Grid | 最强大的响应式布局(推荐) |
| 百分比布局 | 简单易用 |
| rem/vw/vh | 自适应字体、容器大小 |
| 流式图片/视频 | 防止溢出 |
太棒 —— 我把你要的 “全部”响应式内容都做了:
下面包含四个可直接复制运行的完整 HTML 示例(每个都是独立文件):
- 响应式导航栏(含汉堡菜单 + 无障碍/键盘支持)
- 响应式电商首页模板(PC / 平板 / 手机,带轮播、商品卡片)
- 极简响应式栅格系统(50 行左右,可复用的 CSS 实现)
- 响应式后台管理面板布局(侧栏可折叠、顶部栏、响应式内容区)
每个示例前我会给一段简短说明 —— 直接复制到 .html 文件打开即可测试。开始吧!
1. 响应式导航栏(Hamburger 菜单 + 可访问性)
说明:顶部固定导航,桌面显示水平菜单,移动显示汉堡菜单并滑出侧栏。支持键盘与 aria 属性。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>响应式导航栏示例</title>
<style>
:root{
--bg:#fff; --accent:#1d72ff; --muted:#666;
}
*{box-sizing:border-box}
body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,'Helvetica Neue',Arial;background:#f5f7fb}
header{position:fixed;top:0;left:0;right:0;background:var(--bg);border-bottom:1px solid #eee;z-index:60}
.nav-inner{max-width:1100px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;gap:12px}
.brand{display:flex;align-items:center;gap:10px;font-weight:700;color:var(--accent)}
.brand .logo{width:36px;height:36px;border-radius:8px;background:linear-gradient(135deg,var(--accent),#6fb1ff)}
nav{display:flex;gap:8px;align-items:center}
nav a{padding:8px 12px;border-radius:8px;text-decoration:none;color:var(--muted);font-weight:500}
nav a:hover, nav a:focus{background:#f0f6ff;color:var(--accent);outline:none}
.actions{display:flex;gap:8px;align-items:center}
.btn{padding:8px 12px;border-radius:8px;border:1px solid #e6e9ef;background:#fff}
/* hamburger */
.hamburger{display:none;background:transparent;border:0;padding:8px;border-radius:8px}
.hamburger:focus{outline:2px solid #cfe0ff}
/* mobile menu drawer */
.drawer{position:fixed;top:0;left:-280px;width:260px;height:100vh;background:var(--bg);box-shadow:2px 0 18px rgba(20,20,30,.08);transition:left .22s;z-index:70;padding:18px;display:flex;flex-direction:column;gap:10px}
.drawer.open{left:0}
.drawer a{display:block;padding:12px;border-radius:8px;color:#333;text-decoration:none}
.drawer .close{align-self:flex-end;background:transparent;border:0;padding:6px;font-size:18px}
/* overlay */
.overlay{position:fixed;inset:0;background:rgba(10,10,20,.35);opacity:0;pointer-events:none;transition:opacity .22s;z-index:65}
.overlay.show{opacity:1;pointer-events:auto}
/* responsive */
@media (max-width:880px){
nav{display:none}
.hamburger{display:inline-flex}
.actions .desktop-only{display:none}
}
</style>
</head>
<body>
<header>
<div class="nav-inner">
<div style="display:flex;align-items:center;gap:12px">
<button class="hamburger" id="hamburger" aria-label="打开菜单" aria-controls="mobile-drawer" aria-expanded="false">☰</button>
<div class="brand"><div class="logo" aria-hidden="true"></div>MyShop</div>
</div>
<nav role="navigation" aria-label="主导航">
<a href="#">首页</a>
<a href="#">分类</a>
<a href="#">活动</a>
<a href="#">关于我们</a>
</nav>
<div class="actions">
<button class="btn desktop-only">登录</button>
<button class="btn">购物车</button>
</div>
</div>
</header>
<!-- Drawer -->
<aside id="mobile-drawer" class="drawer" aria-hidden="true">
<button class="close" id="close-drawer" aria-label="关闭菜单">✕</button>
<nav>
<a href="#">首页</a>
<a href="#">分类</a>
<a href="#">活动</a>
<a href="#">关于我们</a>
<hr>
<a href="#">登录</a>
<a href="#">购物车</a>
</nav>
</aside>
<div id="overlay" class="overlay" tabindex="-1"></div>
<main style="max-width:1100px;margin:90px auto;padding:20px;">
<h1>响应式导航栏示例</h1>
<p>调整浏览器宽度查看汉堡菜单与抽屉行为。按 Esc 关闭抽屉;点击遮罩也会关闭。</p>
</main>
<script>
const btn = document.getElementById('hamburger');
const drawer = document.getElementById('mobile-drawer');
const closeBtn = document.getElementById('close-drawer');
const overlay = document.getElementById('overlay');
function openDrawer(){
drawer.classList.add('open');
overlay.classList.add('show');
drawer.setAttribute('aria-hidden','false');
btn.setAttribute('aria-expanded','true');
// focus first link
setTimeout(()=>drawer.querySelector('a')?.focus(),120);
document.body.style.overflow = 'hidden';
}
function closeDrawer(){
drawer.classList.remove('open');
overlay.classList.remove('show');
drawer.setAttribute('aria-hidden','true');
btn.setAttribute('aria-expanded','false');
document.body.style.overflow = '';
btn.focus();
}
btn.addEventListener('click', openDrawer);
closeBtn.addEventListener('click', closeDrawer);
overlay.addEventListener('click', closeDrawer);
document.addEventListener('keydown', (e)=>{
if(e.key === 'Escape' && drawer.classList.contains('open')) closeDrawer();
});
</script>
</body>
</html>
2. 响应式电商首页模板(PC / 平板 / 手机)
说明:示例包含顶部导航、轮播(简易实现)、响应式商品网格、底部栏。适合作为电商首页骨架。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>响应式电商首页模板</title>
<style>
*{box-sizing:border-box}
body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,'Noto Sans SC',Arial;background:#fafafa;color:#222}
header{background:#fff;border-bottom:1px solid #eee;position:sticky;top:0;z-index:40}
.wrap{max-width:1200px;margin:0 auto;padding:12px}
.top-row{display:flex;gap:12px;align-items:center;justify-content:space-between}
.logo{font-weight:800;color:#1d72ff}
.search{flex:1;margin:0 12px}
.search input{width:100%;padding:10px 12px;border-radius:8px;border:1px solid #e6e9ef}
/* banner */
.banner{margin-top:16px;background:linear-gradient(90deg,#ffd6a5,#ffd6f2);border-radius:10px;padding:24px;display:flex;align-items:center;gap:20px}
.hero{flex:1}
.hero h2{margin:0 0 8px;font-size:20px}
.hero p{margin:0;color:#555}
.carousel{width:320px;height:140px;background:#fff;border-radius:8px;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 20px rgba(20,20,40,.06)}
/* product grid */
.products{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin:18px 0}
.card{background:#fff;border-radius:10px;padding:12px;box-shadow:0 6px 18px rgba(20,20,40,.04);display:flex;flex-direction:column;gap:8px}
.card img{width:100%;height:140px;object-fit:cover;border-radius:8px}
.price{color:#e83e3e;font-weight:700}
/* footer */
footer{margin-top:30px;background:#fff;padding:16px;border-top:1px solid #eee}
/* responsive tweaks */
@media (max-width:720px){
.banner{flex-direction:column;align-items:stretch}
.carousel{width:100%;height:160px}
}
</style>
</head>
<body>
<header>
<div class="wrap top-row">
<div class="logo">ShopLogo</div>
<div class="search" aria-label="站内搜索">
<input type="search" placeholder="搜索商品、品牌">
</div>
<div style="display:flex;gap:8px;align-items:center">
<button class="btn">登录</button>
<button class="btn">购物车(0)</button>
</div>
</div>
</header>
<main class="wrap" style="padding-top:18px">
<section class="banner">
<div class="hero">
<h2>周末狂欢 — 全场最低五折</h2>
<p>精选商品,极速发货,7天无理由退货</p>
</div>
<div class="carousel" id="carousel">BANNER</div>
</section>
<section style="margin-top:18px">
<h3>热门推荐</h3>
<div class="products" id="productList">
<!-- cards 渲染 -->
</div>
</section>
<section style="margin-top:6px">
<h3>猜你喜欢</h3>
<div class="products" id="moreList"></div>
</section>
</main>
<footer class="wrap">
<div style="display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px">
<div>© 2025 MyShop - 所有权保留</div>
<div>关于 · 联系 · 帮助</div>
</div>
</footer>
<script>
// 简易商品数据
const products = Array.from({length:12}).map((_,i)=>({
id:i+1,
title:`潮流单品 ${i+1}`,
price:(Math.random()*300+49).toFixed(2),
img:`https://picsum.photos/seed/p${i+1}/600/400`
}));
function render(listEl, arr){
listEl.innerHTML = arr.map(p=>`
<article class="card" role="article" aria-labelledby="p${p.id}">
<img src="${p.img}" alt="${p.title}">
<div id="p${p.id}" style="font-weight:600">${p.title}</div>
<div style="display:flex;justify-content:space-between;align-items:center">
<div class="price">¥${p.price}</div>
<button style="padding:8px 10px;border-radius:8px;border:1px solid #eee">加入购物车</button>
</div>
</article>
`).join('');
}
render(document.getElementById('productList'), products.slice(0,8));
render(document.getElementById('moreList'), products.slice(8));
// 简易轮播(只切文本)
const carousel = document.getElementById('carousel');
const banners = ['超值爆款','新品首发','限时折扣','热卖推荐'];
let idx=0;
setInterval(()=>{ idx=(idx+1)%banners.length; carousel.textContent=banners[idx]; },2200);
</script>
</body>
</html>
3. 极简响应式栅格系统(约 50 行 CSS,可复用)
说明:实现类似 Bootstrap 的栅格:.row + .col-,支持断点(desktop / tablet / mobile)。提供简单的使用示例。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>简易响应式栅格系统</title>
<style>
/* 基础 */
*{box-sizing:border-box}
.container{max-width:1200px;margin:0 auto;padding:12px}
.row{display:flex;flex-wrap:wrap;margin-left:-8px;margin-right:-8px}
.row > [class*="col-"]{padding:8px}
/* 默认列(mobile-first): 每列占满 */
[class*="col-"]{flex-basis:100%;flex-grow:0;max-width:100%}
/* 小于等于 768 (tablet) */
@media (min-width: 769px){
.col-sm-1{flex-basis:8.3333%;max-width:8.3333%}
.col-sm-2{flex-basis:16.6667%;max-width:16.6667%}
.col-sm-3{flex-basis:25%;max-width:25%}
.col-sm-4{flex-basis:33.3333%;max-width:33.3333%}
.col-sm-6{flex-basis:50%;max-width:50%}
.col-sm-12{flex-basis:100%;max-width:100%}
}
/* 桌面 >= 1024 */
@media (min-width: 1024px){
.col-1{flex-basis:8.3333%;max-width:8.3333%}
.col-2{flex-basis:16.6667%;max-width:16.6667%}
.col-3{flex-basis:25%;max-width:25%}
.col-4{flex-basis:33.3333%;max-width:33.3333%}
.col-6{flex-basis:50%;max-width:50%}
.col-12{flex-basis:100%;max-width:100%}
}
/* 工具样式 */
.card{background:#fff;padding:16px;border-radius:8px;box-shadow:0 8px 20px rgba(15,15,30,.06);text-align:center}
h1{font-size:18px;margin:16px 0}
</style>
</head>
<body>
<div class="container">
<h1>简易响应式栅格系统演示</h1>
<div class="row">
<div class="col-4 col-sm-6"><div class="card">col-4 (desktop) / col-sm-6 (tablet) / full for mobile</div></div>
<div class="col-4 col-sm-6"><div class="card">col-4</div></div>
<div class="col-4 col-sm-12"><div class="card">col-4 / 切换为一列</div></div>
</div>
<div style="height:18px"></div>
<div class="row">
<div class="col-3 col-sm-6"><div class="card">col-3</div></div>
<div class="col-3 col-sm-6"><div class="card">col-3</div></div>
<div class="col-3 col-sm-6"><div class="card">col-3</div></div>
<div class="col-3 col-sm-6"><div class="card">col-3</div></div>
</div>
</div>
</body>
</html>
说明:你可以把
.col-*命名规则扩展到 12 列任意组合;这个版本用 mobile-first 策略(小屏默认一列)。
4. 响应式后台管理布局(侧栏可折叠 + 顶栏 + 内容区)
说明:宽屏显示左侧菜单 + 内容区,窄屏折叠侧栏变为汉堡抽屉。包含示例表格和响应式卡片。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>响应式后台布局 示例</title>
<style>
:root{--sidebar:260px;--collapsed:64px;--bg:#f7f8fb;--card:#fff}
*{box-sizing:border-box}
body{margin:0;font-family:Inter,system-ui,Segoe UI,Roboto,'Noto Sans SC',Arial;background:var(--bg);color:#222}
.app{display:flex;min-height:100vh}
/* sidebar */
.sidebar{width:var(--sidebar);background:#fff;border-right:1px solid #eee;padding:12px 8px;transition:width .2s}
.brand{font-weight:800;padding:12px 8px;margin-bottom:8px}
.menu{display:flex;flex-direction:column;gap:6px}
.menu a{padding:10px;border-radius:8px;color:#444;text-decoration:none;display:flex;gap:10px;align-items:center}
.menu a:hover{background:#f0f6ff;color:#1d72ff}
/* main area */
.main{flex:1;display:flex;flex-direction:column}
.topbar{height:56px;background:transparent;border-bottom:1px solid #eee;display:flex;align-items:center;justify-content:space-between;padding:8px 16px}
.content{padding:18px;max-width:1200px;margin:0 auto;width:100%}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.card{background:var(--card);padding:14px;border-radius:10px;box-shadow:0 6px 18px rgba(20,20,40,.04)}
table{width:100%;border-collapse:collapse;background:var(--card);border-radius:10px;overflow:hidden}
th,td{padding:12px;border-bottom:1px solid #f0f0f0;text-align:left}
th{background:#fafafa;font-weight:700}
/* responsive behavior */
@media (max-width:900px){
.sidebar{position:fixed;left:-320px;top:0;height:100vh;z-index:60;width:260px}
.sidebar.open{left:0}
.overlay{position:fixed;inset:0;background:rgba(10,10,20,.35);opacity:0;pointer-events:none;transition:opacity .2s;z-index:50}
.overlay.show{opacity:1;pointer-events:auto}
.main{margin-left:0}
}
@media (min-width:901px){
.overlay{display:none}
}
</style>
</head>
<body>
<div class="app">
<aside class="sidebar" id="sidebar" aria-hidden="false">
<div class="brand">AdminPanel</div>
<nav class="menu" aria-label="侧边导航">
<a href="#"><span>🏠</span> 仪表盘</a>
<a href="#"><span>📦</span> 商品管理</a>
<a href="#"><span>🧾</span> 订单管理</a>
<a href="#"><span>👥</span> 用户管理</a>
<a href="#"><span>⚙️</span> 设置</a>
</nav>
</aside>
<div class="main">
<div class="topbar">
<div style="display:flex;align-items:center;gap:12px">
<button id="toggle" aria-label="切换侧栏" style="padding:8px;border-radius:8px">☰</button>
<h3 style="margin:0">仪表盘</h3>
</div>
<div style="display:flex;gap:12px;align-items:center">
<input placeholder="搜索订单" style="padding:8px 12px;border-radius:8px;border:1px solid #e6e9ef">
<div>管理员</div>
</div>
</div>
<div class="content">
<div class="grid">
<div class="card"><div style="font-size:14px;color:#666">今天收入</div><div style="font-size:20px;font-weight:700">¥12,345</div></div>
<div class="card"><div style="font-size:14px;color:#666">新用户</div><div style="font-size:20px;font-weight:700">1,234</div></div>
<div class="card"><div style="font-size:14px;color:#666">待发货订单</div><div style="font-size:20px;font-weight:700">32</div></div>
</div>
<div style="height:16px"></div>
<div class="card">
<h4 style="margin:0 0 8px">最近订单</h4>
<table>
<thead><tr><th>ID</th><th>用户</th><th>金额</th><th>状态</th></tr></thead>
<tbody>
<tr><td>#1001</td><td>张三</td><td>¥299.00</td><td>已支付</td></tr>
<tr><td>#1002</td><td>李四</td><td>¥1,299.00</td><td>待发货</td></tr>
<tr><td>#1003</td><td>王五</td><td>¥49.00</td><td>已取消</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="overlay" class="overlay" tabindex="-1"></div>
<script>
const toggle = document.getElementById('toggle');
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('overlay');
function openSidebar(){
sidebar.classList.add('open');
overlay.classList.add('show');
sidebar.setAttribute('aria-hidden','false');
document.body.style.overflow='hidden';
}
function closeSidebar(){
sidebar.classList.remove('open');
overlay.classList.remove('show');
sidebar.setAttribute('aria-hidden','true');
document.body.style.overflow='';
}
toggle.addEventListener('click', ()=>{
if(window.innerWidth <= 900){
if(sidebar.classList.contains('open')) closeSidebar();
else openSidebar();
} else {
// 宽屏下切换折叠(简单实现:宽度切小)
if(getComputedStyle(sidebar).width === '64px'){
sidebar.style.width = '260px';
} else {
sidebar.style.width = '64px';
}
}
});
overlay.addEventListener('click', closeSidebar);
window.addEventListener('resize', ()=>{
if(window.innerWidth > 900){
sidebar.classList.remove('open');
overlay.classList.remove('show');
sidebar.style.width = '';
document.body.style.overflow = '';
}
});
</script>
</body>
</html>
发表回复