Skeleton screens
by bc_rikko
HTML
<section class="card-item">
<figure class="card-image -loading"></figure>
<div class="card-detail">
<h3 class="title -loading"></h3>
<p class="description -loading"></p>
</div>
</section>
SCSS
body {
background-color: white;
color: #666666;
padding: 10px;
}
.card-item {
width: 320px;
box-shadow: 0 4px 8px rgba(0,0,0,.2);
transition: .3s;
&:hover {
box-shadow: 0 8px 16px rgba(0,0,0,.2);
}
> .card-image {
margin: 0;
width: 100%;
height: 180px;
> .image {
width: 100%;
height: 100%;
}
}
}
.card-detail {
padding: 2px 16px;
> .title {
letter-spacing: 3px;
}
> .description {
letter-spacing: 1px;
}
}
.-loading {
position: relative;
background-color: #E2E2E2;
border-radius: 15px;
&.card-image {
border-radius: 0;
}
&::after {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
transform: translateX(-100%);
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .2), transparent);
animation: loading 1.5s infinite;
}
}
@keyframes loading {
100% {
transform: translateX(100%);
}
}
.title.-loading {
height: 2rem;
}
.description.-loading {
height: 80px;
}
JavaScript
// LOAD TYPE - No wrap in <body>
window.onload = () => {
const cardImage = document.getElementsByClassName('card-image')[0];
const title = document.getElementsByClassName('title')[0];
const description = document.getElementsByClassName('description')[0];
const render = () => {
title.innerText = 'ポルトの街並み'
description.innerText = 'ポルトはポルトガル北部の港湾都市。人口約263,000人。リスボンに次ぐポルトガル第二の都市。同国屈指の世界都市であり、ポルト都市圏では、人口は約160万人を数える。';
title.classList.remove('-loading');
description.classList.remove('-loading');
cardImage.classList.remove('-loading');
};
const img = new Image();
img.onload = () => {
render();
img.classList.add('image');
cardImage.appendChild(img);
};
img.onerror = () => {
render();
};
// 重い画像ファイル
setTimeout(() => {
img.src = 'https://www.pakutaso.com/shared/img/thumb/hiroto_htmachi.jpg';
}, 5000);
};