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

Tailwind CSS实现容器内图片固定高度且保持比例不裁剪

解决Tailwind中固定高度图片保持比例且不裁剪的问题

问题场景

我用Tailwind CSS、React、TypeScript和Framer Motion开发作品集网站,项目展示区采用网格布局的卡片形式,卡片包含图片及hover时显示的绝对定位信息层。需要实现:

  • 图片设置为约500px固定高度
  • 宽度占满网格列
  • 保持图片原比例且不被裁剪

尝试过调整div高度无效,object-fill导致图片拉伸,object-cover会裁剪图片,无法满足需求。

解决方案

核心思路是用object-contain配合固定高度的容器,同时通过flex布局让图片居中,空白区域可添加背景色填充。以下是修改后的代码:

import { motion } from 'framer-motion';

import { SiGithub, SiReact, SiTailwindcss } from 'react-icons/si';
import spotifyStats from '../assets/Spotify-Stats.png';
import flasher from '../assets/Flasher.png';

export default function Projects() {
  const fadeUp = {
    hidden: {
      opacity: 0,
      y: 20,
    },
    visible: {
      opacity: 1,
      y: 0,
    },
  };

  const fadeIn = {
    hidden: {
      opacity: 0,
    },
    visible: {
      opacity: 1,
      transition: {
        when: 'beforeChildren',
        staggerChildren: 0.45,
      },
    },
  };

  const scaleIn = {
    hidden: {
      opacity: 0,
      scale: 0,
    },
    visible: {
      opacity: 1,
      scale: 1,
      transition: {
        duration: 0.4,
      },
    },
  };

  return (
    <section className='my-40'>
      <motion.h2
        variants={fadeUp}
        initial={'hidden'}
        whileInView={'visible'}
        viewport={{ once: false, amount: 0.5 }}
        className='text-center text-4xl'
      >
        Projects
      </motion.h2>

      <motion.div
        variants={fadeIn}
        initial={'hidden'}
        whileInView={'visible'}
        viewport={{ once: false, amount: 0.1 }}
        className='grid grid-cols-1 md:grid-cols-2 mt-6 gap-6'
      >
        <motion.div
          variants={scaleIn}
          className='w-full group hover:cursor-pointer'
        >
          {/* 固定容器高度+flex居中+背景填充空白 */}
          <div className='relative overflow-hidden rounded-xl h-[500px] flex items-center justify-center bg-gray-100'>
            {/* object-contain保证图片完整显示,max-h-full限制高度不超容器 */}
            <img
              className='w-full max-h-full object-contain group-hover:scale-125 group-hover:rotate-3 duration-500'
              src={spotifyStats}
              alt='Spotify Stats Web App'
            />
            <div className='absolute h-full w-full bg-black/90 flex flex-col gap-2 items-center text-center justify-center -bottom-96 group-hover:bottom-0 opacity-0 group-hover:opacity-100 transition-all duration-300 text-xs'>
              <h2>Spotify Stats Web App</h2>
              <p>Tech Stack:</p>
              <ul className='list-none flex gap-2'>
                <li>
                  <SiReact size={20} />
                </li>
                <li>
                  <SiTailwindcss size={20} />
                </li>
              </ul>
              <p>Git Repo:</p>
              <a
                href='#'
                target='_blank'
              >
                <SiGithub size={20} />
              </a>
              <p>Link to Live Site:</p>
              <></>
              <small>
                Description: A web app using Spotify's api to show the user
                their most listened to music artist and tracks in a specific
                time frame. (Similarly to Spotify rewind that comes out every
                year)
              </small>
              <small>
                Please note: This site will not allow spotify accounts to work
                unless they are added to the developers list (Please contact me
                in the form below if you would like to be added)
              </small>
            </div>
          </div>
        </motion.div>
        <motion.div
          variants={scaleIn}
          className='w-full group hover:cursor-pointer '
        >
          <div className='relative overflow-hidden rounded-xl h-[500px] flex items-center justify-center bg-gray-100'>
            <img
              className='w-full max-h-full object-contain group-hover:scale-125 group-hover:rotate-3 duration-500'
              src={flasher}
              alt='A social media meets flash card sharing experience'
            />

            <div className='absolute h-full w-full bg-black/90 flex flex-col items-center justify-center -bottom-96 group-hover:bottom-0 opacity-0 group-hover:opacity-100 transition-all duration-300'>
              <h2>Flasher</h2>
            </div>
          </div>
        </motion.div>
      </motion.div>
    </section>
  );
}

关键修改说明

  1. 容器设置:给图片外层容器添加h-[500px] flex items-center justify-center bg-gray-100

    • h-[500px]固定容器高度
    • flex items-center justify-center让图片在容器内水平垂直居中
    • bg-gray-100填充图片比例与容器不匹配时的空白区域(可根据需求修改颜色)
  2. 图片属性:将object-cover改为object-contain,同时添加max-h-full

    • object-contain保证图片完整显示,保持原始比例,不会拉伸或裁剪
    • max-h-full限制图片高度不超出容器的500px上限
  3. hover效果保留:原有的scale-125和rotate-3效果依然有效,图片会在容器内放大旋转,不会超出容器(因为容器有overflow-hidden)

原理补充

  • object-contain的作用是让图片完全适配容器的可用空间,优先保证图片完整显示,比例不变
  • 容器固定高度后,宽度由网格列自动填充,图片会根据自身比例调整宽度或高度,多余空间用容器背景填充
  • 绝对定位的信息层不受图片布局影响,依然能正常触发hover动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:03:17