Skeleton Screen

by hohoya33

HTML

<div class="container">
    <div class="card">
        <figure class="card-image loading"></figure>
        <div class="card-detail">
            <div class="card-mall loading"></div>
            <div class="card-title loading"></div>
            <div class="card-price loading"></div>
        </div>
    </div>
</div>

 <div class="button-group"><button class="button js-toggle">Toggle Content</button></div>

SCSS

$border-color: #dae1e7;
$background-color: #f2f2f2;
$text-color: #333;

body {
  background: $background-color;
  margin: 0;
  padding: 0;
  font-family: system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue;
  color: $text-color;
}

.container {
  margin: 2rem auto;
  max-width: 800px;
  display: flex;
  justify-content: center;
}


.button-group{display:block;text-align: center;}
.button-group button{width:100px;height:30px;}


.card {
  overflow: hidden;
  background: white;
  border-radius: .25rem;
  max-width: 232px;
  width: 232px;
}

.card-detail {
  padding: .5rem 1rem;
  height: 84px;
}

.card-image {
  margin: 0;
  padding: 0;
  overflow: hidden;
  img {
    max-width: 100%;
    height: auto;
  }
}


.loading {
  position: relative;
  background-color: #E2E2E2;
  &::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;
  }
}

.card-mall.loading {
    width:100px;
    height:10px;
    margin:16px 0;
}

.card-title.loading {
    width:180px;
    height:8px;
    margin-bottom:8px;
}

.card-price.loading {
    width:180px;
    height:8px;
    margin-bottom:8px;
}


@keyframes loading {
  100% {
    transform: translateX(100%);
  }
}


@keyframes Gradient {
    0% {
        background-position: 0% 50%
    }
    50% {
        background-position: 100% 50%
    }
    100% {
        background-position: 0% 50%
    }
}

.lazyloading img{display:block}

JavaScript

const cardImage = document.querySelector('.card-image');
const cardMall = document.querySelector('.card-mall');
const cardTitle = document.querySelector('.card-title');
const cardPrice = document.querySelector('.card-price');


const renderCard = () => {
  cardTitle.textContent = '국산 라지자 캔들 아로마 향초 캔들워머';
  cardMall.textContent = '이마트몰';
  cardPrice.textContent = '8,910 원~';
  createImage();

  cardTitle.classList.remove('loading');
  cardMall.classList.remove('loading');
  cardPrice.classList.remove('loading');
  cardImage.classList.remove('loading');
};

function createImage() {
  const img = new Image();
  img.classList.add("image");
  img.setAttribute('alt', '국산 라지자 캔들 아로마 향초 캔들워머');
  img.setAttribute('src', 'http://item.ssgcdn.com/31/37/76/item/1000031763731_i2_500.jpg');
  cardImage.appendChild(img);
}



const toggle = document.querySelector('.js-toggle');
let content = false;

toggle.addEventListener('click', function() {
  if(content === false) {
    content = true;
    renderCard();
  } else {
    content = false
    cardImage.innerHTML = '';
    cardTitle.textContent = '';
    cardMall.textContent = '';
    cardPrice.textContent = '';

    cardTitle.classList.add('loading');
    cardMall.classList.add('loading');
    cardPrice.classList.add('loading');
    cardImage.classList.add('loading');
  }
});