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

多张不同背景图的Hover卡片动画实现问题求助

问题

参考Kevin Powell的教程《CSS Card with hover animation and mobile fallback》实现了单张Hover动画卡片,现在需要实现多张带不同背景图的同款卡片。原教程用CSS的background-image设置卡片背景,尝试用HTML的<img>标签替换背景后,出现图片锁定在Hover弹出层的问题,同时希望将卡片布局为3列网格,但目前图片问题导致布局失效。求助如何正确用<img>标签替换原背景图并实现预期效果。


解决方案

一、调整HTML结构,引入独立img标签

将<img>放在.card容器最外层,与.card-content同级,确保图片作为底层背景,不会被内容层覆盖。每个卡片可单独设置不同的图片地址:

<section class="Personal-Projects">
    <h2 class="personal-label">Personal Projects</h2>
    <div class="personal-grid">
        <!-- 卡片1 -->
        <div class="card">
            <img src="https://placekitten.com/400/300" alt="项目1封面" class="card-img">
            <div class="card-content">
                <h2 class="card-title">cool beans</h2>
                <p class="card-body">Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi similique </p>
                <a href="#" class="btn-project">To the Site</a>
            </div>
        </div>
        <!-- 卡片2 -->
        <div class="card">
            <img src="https://placekitten.com/400/301" alt="项目2封面" class="card-img">
            <div class="card-content">
                <h2 class="card-title">Another Project</h2>
                <p class="card-body">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, culpa.</p>
                <a href="#" class="btn-project">To the Site</a>
            </div>
        </div>
        <!-- 卡片3 -->
        <div class="card">
            <img src="https://placekitten.com/400/302" alt="项目3封面" class="card-img">
            <div class="card-content">
                <h2 class="card-title">Third Project</h2>
                <p class="card-body">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia, quas.</p>
                <a href="#" class="btn-project">To the Site</a>
            </div>
        </div>
    </div>
</section>

二、修改CSS样式,适配img标签并实现3列网格

移除原.card的背景图设置,通过定位和层级控制解决图片覆盖问题,同时配置网格布局:

:root {
--clr-accent: #60992d;
--clr-header: #DEDEDE;
--clr-elements: #4a7a22; /* 补充原代码未定义的变量 */
}

.Personal-Projects {
    padding: 2rem;
    text-align: center;
}

.personal-grid {
    display: grid;
    /* 自适应3列布局,小屏幕自动换行 */
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
    max-width: 1200px;
    margin: 0 auto;
}

.card {
    color: var(--clr-header);
    max-width: 35ch;
    border-radius: 10px;
    overflow: hidden;
    transition: transform 500ms ease;
    position: relative; /* 作为内部元素绝对定位的容器 */
    aspect-ratio: 4/3; /* 固定卡片宽高比,避免图片拉伸 */
}

.card-img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover; /* 图片铺满容器且保持比例 */
    z-index: 0; /* 图片置于最底层 */
}

.card:hover,
.card:focus-within {
    transform: scale(1.05);
}

.card-content {
    --padding: 1.5rem;
    padding: var(--padding);
    background: linear-gradient(
        hsl(0 0% 0% / 0),
        hsl(0 0% 0% / .4) 10%,
        hsl(0 0% 0% / 1)
    );
    position: absolute; /* 内容层绝对定位在卡片底部 */
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1; /* 内容层置于图片上方 */
}

/* 保留原hover动画逻辑 */
@media (hover: hover) {
    .card-content{
        transform: translateY(70%);
        transition: transform 500ms ease;
    }

    .card:hover .card-content,
    .card:focus-within .card-content {
        transform: translateY(0);
        transition-delay: 500ms;
    }
    
    .card:focus-within .card-content {
        transition-duration: 0ms;
    }
    
    .card-content > *:not(.card-title) {
        opacity: 0;
        transition: opacity 500ms linear;
    }
    
    .card:hover .card-content > *:not(.card-title),
    .card:focus-within .card-content > *:not(.card-title) {
        opacity: 1;
        transition-delay: 800ms;
    }

    .card-title::after {
        transform: scaleX(0);
    }
}

.btn-project {
    cursor: pointer;
    display: inline-block;
    padding: .5em 1.1em;
    text-decoration: none;
    color: var(--clr-header);
    background-color: var(--clr-accent);
    border-radius: 6px;
}

.btn-project:hover, 
.btn-project:focus {
    background-color: var(--clr-elements);
}

三、关键修复说明

  • 图片层级问题:通过position: absolute和z-index控制图片在最底层,内容层在上方,解决图片锁定在弹出层的问题。
  • 3列网格布局:使用grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))实现自适应3列,小屏幕自动换行,同时用gap设置卡片间距,margin:0 auto让网格居中。
  • 图片适配:object-fit: cover确保图片铺满卡片且保持比例,aspect-ratio固定卡片宽高比,避免不同图片导致卡片高度不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:35:23