使用网格布局的CSS粘卡

问题描述 投票:0回答:1

我想使用网格布局来设计粘性卡的布局。这就是我设法实现的目标: enter image description here

<div class="cards">
    <div class="card">1</div>
    <div class="card">2</div>
    <div class="card">3</div>
    <div class="card">4</div>
    <div class="card">5</div>
</div>
:root {
    --card-top-offset: 3rem;
    --card-h: 36rem;
}

.cards {
    display: grid;
    grid-template-columns: repeat(1, minmax(0, 1fr));
    gap: calc(var(--card-h) / 2);
    align-items: baseline;
}

.card {
    position: sticky;
    top: 0;
    height: var(--card-h);
    transition: all 0.5s;
}
for (const cards of document.querySelectorAll(".cards")) {
    let i = 0;
    for (const card of cards.children) {
        if (card.classList.contains("card")) {
            card.style.top = `calc(5vh + ${i} * var(--card-top-offset))`;
            i += 1;
        }
    }

    cards.style.setProperty(
        "grid-template-rows",
        `repeat(${i}, var(--card-h))`,
    );
}

前 4 张卡效果很好,但第五张卡比我预期的要早脱开。我认为这是因为父元素

cards
正在结束。有没有办法使用 css 网格来实现这种行为?我发现了一些其他方法,但它涉及对某些元素的某些高度进行硬编码,我想避免这种情况。

html css css-grid sticky
1个回答
0
投票

您遇到的问题是由于粘性定位依赖于父容器的高度。当父容器结束时,粘性元素无法再粘在顶部。为了实现您正在寻找的行为,您可以利用 CSS 网格进行一些调整。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sticky Cards</title>
    <style>
        :root {
            --card-top-offset: 3rem;
            --card-h: 36rem;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
        }

        .cards {
            display: grid;
            grid-template-columns: repeat(1, minmax(0, 1fr));
            gap: calc(var(--card-h) / 2);
            align-items: baseline;
            position: relative;
            padding-top: 5vh;
        }

        .card {
            position: sticky;
            top: calc(5vh + var(--card-top-offset) * var(--i));
            height: var(--card-h);
            transition: all 0.5s;
            background: lightblue;
        }

        .card:nth-child(1) {
            --i: 0;
        }

        .card:nth-child(2) {
            --i: 1;
        }

        .card:nth-child(3) {
            --i: 2;
        }

        .card:nth-child(4) {
            --i: 3;
        }

        .card:nth-child(5) {
            --i: 4;
        }
    </style>
</head>
<body>
    <div class="cards">
        <div class="card">1</div>
        <div class="card">2</div>
        <div class="card">3</div>
        <div class="card">4</div>
        <div class="card">5</div>
    </div>
</body>
</html>

这里,每张卡片都有一个 --i 自定义属性,用于确定其相对于顶部的位置。这避免了硬编码高度并允许更动态的设置。位置:粘性仍被使用,但具有计算的顶部偏移量。

© www.soinside.com 2019 - 2024. All rights reserved.