You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用picture元素适配不同视口图片失败的技术求助

响应式图片与Flex布局问题修复

一、核心问题排查

1. 图片适配失效原因

  • HTML未正确使用<picture>元素,直接用固定src的<img>标签,无法触发响应式图片切换
  • CSS存在错误选择器:媒体查询中的picture-image-container是无效写法,正确应为.image-container
  • 图片容器固定宽高限制了响应式调整,且未设置合适的图片适配属性

2. Flex布局未达预期原因

  • 桌面端媒体查询中,article.card-body仅设置min-width未配合max-width控制整体尺寸,未给图片容器分配合理宽度
  • 移动端.card-body的max-width限制导致桌面端布局无法展开
  • 未统一main的布局属性,存在重复定义

二、修复方案

1. 重构HTML结构,正确使用picture元素

添加<picture>标签,通过source指定不同视口下的图片资源,确保桌面端加载对应图片。

2. 修正CSS选择器与布局属性

  • 修复媒体查询中的错误选择器
  • 调整桌面端.card-body的flex方向与尺寸分配,让图片和内容各占50%宽度
  • 优化图片容器的尺寸设置,使用百分比而非固定值,配合object-fit: cover保证图片比例
  • 统一main的布局属性,移除重复定义

三、修正后的完整代码

HTML代码

<main class="background">
  <article class="card-body">
    <picture class="image-container">
      <source media="(min-width: 800px)" srcset="./images/image-product-desktop.jpg">
      <img src="./images/image-product-mobile.jpg" alt="perfume" class="perfume-image">
    </picture>
    <section class="card-details">
      <header class="title">PERFUME</header>
      <h1 class="title-detail">Gabrielle Essence Eau De Parfum</h1>
      <p class="section-detail">A floral, solar and voluptuous interpretation composed by Olivier Polge, Perfumer-Creator for the House of CHANEL.</p>
      <h2 class="price">$149.99</h2>
      <button class="add-to-cart">
        <img src="./images/icon-cart.svg" alt="cart" class="cart-icon">
        <span class="btn-text">Add to Cart</span>
      </button>
    </section>
  </article>
  <footer class="challenge-userinfo">
    <div class="attribution">
      Challenge by Frontend Mentor. Coded by David Bayode.
    </div>
  </footer>
</main>

CSS代码

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

*::before,
*::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  min-height: 100vh;
  background-color: hsl(30, 38%, 92%);
}

main.background {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 100vh;
  padding: 20px;
}

article.card-body {
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border-radius: 10px;
  max-width: 346px;
  overflow: hidden;
}

section.card-details {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  padding: 25px;
}

picture.image-container {
  width: 100%;
  height: 243px;
}

img.perfume-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

header.title {
  color: hsl(228, 12%, 48%);
  font-family: 'Montserrat', sans-serif;
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 5px;
  margin-bottom: 13px;
  transform: scale(0.9);
}

h1.title-detail {
  color: hsl(212, 21%, 14%);
  font-family: 'Fraunces', serif;
  font-size: 34px;
  line-height: 1;
  font-weight: 700;
  margin-bottom: 17px;
}

p.section-detail {
  font-family: 'Montserrat', sans-serif;
  color: hsl(228, 12%, 48%);
  font-size: 13px;
  line-height: 1.6;
  margin-bottom: 29px;
}

h2.price {
  display: flex;
  flex-direction: row;
  font-family: 'Fraunces', sans-serif;
  color: hsl(158, 36%, 37%);
  font-size: 32px;
  font-weight: 900;
  margin-bottom: 20px;
}

h2.price::after {
  content: '$169.99';
  display: flex;
  align-self: center;
  color: hsl(228, 12%, 48%);
  font-size: 11px;
  font-family: 'Fraunces', sans-serif;
  font-weight: 300;
  padding-left: 23px;
  text-decoration: line-through;
}

img.cart-icon {
  margin-left: -15px;
}

button.add-to-cart {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  background-color: hsl(158, 36%, 37%);
  color: #fff;
  width: 100%;
  height: 50px;
  border: none;
  border-radius: 5px;
}

button.add-to-cart:hover {
  background-color: hsl(158, 36%, 13%);
  cursor: pointer;
}

span.btn-text {
  padding-left: 15px;
}

footer.challenge-userinfo {
  margin-top: 20px;
  width: 100%;
}

div.attribution {
  background-color: #fff;
  text-align: center;
  width: 100%;
  font-size: 11px;
  padding: 10px;
  border-radius: 5px;
}

@media (min-width: 800px) {
  article.card-body {
    flex-direction: row;
    max-width: 616px;
    min-width: auto;
  }

  picture.image-container {
    width: 50%;
    height: auto;
  }

  .card-details {
    width: 50%;
    justify-content: space-between;
  }
}

四、关键修复点说明

  • 用<picture>+<source>实现响应式图片切换,桌面端加载image-product-desktop.jpg
  • 桌面端.card-body改为横向flex布局,图片和内容各占50%宽度
  • 图片使用object-fit: cover保证比例,避免拉伸变形
  • 按钮宽度设为100%适配容器,移除固定宽度限制
  • 给main添加内边距,避免小屏内容贴边

内容的提问来源于stack exchange,提问作者Davidbay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:10:24