CSS animation-delay timing off in Safari and mobile Chrome

Refresh

December 2018

Views

2.7k time

23

I've got a frustrating bug in Safari around CSS animation-delay.

This animation works beautifully on Desktop in Chrome, Firefox, IE11, IE10, but I get mixed results in Safari. The pieces of the bag should all display after an equal amount of pause (controlled by the animation-delay).

Desktop Safari will sometimes display correctly, and other times will slow down the first part of the bag transition and speed up the end, or it will clump a few transitions together. In mobile Safari and mobile Chrome on an iPhone 6, sometimes it will just ignore the animation-delay all together and transition the whole bag at once. I'm having a hard time troubleshooting when the performance isn't consistent. I added a little JavaScript to make sure that all the assets were loaded on the page before starting the animation, but that didn't seem to help. Anyone have any idea what's happening here?

http://codepen.io/brendamarienyc/pen/qdoOZM

@-webkit-keyframes bag-1 {
  0%, 
    19.9% {
    opacity: 0;
  }
  20%,
    100% {
    opacity: 1;
  }
}
@keyframes bag-1 {
  0%, 
    19.9% {
    opacity: 0;
  }
  20%,
    100% {
    opacity: 1;
  }
}
.satchel-1 {
  -webkit-animation-name: bag-1;
          animation-name: bag-1;
  -webkit-animation-duration: 22500ms;
          animation-duration: 22500ms;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-transform: translateZ(0);
          transform: translateZ(0);
  opacity: 0;
}
.preload .satchel-1 {
  -webkit-animation-name: none !important;
          animation-name: none !important;
}

@-webkit-keyframes bag-2 {
  0%, 
    39.9% {
    opacity: 0;
  }
  40%,
    100% {
    opacity: 1;
  }
}

@keyframes bag-2 {
  0%, 
    39.9% {
    opacity: 0;
  }
  40%,
    100% {
    opacity: 1;
  }
}
.satchel-2 {
  -webkit-animation-name: bag-2;
          animation-name: bag-2;
  -webkit-animation-duration: 22500ms;
          animation-duration: 22500ms;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-transform: translateZ(0);
          transform: translateZ(0);
  opacity: 0;
}
.preload .satchel-2 {
  -webkit-animation-name: none !important;
          animation-name: none !important;
}

@-webkit-keyframes bag-3 {
  0%, 
    59.9% {
    opacity: 0;
  }
  60%,
    100% {
    opacity: 1;
  }
}

@keyframes bag-3 {
  0%, 
    59.9% {
    opacity: 0;
  }
  60%,
    100% {
    opacity: 1;
  }
}
.satchel-3 {
  -webkit-animation-name: bag-3;
          animation-name: bag-3;
  -webkit-animation-duration: 22500ms;
          animation-duration: 22500ms;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-transform: translateZ(0);
          transform: translateZ(0);
  opacity: 0;
}
.preload .satchel-3 {
  -webkit-animation-name: none !important;
          animation-name: none !important;
}

@-webkit-keyframes bag-4 {
  0%, 
    79.9% {
    opacity: 0;
  }
  80%,
    100% {
    opacity: 1;
  }
}

@keyframes bag-4 {
  0%, 
    79.9% {
    opacity: 0;
  }
  80%,
    100% {
    opacity: 1;
  }
}
.satchel-4 {
  -webkit-animation-name: bag-4;
          animation-name: bag-4;
  -webkit-animation-duration: 22500ms;
          animation-duration: 22500ms;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-transform: translateZ(0);
          transform: translateZ(0);
  opacity: 0;
}
.preload .satchel-4 {
  -webkit-animation-name: none !important;
          animation-name: none !important;
}

@-webkit-keyframes bag-5 {
  0%, 
    99.9% {
    opacity: 0;
  }
  100%,
    100% {
    opacity: 1;
  }
}

@keyframes bag-5 {
  0%, 
    99.9% {
    opacity: 0;
  }
  100%,
    100% {
    opacity: 1;
  }
}
.satchel-5 {
  -webkit-animation-name: bag-5;
          animation-name: bag-5;
  -webkit-animation-duration: 22500ms;
          animation-duration: 22500ms;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-transform: translateZ(0);
          transform: translateZ(0);
  opacity: 0;
}
.preload .satchel-5 {
  -webkit-animation-name: none !important;
          animation-name: none !important;
}

.satchel-container {
  height: 450px;
  width: 472px;
  margin: 2em auto;
  position: relative;
}
@media (max-width: 500px) {
  .satchel-container {
    height: 300px;
    width: 315px;
  }
}

.satchel-shadow {
  position: absolute;
  right: 0px;
  bottom: 0px;
  left: 0px;
  height: 94px;
  width: 472px;
}
@media (max-width: 500px) {
  .satchel-shadow {
    height: 63px;
    width: 315px;
  }
}

.satchel-body {
  position: absolute;
  right: 0px;
  bottom: 0px;
  left: 0px;
  height: 295px;
  width: 472px;
  -webkit-animation-delay: 0;
          animation-delay: 0;
}
@media (max-width: 500px) {
  .satchel-body {
    height: 197px;
    width: 315px;
  }
}

.satchel-gusset {
  position: absolute;
  bottom: 30px;
  left: 14px;
  height: 221px;
  width: 441px;
  -webkit-animation-delay: 450ms;
          animation-delay: 450ms;
}
@media (max-width: 500px) {
  .satchel-gusset {
    position: absolute;
    bottom: 20px;
    left: 10px;
    height: 149px;
    width: 294px;
  }
}

.satchel-piping {
  position: absolute;
  bottom: 22px;
  left: 21px;
  height: 268px;
  width: 429px;
  -webkit-animation-delay: 900ms;
          animation-delay: 900ms;
}
@media (max-width: 500px) {
  .satchel-piping {
    position: absolute;
    bottom: 15px;
    left: 14px;
    height: 179px;
    width: 286px;
  }
}

.satchel-collar {
  position: absolute;
  bottom: 15px;
  left: 30px;
  height: 63px;
  width: 412px;
  -webkit-animation-delay: 900ms;
          animation-delay: 900ms;
}
@media (max-width: 500px) {
  .satchel-collar {
    position: absolute;
    bottom: 7px;
    left: 20px;
    height: 42px;
    width: 275px;
  }
}

.satchel-strap {
  position: absolute;
  bottom: 70px;
  left: 139px;
  height: 370px;
  width: 195px;
  -webkit-animation-delay: 1350ms;
          animation-delay: 1350ms;
}
@media (max-width: 500px) {
  .satchel-strap {
    position: absolute;
    bottom: 47px;
    left: 92px;
    height: 247px;
    width: 130px;
  }
}

.satchel-narrow {
  position: absolute;
  bottom: 68px;
  left: 13px;
  height: 232px;
  width: 377px;
  -webkit-animation-delay: 1800ms;
          animation-delay: 1800ms;
}
@media (max-width: 500px) {
  .satchel-narrow {
    position: absolute;
    bottom: 46px;
    left: 8px;
    height: 155px;
    width: 251px;
  }
}

4 answers

4

от того, что я вижу, что вы на самом деле не дает задержек элементов правильно, назначение задержки анимации должно быть что-то вроде этого.

.satchel-strap.satchel-#{$i}{
     animation-delay: $bag-piece-timing * 1.5 * $i
  }

  .satchel-body.satchel-#{$i}{
     animation-delay: $bag-piece-timing * $i;
  }

  .satchel-gusset.satchel-#{$i}{
     animation-delay: $bag-piece-timing * 0.5 * $i
  }

  .satchel-piping.satchel-#{$i}{
    animation-delay: $bag-piece-timing;
  }

  .stachel-collar.satchel-#{$i}{
    animation-delay: $bag-piece-timing;
  }
6

что о попытке использовать простой переход вместо ключевого кадра анимации? вы только переход непрозрачности здесь - может быть, с помощью пользовательской кривой Безье вы можете достичь того же эффекта.

Вы также можете попробовать заменить -webkit-преобразование: translateZ (0); с -webkit-преобразование: translate3d (0,0,0); - Я заметил небольшие проблемы синхронизации между ними в прошлом (вы используете эту технику только, чтобы заставить элементы на своем собственном аппаратном уровне?)

0

Я играл немного с CSSтак же как я искал мобильные webkitконкретные вопросы , но я не нашел ничего полезного.

Поэтому в основном я переработан проблему и используется CSS transitionsдля замирания-In / Out эффекты и JQuery для управления темп этих анимаций.

Смотрите демо .

Я испытал это на прошивку и Safari, а также другие браузерах, и она работала хорошо для меня.

HTML (перегруппировку изображения по модели мешков)

<div id="bag1" class="bag shown">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-black-croc.png" class="satchel-static satchel-body">
  <!-- <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-collar-blue-python.png" class="satchel-3 satchel-collar"> -->
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-black-croc.png" class="satchel-static satchel-gusset">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-black-croc.png" class="satchel-static satchel-piping">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-black-croc.png" class="satchel-static satchel-strap">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-marble-python.png" class="satchel-static satchel-narrow">
</div>

<div id="bag2" class="bag">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-marble-python.png" class="satchel-1 satchel-body">
  <!-- <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-collar-bone.png" class="satchel-4 satchel-collar"> -->
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-marble-python.png" class="satchel-1 satchel-gusset">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-marble-python.png" class="satchel-1 satchel-piping">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-marble-python.png" class="satchel-1 satchel-strap">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-blue-python.png" class="satchel-1 satchel-narrow">
</div>

<div id="bag3" class="bag">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-celedon.png" class="satchel-2 satchel-body">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-celedon.png" class="satchel-2 satchel-gusset">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-celedon.png" class="satchel-2 satchel-piping">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-celedon.png" class="satchel-2 satchel-strap">
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-celedon.png" class="satchel-2 satchel-narrow">
</div>

CSS (заменить все анимации CSS3 для этих нескольких строк кода)

.bag img {
  z-index: 0;
  opacity: 0;
  -webkit-transition: opacity .1s ease-in-out;
  transition: opacity .1s ease-in-out;
}

.shown img {
  opacity: 1;
}
.shown img.satchel-strap, .shown img.satchel-narrow {
  z-index: 2;
}

.bag .fadeIn {
  opacity: 1;
  z-index: 1;
}
.bag .fadeIn.satchel-strap, .bag .fadeIn.satchel-narrow {
  z-index: 3;
}

JQuery (вы можете установить параметры анимации)

$(document).ready(function() {

  var $bags         = [$('#bag1'), $('#bag2'), $('#bag3')],
      piecesDelay   = 400,
      bagsDelay     = 3000,
      timePiecesID,
      imgs;


  setTimeout(function() { 
    loopThroughBags(1, 0); 
  }, bagsDelay);


  function fadeInPieces(k) {
    $(imgs[k]).addClass('fadeIn');

    timePiecesID = setTimeout(function() {
      if (k < imgs.length - 1) {
        k++;
        fadeInPieces(k);
      } else {
        clearTimeout(timePiecesID);
        return;
      }
    }, piecesDelay);

  } // fadeInPieces ends


  function loopThroughBags(i, j) {

    imgs = $bags[i].find('img');

    fadeInPieces(0);

    setTimeout(function() {

      clearTimeout(timePiecesID);

      $bags[i].addClass('shown');
      $(imgs).removeClass('fadeIn');
      $bags[j].removeClass('shown');

      j = i;
      i = (i < $bags.length - 1) ? i + 1 : 0;

      loopThroughBags(i, j);

    }, bagsDelay);

  } // loopThroughBags ends

});
9

Даже если в Chrome показывает хорошо, даже там есть проблемы с производительностью. Попытка получить статистику производительности глючит, и сделать 6 копий базовой конструкции и отключение GPU воспроизводит эту проблему на моей машине (Chrome на Windows).

Ну, вот моя попытка оптимизировать производительность вашего дизайна.

Прежде всего, вы используете прозрачность, но без перехода - движется очень быстро от 0 до 1. Если все, что вы хотите изменить видимость элемента, вы можете использовать видимость для этого. Она будет работать намного быстрее.

Во-вторых, вы используете анимацию, которая отличается для 5 различных мешков. И это держит первые сумки видны - но скрыто под другими из них в последней части анимации. Вы можете использовать ту же анимацию для всех элементов, только изменяя задержку анимации. Вы увидите в моем демо, что ключевые кадры проще, за счет повышенной сложности в задержке анимации. Заметьте также, что я выключаю видимость, как только Возможное, чтобы избежать затрат отображения невидимого элемента.

Как вы справились с накладками, заданные для первого элемента каждого класса должны быть повторены после того, как статические и другой показ на несколько мгновений в конце цикла. Я изменил эту схему еще один, где я меняющийся Z-индекс элементов. Теперь вам не нужно повторять этот элемент.

И наконец, я сгруппировал несколько предметов под классом мешка, и я выключая также видимость контейнера мешка. Я считаю, что это как-то оптимизировать производительность, но я не уверен в этом

Мои демо:

@-webkit-keyframes satchel {
  0% {
    visibility: visible;
    z-index: 100;
  }
  25% {
    visibility: visible;
    z-index: 1;
  }
  25%, 100% {
    visibility: hidden;
  }
}
@keyframes satchel {
  0% {
    visibility: visible;
    z-index: 100;
  }
  25% {
    visibility: visible;
    z-index: 1;
  }
  25%, 100% {
    visibility: hidden;
  }
}

.satchel-1, .satchel-2, .satchel-3, .satchel-4, .satchel-5 {
    -webkit-animation: satchel 22500ms infinite;
    animation-name: satchel;
    animation-duration: 22500ms;
    animation-iteration-count: infinite;
}

/* body 0ms gusset 450ms collar=900ms piping=900ms strap=1350ms narrow=1800ms  */
.satchel-1.satchel-body {
    -webkit-animation-delay: calc(0ms - 22500ms);
    animation-delay: calc(0ms - 22500ms);
}
.satchel-1.satchel-gusset {
    -webkit-animation-delay: calc(450ms - 22500ms);
    animation-delay: calc(450ms - 22500ms);
}
.satchel-1.satchel-collar {
    -webkit-animation-delay: calc(900ms - 22500ms);
    animation-delay: calc(900ms - 22500ms);
}
.satchel-1.satchel-piping {
    -webkit-animation-delay: calc(900ms - 22500ms);
    animation-delay: calc(900ms - 22500ms);
}
.satchel-1.satchel-strap {
    -webkit-animation-delay: calc(1350ms - 22500ms);
    animation-delay: calc(1350ms - 22500ms);
}
.satchel-1.satchel-narrow {
    -webkit-animation-delay: calc(1800ms - 22500ms);
    animation-delay: calc(1800ms - 22500ms);
}

/* satchel-2 4500ms */
.satchel-2.satchel-body {
    -webkit-animation-delay: calc(0ms + 4500ms - 22500ms);
    animation-delay: calc(0ms + 4500ms - 22500ms);
}
.satchel-2.satchel-gusset {
    -webkit-animation-delay: calc(450ms + 4500ms - 22500ms);
    animation-delay: calc(450ms + 4500ms - 22500ms);
}
.satchel-2.satchel-collar {
    -webkit-animation-delay: calc(900ms + 4500ms - 22500ms);
    animation-delay: calc(900ms + 4500ms - 22500ms);
}
.satchel-2.satchel-piping {
    -webkit-animation-delay: calc(900ms + 4500ms - 22500ms);
    animation-delay: calc(900ms + 4500ms - 22500ms);
}
.satchel-2.satchel-strap {
    -webkit-animation-delay: calc(1350ms + 4500ms - 22500ms);
    animation-delay: calc(1350ms + 4500ms - 22500ms);
}
.satchel-2.satchel-narrow {
    -webkit-animation-delay: calc(1800ms + 4500ms - 22500ms);
    animation-delay: calc(1800ms + 4500ms - 22500ms);
}

/* satchel-3 9000ms */
.satchel-3.satchel-body {
    -webkit-animation-delay: calc(0ms + 9000ms - 22500ms);
    animation-delay: calc(0ms + 9000ms - 22500ms);
}
.satchel-3.satchel-gusset {
    -webkit-animation-delay: calc(450ms + 9000ms - 22500ms);
    animation-delay: calc(450ms + 9000ms - 22500ms);
}
.satchel-3.satchel-collar {
    -webkit-animation-delay: calc(900ms + 9000ms - 22500ms);
    animation-delay: calc(900ms + 9000ms - 22500ms);
}
.satchel-3.satchel-piping {
    -webkit-animation-delay: calc(900ms + 9000ms - 22500ms);
    animation-delay: calc(900ms + 9000ms - 22500ms);
}
.satchel-3.satchel-strap {
    -webkit-animation-delay: calc(1350ms + 9000ms - 22500ms);
    animation-delay: calc(1350ms + 9000ms - 22500ms);
}
.satchel-3.satchel-narrow {
    -webkit-animation-delay: calc(1800ms + 9000ms - 22500ms);
    animation-delay: calc(1800ms + 9000ms - 22500ms);
}
/* satchel-4 13500ms */
.satchel-4.satchel-body {
    -webkit-animation-delay: calc(0ms + 13500ms - 22500ms);
    animation-delay: calc(0ms + 13500ms - 22500ms);
}
.satchel-4.satchel-gusset {
    -webkit-animation-delay: calc(450ms + 13500ms - 22500ms);
    animation-delay: calc(450ms + 13500ms - 22500ms);
}
.satchel-4.satchel-collar {
    -webkit-animation-delay: calc(900ms + 13500ms - 22500ms);
    animation-delay: calc(900ms + 13500ms - 22500ms);
}
.satchel-4.satchel-piping {
    -webkit-animation-delay: calc(900ms + 13500ms - 22500ms);
    animation-delay: calc(900ms + 13500ms - 22500ms);
}
.satchel-4.satchel-strap {
    -webkit-animation-delay: calc(1350ms + 13500ms - 22500ms);
    animation-delay: calc(1350ms + 13500ms - 22500ms);
}
.satchel-4.satchel-narrow {
    -webkit-animation-delay: calc(1800ms + 13500ms - 22500ms);
    animation-delay: calc(1800ms + 13500ms - 22500ms);
}
/* satchel-5 18000ms */
.satchel-5.satchel-body {
    -webkit-animation-delay: calc(0ms + 18000ms - 22500ms);
    animation-delay: calc(0ms + 18000ms - 22500ms);
}
.satchel-5.satchel-gusset {
    -webkit-animation-delay: calc(450ms + 18000ms - 22500ms);
    animation-delay: calc(450ms + 18000ms - 22500ms);
}
.satchel-5.satchel-collar {
    -webkit-animation-delay: calc(900ms + 18000ms - 22500ms);
    animation-delay: calc(900ms + 18000ms - 22500ms);
}
.satchel-5.satchel-piping {
    -webkit-animation-delay: calc(900ms + 18000ms - 22500ms);
    animation-delay: calc(900ms + 18000ms - 22500ms);
}
.satchel-5.satchel-strap {
    -webkit-animation-delay: calc(1350ms + 18000ms - 22500ms);
    animation-delay: calc(1350ms + 18000ms - 22500ms);
}
.satchel-5.satchel-narrow {
    -webkit-animation-delay: calc(1800ms + 18000ms - 22500ms);
    animation-delay: calc(1800ms + 18000ms - 22500ms);
}

@-webkit-keyframes bag {
  0%, 35% {
    visibility: visible;
  }
  35%, 100% {
    visibility: hidden;
  }
}
@keyframes bag {
  0%, 35% {
    visibility: visible;
  }
  35%, 100% {
    visibility: hidden;
  }
}

.bag {
    -webkit-animation-name: bag;
    -webkit-animation-duration: 22500ms;
    -webkit-animation-iteration-count: infinite;
    animation-name: bag;
    animation-duration: 22500ms;
    animation-iteration-count: infinite;
    z-index: 1000;
    position: absolute;
    height: 100%;
    width: 100%;
}
.bag:nth-child(2) {
    -webkit-animation-delay: calc(4500ms - 22500ms);
    animation-delay: calc(4500ms - 22500ms);
}
.bag:nth-child(3) {
    -webkit-animation-delay: calc(9000ms - 22500ms);
    animation-delay: calc(9000ms - 22500ms);
}
.bag:nth-child(4) {
    -webkit-animation-delay: calc(13500ms - 22500ms);
    animation-delay: calc(13500ms - 22500ms);
}
.bag:nth-child(5) {
    -webkit-animation-delay: calc(18000ms - 22500ms);
    animation-delay: calc(18000ms - 22500ms);
}


.satchel-container {
  height: 450px;
  width: 472px;
  margin: 2em;
  position: relative;
  display: inline-block;
}
@media (max-width: 500px) {
  .satchel-container {
    height: 300px;
    width: 315px;
  }
}

.satchel-shadow {
  position: absolute;
  right: 0px;
  bottom: 0px;
  left: 0px;
  height: 94px;
  width: 472px;
}
@media (max-width: 500px) {
  .satchel-shadow {
    height: 63px;
    width: 315px;
  }
}

.satchel-body {
  position: absolute;
  right: 0px;
  bottom: 0px;
  left: 0px;
  height: 295px;
  width: 472px;
}
@media (max-width: 500px) {
  .satchel-body {
    height: 197px;
    width: 315px;
  }
}

.satchel-gusset {
  position: absolute;
  bottom: 30px;
  left: 14px;
  height: 221px;
  width: 441px;
}
@media (max-width: 500px) {
  .satchel-gusset {
    position: absolute;
    bottom: 20px;
    left: 10px;
    height: 149px;
    width: 294px;
  }
}

.satchel-piping {
  position: absolute;
  bottom: 22px;
  left: 21px;
  height: 268px;
  width: 429px;
}
@media (max-width: 500px) {
  .satchel-piping {
    position: absolute;
    bottom: 15px;
    left: 14px;
    height: 179px;
    width: 286px;
  }
}

.satchel-collar {
  position: absolute;
  bottom: 15px;
  left: 30px;
  height: 63px;
  width: 412px;
}
@media (max-width: 500px) {
  .satchel-collar {
    position: absolute;
    bottom: 7px;
    left: 20px;
    height: 42px;
    width: 275px;
  }
}

.satchel-strap {
  position: absolute;
  bottom: 70px;
  left: 139px;
  height: 370px;
  width: 195px;
}
@media (max-width: 500px) {
  .satchel-strap {
    position: absolute;
    bottom: 47px;
    left: 92px;
    height: 247px;
    width: 130px;
  }
}

.satchel-narrow {
  position: absolute;
  bottom: 68px;
  left: 13px;
  height: 232px;
  width: 377px;
    animation-delay: calc(1800ms - 22500ms);
}
@media (max-width: 500px) {
  .satchel-narrow {
    position: absolute;
    bottom: 46px;
    left: 8px;
    height: 155px;
    width: 251px;
  }
}
<section class="bag-animation">
    <div class="satchel-container">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-shadow.png" class="satchel-shadow">

      <!--Satchel Body-->
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-marble-python.png" class="satchel-1 satchel-body">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-celedon.png" class="satchel-2 satchel-body">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-blue-python.png" class="satchel-body satchel-3">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-bone.png" class="satchel-4 satchel-body">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-body-black-croc.png" class="satchel-5 satchel-body">

      <!--bag marble-->
      <div class="bag">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-marble-python.png" class="satchel-1 satchel-gusset">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-marble-python.png" class="satchel-1 satchel-piping">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-marble-python.png" class="satchel-1 satchel-strap">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-blue-python.png" class="satchel-1 satchel-narrow">
      </div>

      <!--bag celedon-->
      <div class="bag">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-celedon.png" class="satchel-2 satchel-gusset">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-celedon.png" class="satchel-2 satchel-piping">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-celedon.png" class="satchel-2 satchel-strap">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-celedon.png" class="satchel-2 satchel-narrow">
	</div>

      <!--bag blue-->
      <div class="bag">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-blue-python.png" class="satchel-3 satchel-gusset">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-blue-python.png" class="satchel-3 satchel-piping">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-blue-python.png" class="satchel-3 satchel-strap">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-blue-python.png" class="satchel-3 satchel-narrow">
	</div>

      <!--bag bone-->
      <div class="bag">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-bone.png" class="satchel-4 satchel-gusset">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-bone.png" class="satchel-4 satchel-piping">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-bone.png" class="satchel-4 satchel-strap">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-bone.png" class="satchel-4 satchel-narrow">
      </div>

      <!--bag bone-->
      <div class="bag">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-gusset-black-croc.png" class="satchel-5 satchel-gusset">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-piping-black-croc.png" class="satchel-5 satchel-piping">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-strap-black-croc.png" class="satchel-5 satchel-strap">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/196308/satchel-narrow-black-croc.png" class="satchel-5 satchel-narrow">
      </div>

    </div>


  </section>

Существует также другой вешать, что будет гораздо более эффективным, но менее гибок: Вы можете сгруппировать ваши изображения одного и того же класса в составном изображении, и справиться с этим, как изменение спрайтов (изменение позиции фонового изображения Вам нужно, однако. полный редизайн для этого.