預留位置

為網頁內容建立預留位置有時就像為現有頁面元素新增背景效果一樣簡單。在本例中,所有清單項目都會共用相同的基礎 HTML 結構。不過,預留位置的樣式採用灰色背景,也就是使用 CSS 動畫建立閃爍的載入效果。

視網頁元素的實作方式而定,您可能也需要稍微調整 CSS,確保預留位置即使不含內容,仍會佔用空間。這通常是在現有網頁元素中加入 widthheight 屬性的形式。舉例來說,在這個範例中,新增 height: 1.5em.text-container 可確保即使預留位置不含任何文字,仍會持續顯示。

HTML

<div class="grid">
    <div class="item">
        <div class="image-container">
            <img src="hats.jpg">
        </div>
        <div class="text-container">Hats</div>
    </div>
    <div class="item empty">
        <div class="image-container">
            <img src="">
        </div>
        <div class="text-container">Watches</div>
    </div>
    <div class="item empty">
        <div class="image-container">
            <img src="">
        </div>
        <div class="text-container"></div>
    </div>
    <div class="item empty">
        <div class="image-container">
            <img src="">
        </div>
        <div class="text-container"></div>
    </div>
    <div class="item empty">
        <div class="image-container">
            <img src="">
        </div>
        <div class="text-container"></div>
    </div>
    <div class="item empty">
        <div class="image-container">
            <img src="">
        </div>
        <div class="text-container"></div>
    </div>
</div>

CSS


        :root {
    --placeholder-primary: #eeeeee;
    --placeholder-secondary: #cccccc;
}
.grid {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1em;
    width: 100%;
    max-width: 650px;
    margin: 1em 0;
}
.item {
    display: grid;
    gap: .5em;
    width: 200px;
}
.text-container {
    font-size: 1em;
    height: 1.5em;
    text-align: center;
    font-weight: bold;
}
.image-container {
    width: 200px;
    height: 200px;;
    animation: placeholder ease-in-out 2s infinite;
}
.image-container img {
    width: 100%;
}
@keyframes placeholder {
    0% {
        background-color: var(--placeholder-primary);
    }
    50% {
        background-color: var(--placeholder-secondary);
    }
    100% {
        background-color: var(--placeholder-primary);
    }
}
@keyframes fadeIn {
    0% {
        opacity: 0%;
    }
    100% {
        opacity: 100%;
    }
}
.item.loaded .image-container {
    animation: none;
}
.item.loaded .image-container img{
    animation: fadeIn linear .5s;
}
        

JS


        const data = [
    {
        description: "Watches",
        // 
        // src: "https://web-dev.imgix.net/image/j2RDdG43oidUy6AL6LovThjeX9c2/GMPpoERpp9aM5Rihk5F2.jpg"
    },
    {
        description: "Shirt",
        src: "shirt.jpg"
    },
    {
        description: "Shorts",
        src: "shorts.jpg"
    },
    {
        description: "Sunglasses",
        src: "sunglasses.jpg"
    },
    {
        description: "Shoes",
        src: "shoes.jpg"
    }
];
document.querySelectorAll(".item.empty").forEach((el, index) => {
    if (data[index]) {
        el.classList = "item loaded";
        el.querySelector("img").src = data[index].src;
        el.querySelector(".text-container").innerHTML = data[index].description;
    }
});