<div class='board'></div>
<div class='clone'>
  <div class='face'></div>
  <div class='face'></div>
  <div class='face'></div>
  <div class='face'></div>
  <div class='face'></div>
  <div class='face'></div>
</div>
<div class='overlay hidden'>
  <div class='gameover'>
    <p>Super gemacht!</p>
    <button class='reset'>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"><path d="M485.8 113.9L349.3 250.5c-3.5 3.5-3.5 9.1 0 12.6l136.6 136.6c5.6 5.6 15.2 1.6 15.2-6.3V120.2c-.1-7.9-9.7-11.9-15.3-6.3z" fill="#fff"/><path d="M500 194.8V317c125.9 0 228 102.1 228 228S625.9 773 500 773v121.8c193.3 0 350-156.7 350-350s-156.7-350-350-350zM272 545c0-55.1 19.6-105.7 52.1-145.1 6.5-7.9 5.9-19.5-1.4-26.8l-58.3-58.3c-8.2-8.2-21.7-7.7-29.3 1-53 61.5-85.1 141.5-85.1 229 0 193.3 156.7 350 350 350V773c-125.9 0-228-102.1-228-228z" fill="#fff"/></svg>
    </button>
  </div>
</div>

<!-- Preload Game Sounds -->
<audio preload="auto" class="audio-win" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/dino-win.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/dino-win.ogg">
</audio>
<audio preload="auto" class="audio-ahahah" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ahahah.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ahahah.ogg">
</audio>
<audio preload="auto" class="audio-dino" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audo-dino.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-dino.ogg">
</audio>
<audio preload="auto" class="audio-egg" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-egg.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-egg.ogg">
</audio>
<audio preload="auto" class="audio-erupt" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-erupt.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-erupt.ogg">
</audio>
<audio preload="auto" class="audio-ptero" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ptero.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ptero.ogg">
</audio>
<audio preload="auto" class="audio-tri" >
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-tri.mp3">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-tri.ogg">
</audio>


body {
  align-items: center;
  background-image: radial-gradient(circle 448px at center, #e0e0e0 0%, #ffffff 50%);
  display: flex;
  height: 100vh;
  justify-content: center;
  overflow: hidden;
  perspective: 1200px;
}

.board {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(4, 100px);
  grid-template-rows: repeat(4, 100px);
  position: relative;
  top: 20px;
  transform-style: preserve-3d;
  transform: rotateX(20deg) rotateZ(2deg);
  user-select: none;
}

.clone {
  display: none;
}

.cube {
  animation: enter 600ms ease-out;
  transform-style: preserve-3d;
  transform: translateZ(0) scale(1);
  transition: all 350ms ease-out;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  
  &.flipped {
    pointer-events: none;
    transform: rotateY(180deg) translateZ(0) scale(1);
    transition: all 500ms ease-out;
  }
  
  &.matched {
    pointer-events: none;
    transform: rotateY(180deg) translateZ(0) scale(1);
    animation: match 650ms ease-out;
  }
}

.face {
  outline: 1px solid transparent;
  backface-visibility: hidden;
  box-shadow: inset 0 0 1px 1px #fff;
  height: 100px;
  overflow: hidden;
  position: absolute;
  transform-origin: 50% 50%;
  width: 100px;
}

.face:nth-child(1) {
  background-color: #a72c80;
  cursor: pointer;
  transform: rotateY(0deg) translateZ(10px);
  transition: background 150ms ease-out;
    
  &:before {
    align-items: center;
    bottom: 0;
    color: #fff;
    content: '?';
    display: flex;
    font-family: 'Verdana', cursive;
    font-size: 60px;
    justify-content: center;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
  }
}

.face:nth-child(2) {
  background-color: darken(#a72c80, 10%);
  width: 20px;
  transform: rotateY(90deg) translateZ(90px)
}
.face:nth-child(3) {
  background-color: dodgerblue;
  transform: rotateY(180deg) translateZ(10px)
}
.face:nth-child(4) {
  background-color: darken(#a72c80, 10%);
  width: 20px;
  transform: rotateY(270deg) translateZ(10px)
}
.face:nth-child(5) {
  background-color: darken(#a72c80, 10%);
  height: 20px;
  transform: rotateX(90deg) translateZ(10px)
}
.face:nth-child(6) {
  background-color: darken(#a72c80, 10%);
  height: 20px;
  transform: rotateX(-90deg) translateZ(90px)
}

.overlay {
  align-items: center;
  background: rgba(255,255,255,0.75);
  width: 100vw;
  display: flex;
  justify-content: center;
  left: 0;
  opacity: 1;
  position: absolute;
  height: 100vh;
  top: 0;
  transition: all 500ms ease-out;
  z-index: 100;
  
  &.hidden {
    opacity: 0;
    pointer-events: none;
    transition: all 300ms ease-out;
    
    .gameover {
      transform: translateY(60px);
      transition: all 300ms ease-out;
    }
  }
}

.gameover {
  align-items: center;
  background-color: #fff;
  border-radius: 120px;
  border: 12px solid #50b8f7;
  color: #2e2e2e;
  display: flex;
  font-family: 'Verdana', cursive;
  font-size: 40px;
  height: 120px;
  width: 340px;
  justify-content: space-between;
  padding: 0 10px 0 30px;
  transform: translateY(0);
  transition: all 500ms ease-out;
  user-select: none;
}

.reset {
  background-color: #fbc300;
  border-radius: 50%;
  border: 0;
  box-shadow: 0px 6px 0px 0px #f2a003;
  cursor: pointer;
  display: block;
  height: 94px;
  margin-left: 20px;
  position: relative;
  top: -3px;
  width: 96px;
  
  &:active {
    box-shadow: none;
    top: 0;
  }
  
  &:focus {
    outline: 0;
  }
}

.twitter__link {
  user-select: none;
  cursor: pointer;
  position: absolute;
  right: 10px;
  top: 12px;
  z-index: -1;
  background: #fff;
  border-radius: 20px;
  height: 30px;
  text-decoration: none;
  padding-right: 10px;
  justify-content: space-between;
  font-family: sans-serif;
  font-weight: 600;
  display: flex;
  align-items: center;
  color: #00aced;
  font-size: 14px;
  width: 74px;
  opacity: 0.4;
  z-index: 10;
  
  &:hover {
    opacity: 1;
  }
}

.twitter__icon {
  height: 30px;
}




[data-tile="egg"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/naseweis1.png) center center no-repeat;
   background-size: contain;
  }
}
[data-tile="egg"]~[data-tile="egg"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/naseweis2.png) center center no-repeat;
   background-size: contain;
  }
}



[data-tile="dino"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/hosentraeger1.png);
    background-size: contain;
  }
}
[data-tile="dino"]~[data-tile="dino"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/hosentraeger2.png);
    background-size: contain;
  }
}


[data-tile="ahahah"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/zoepfe1.png) center center no-repeat;
    background-size: contain;
  }
}
[data-tile="ahahah"]~[data-tile="ahahah"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/zoepfe2.png) center center no-repeat;
    background-size: contain;
  }
}




[data-tile="tri"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/fleissig1.png) center center no-repeat;
    background-size: contain;
  }
}
[data-tile="tri"]~[data-tile="tri"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/fleissig2.png) center center no-repeat;
    background-size: contain;
  }
}



[data-tile="ptero"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/oben1.png) center center no-repeat;
    background-size: contain;
  }
}
[data-tile="ptero"]~[data-tile="ptero"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/oben2.png) center center no-repeat;
    background-size: contain;
  }
}



[data-tile="erupt"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/gabel1.png) center center no-repeat;
   background-size: contain;
  }
}
[data-tile="erupt"]~[data-tile="erupt"] { 
  div:nth-child(3) {
    background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/gabel2.png) center center no-repeat;
   background-size: contain;
  }
}


audio {
  display: none;
}


@keyframes enter {
  0% {
    transform: translateZ(-20px) scale(0.3);
  }
  50% {
    transform: translateZ(20px) scale(1.02);
  }
  100% {
    transform: translateZ(0) scale(1);
  }
}

@keyframes match {
  0% {
    transform: rotateY(180deg) translateZ(-15px);
  }
  50% {
    transform: rotateY(180deg) translateZ(10px);
  }
  100% {
    transform: rotateY(180deg) translateZ(0);
  }
}
View Compiled
const board = document.querySelector('.board');
const clone = document.querySelector('.clone');
const overlay = document.querySelector('.overlay');
const reset = document.querySelector('.reset');
const tileOptions = ['erupt', 'ptero', 'tri', 'ahahah', 'egg', 'dino'];

const state = {
  selections: [],
  boardLocked: false,
  matches: 0
};

reset.addEventListener('click', () => {
  if (state.boardLocked) return;
  resetGame();
});

function resetGame() {
  state.boardLocked = true;
  state.selections = [];
  state.matches = 0;

  document.querySelectorAll('.cube').forEach(tile => {
    tile.removeEventListener('click', () => selectTile(tile));
    tile.remove();
  });

  overlay.classList.add('hidden');
  createBoard();
}

function createBoard() {
  const tiles = shuffleArray([...tileOptions, ...tileOptions]);
  const length = tiles.length;

  for (let i = 0; i < length; i++) {
    window.setTimeout(() => {
      board.appendChild(buildTile(tiles.pop(), i));
    }, i * 100);
  }

  window.setTimeout(() => {
    document.querySelectorAll('.cube').forEach(tile => {
      tile.addEventListener('click', () => selectTile(tile));
    });

    state.boardLocked = false;
  }, tiles.length * 100);
}

function buildTile(option, id) {
  const tile = clone.cloneNode(true);
  tile.classList.remove('clone');
  tile.classList.add('cube');
  tile.setAttribute('data-tile', option);
  tile.setAttribute('data-id', id);
  return tile;
}

function selectTile(selectedTile) {
  if (state.boardLocked || selectedTile.classList.contains('flipped')) return;

  state.boardLocked = true;

  if (state.selections.length <= 1) {
    selectedTile.classList.add('flipped');
    state.selections.push({
      id: selectedTile.dataset.id,
      tile: selectedTile.dataset.tile,
      el: selectedTile
    });
  }

  /* =================================*
   *      Welcome to Timeout City     *
   *  Time since last incident: 300ms *
   * =================================*/
  if (state.selections.length === 2) {
    if (state.selections[0].tile === state.selections[1].tile) {
      window.setTimeout(() => {
        state.selections[0].el.classList.add('matched');
        state.selections[1].el.classList.add('matched');
        
        state.boardLocked = false;
        state.matches = state.matches + 1;
        
        if (state.matches === tileOptions.length) {
          window.setTimeout(() => {
            overlay.classList.remove('hidden');
            document.querySelector('.audio-win').play();
          }, 600);
        }
        state.selections = [];
        document.querySelector(`.audio-${selectedTile.dataset.tile}`).play();
      }, 600);
    } else {
      setTimeout(() => {
        document.querySelectorAll('.cube').forEach(tile => {
          tile.classList.remove('flipped');
        });
        state.boardLocked = false;
      }, 800);
      state.selections = [];
    }
  } else {
    state.boardLocked = false;
  }
}

// 🍝 Copy-Pasta - "ain't nobody got time for that"
function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

createBoard();
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.