CSS only Room Escape

Collect Sep 11, 2020

An interesting interactive escape room game without javascript by Takane Ichinose.

HTML Code

<div class="container">
  <!-- FRONT -->
  <input type="radio" name="stage" class="stage-radio" checked />
  <label class="stage front" for="instructions"></label>
  <!-- INSTRUCTIONS -->
  <input type="radio" name="stage" id="instructions" class="stage-radio" />
  <label class="stage instructions" for="stage_1"></label>
  <!-- STAGE 1 -->
  <input type="radio" name="stage" id="stage_1" class="stage-radio" />
  <form class="stage stage-1">
    <!-- MAP 1 -->
    <input type="radio" class="map-radio" id="stage_1_map_1" checked />
    <div class="map stage-1-map-1">
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- MAT -->
      <div class="object mat"
           style="--object-top: 170px; --object-left: 80px;"></div>
      <!-- CLOSED DOOR -->
      <input type="checkbox" id="stage_1_door" class="door-way-checkbox" />
      <label class="door-way door-way-close" for="stage_1_door">
        <div class="door"></div>
      </label>
      <!-- OPEN DOOR -->
      <label class="door-way door-way-open" for="stage_2">
        <div class="door"></div>
      </label>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 130px; --object-left: 55px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 100px; --object-left: 158px;"></div>
    </div>
    <!-- RESET -->
    <input type="reset" class="nav nav-reset" value="" />
    <!-- STAGE LABEL -->
    <div class="stage-label stage-label-1"></div>
  </form>
  <!-- STAGE 2 -->
  <input type="radio" name="stage" id="stage_2" class="stage-radio" />
  <form class="stage stage-2">
    <!-- DOOR KEY -->
    <input type="checkbox"
           id="stage_2_map_1_key"
           class="key-checkbox door-key" />
    <!-- MAP 1 -->
    <input type="radio" class="map-radio" id="stage_2_map_1" checked />
    <div class="map stage-2-map-1">
      <!-- DOOR KEY TRIGGER -->
      <label class="object key door-key-trigger"
             for="stage_2_map_1_key"
             style="--object-top: 175px; --object-left: 112px;"></label>
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- MAT -->
      <input type="checkbox" id="stage_2_map_1_mat" class="mat-checkbox" />
      <label class="object mat"
             for="stage_2_map_1_mat"
             style="--object-top: 170px; --object-left: 80px;"></label>
      <!-- DISABLED DOOR -->
      <div class="door-way">
        <div class="door"></div>
      </div>
      <!-- CLOSED DOOR -->
      <input type="checkbox" id="stage_2_door" class="door-way-checkbox" />
      <label class="door-way door-way-close" for="stage_2_door">
        <div class="door"></div>
      </label>
      <!-- OPEN DOOR -->
      <label class="door-way door-way-open" for="stage_3">
        <div class="door"></div>
      </label>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 130px; --object-left: 55px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 100px; --object-left: 158px;"></div>
    </div>
    <!-- RESET -->
    <input type="reset" class="nav nav-reset" value="" />
    <!-- STAGE LABEL -->
    <div class="stage-label stage-label-2"></div>
  </form>
  <!-- STAGE 3 -->
  <input type="radio" name="stage" id="stage_3" class="stage-radio" />
  <form class="stage stage-3">
    <!-- CLOSET KEY -->
    <input type="checkbox"
           id="stage_3_map_1_closet_key"
           class="key-checkbox closet-key" />
    <!-- DOOR KEY -->
    <input type="checkbox"
           id="stage_3_map_2_key"
           class="key-checkbox door-key" />
    <!-- MAP 1 -->
    <input type="radio"
           name="stage3_radio"
           id="stage_3_map_1"
           class="map-radio"
           checked />
    <div class="map stage-3-map-1">
      <!-- DISABLED WINDOW -->
      <div class="window"
           style="--lockable-bottom: 90px; --lockable-left: 55px;">
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </div>
      <!-- DISABLED CLOSET -->
      <div class="closet closet-locked">
        <div class="closet-door closet-door-left"></div>
        <div class="closet-door closet-door-right"></div>
      </div>
      <!-- CLOSED CLOSET -->
      <input type="checkbox" id="stage_3_closet" class="closet-checkbox" />
      <label class="closet closet-close" for="stage_3_closet">
         <div class="closet-door closet-door-left"></div>
         <div class="closet-door closet-door-right"></div>
      </label>
      <!-- OPEN CLOSET -->
      <label class="closet closet-open" for="stage_3_closet">
        <div class="closet-door closet-door-left"></div>
        <div class="closet-door closet-door-right"></div>
        <!-- DOOR KEY TRIGGER -->
        <label class="object key door-key-trigger"
               for="stage_3_map_2_key"
               style="--object-top: 22px; --object-left: 26px;"></label>
      </label>
      <!-- FLOWER VASE -->
      <div class="object flower-vase"
           style="--object-top: 68px; --object-left: 113px;"></div>
      <!-- RESET -->
      <input type="reset" class="nav nav-reset" value="" />
      <!-- NAVIGATION -->
      <label class="nav nav-right" for="stage_3_map_2"></label>
    </div>
    <!-- MAP 2 -->
    <input type="radio"
           name="stage3_radio"
           id="stage_3_map_2"
           class="map-radio" />
    <div class="map stage-3-map-2">
      <!-- CLOSET KEY TRIGGER -->
      <label class="object key closet-key-trigger"
             for="stage_3_map_1_closet_key"
             style="--object-top: 175px; --object-left: 112px;"></label>
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- FRAME -->
      <div class="object frame"
           for="stage_4_map_3_frame"
           style="--object-top: 40px; --object-left: 17px;"></div>
      <!-- MAT -->
      <input type="checkbox" id="stage_3_map_2_mat" class="mat-checkbox" />
      <label class="object mat"
             for="stage_3_map_2_mat"
             style="--object-top: 170px; --object-left: 80px;"></label>
      <!-- DISABLED DOOR -->
      <div class="door-way">
        <div class="door"></div>
      </div>
      <!-- CLOSED DOOR -->
      <input type="checkbox" id="stage_3_door" class="door-way-checkbox" />
      <label class="door-way door-way-close" for="stage_3_door">
        <div class="door"></div>
      </label>
      <!-- OPEN DOOR -->
      <label class="door-way door-way-open" for="stage_4">
        <div class="door"></div>
      </label>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 100px; --object-left: 55px;"></div>
      <!-- BOOK SHELF -->
      <div class="object book-shelf"
           style="--object-top: 100px; --object-left: 147px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_3_map_1"></label>
    </div>
    <!-- RESET -->
    <input type="reset" class="nav nav-reset" value="" />
    <!-- STAGE LABEL -->
    <div class="stage-label stage-label-3"></div>
  </form>
  <!-- STAGE 4 -->
  <input type="radio" name="stage" id="stage_4" class="stage-radio" />
  <form class="stage stage-4">
    <!-- DOOR KEY -->
    <input type="checkbox"
           id="stage_4_map_2_key"
           class="key-checkbox door-key" />
    <!-- SCISSORS THREAD -->
    <input type="checkbox"
           id="stage_4_map_3_window_key"
           class="key-checkbox window-key" />
    <!-- MAP 1 -->
    <input type="radio"
           name="stage4_radio"
           id="stage_4_map_1"
           class="map-radio" />
    <div class="map stage-4-map-1">
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 130px; --object-left: 55px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 100px; --object-left: 163px;"></div>
      <!-- WINDOW KEY TRIGGER -->
      <label class="object scissors window-key-trigger"
             for="stage_4_map_3_window_key"
             style="--object-top: 60px; --object-left: 175px;"></label>
      <!-- FRAME -->
      <input type="checkbox"
             id="stage_4_map_3_frame"
             class="frame-checkbox" />
      <label class="object frame"
             for="stage_4_map_3_frame"
             style="--object-top: 40px; --object-left: 140px;"></label>
      <!-- DISABLED CLOSET -->
      <div class="closet closet-locked">
        <div class="closet-door closet-door-left"></div>
        <div class="closet-door closet-door-right"></div>
      </div>
      <!-- FLOWER VASE -->
      <div class="object flower-vase"
           style="--object-top: 68px; --object-left: 113px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-right" for="stage_4_map_2"></label>
    </div>
    <!-- MAP 2 -->
    <input type="radio"
           name="stage4_radio"
           id="stage_4_map_2"
           class="map-radio"
           checked />
    <div class="map stage-4-map-2">
      <!-- MAT -->
      <div class="object mat"
           style="--object-top: 170px; --object-left: 80px;"></div>
      <!-- BOOK SHELF -->
      <div class="object book-shelf"
           style="--object-top: 110px; --object-left: 19px;"></div>
      <!-- FLOWER VASE -->
      <div class="object flower-vase"
           style="--object-top: 64px; --object-left: 40px;"></div>
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- DISABLED DOOR -->
      <div class="door-way">
        <div class="door"></div>
      </div>
      <!-- CLOSED DOOR -->
      <input type="checkbox" id="stage_4_door" class="door-way-checkbox" />
      <label class="door-way door-way-close" for="stage_4_door">
        <div class="door"></div>
      </label>
      <!-- OPEN DOOR -->
      <label class="door-way door-way-open" for="stage_5">
        <div class="door"></div>
      </label>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 123px; --object-left: 185px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 90px; --object-left: 163px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_4_map_1"></label>
      <label class="nav nav-right" for="stage_4_map_3"></label>
    </div>
    <!-- MAP 3 -->
    <input type="radio"
           name="stage4_radio"
           id="stage_4_map_3"
           class="map-radio" />
    <div class="map stage-4-map-3">
      <!-- DISABLED WINDOW -->
      <div class="window"
           style="--lockable-bottom: 95px; --lockable-left: 14px;">
        <!-- DOOR KEY FAKE TRIGGER -->
        <div class="object key door-key-trigger"
             style="--object-top: 64px; --object-left: 79px;"></div>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </div>
      <!-- CLOSED WINDOW -->
      <input type="checkbox"
             id="stage_4_map_3_window_curtain_key"
             class="window-checkbox" />
      <label class="window window-close"
             for="stage_4_map_3_window_curtain_key"
             style="--lockable-bottom: 95px; --lockable-left: 14px;">
        <!-- DOOR KEY FAKE TRIGGER -->
        <div class="object key door-key-trigger"
             style="--object-top: 64px; --object-left: 79px;"></div>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </label>
      <!-- OPEN WINDOW -->
      <div class="window window-open"
             style="--lockable-bottom: 95px; --lockable-left: 14px;">
        <!-- DOOR KEY TRIGGER -->
        <label class="object key door-key-trigger"
               for="stage_4_map_2_key"
               style="--object-top: 64px; --object-left: 79px;"></label>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </div>
      <!-- MAT -->
      <input type="checkbox" id="stage_5_map_3_mat" class="mat-checkbox" />
      <label class="object mat"
             for="stage_5_map_3_mat"
             style="--object-top: 170px; --object-left: 60px;"></label>
      <!-- BOOK SHELF -->
      <div class="object book-shelf"
           style="--object-top: 110px; --object-left: 142px;"></div>
      <!-- FLOWER VASE -->
      <div class="object flower-vase"
           style="--object-top: 64px; --object-left: 164px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_4_map_2"></label>
    </div>
    <!-- RESET -->
    <input type="reset" class="nav nav-reset" value="" />
    <!-- STAGE LABEL -->
    <div class="stage-label stage-label-4"></div>
  </form>
  <!-- STAGE 5 -->
  <input type="radio" name="stage" id="stage_5" class="stage-radio" />
  <form class="stage stage-5">
    <!-- CLOSET KEY -->
    <input type="checkbox"
           id="stage_5_map_1_closet_key"
           class="key-checkbox closet-key" />
    <!-- SCISSORS THREAD -->
    <input type="checkbox"
           id="stage_5_map_2_window_key"
           class="key-checkbox window-key" />
    <!-- DOOR KEY -->
    <input type="checkbox"
           id="stage_5_fake_key"
           class="key-checkbox fake-key" />
    <!-- DOOR KEY -->
    <input type="checkbox"
           id="stage_5_map_4_key"
           class="key-checkbox door-key" />
    <!-- MAP 1 -->
    <input type="radio"
           name="stage5_radio"
           id="stage_5_map_1"
           class="map-radio" />
    <div class="map stage-5-map-1">
      <!-- FRAME -->
      <div class="object frame"
           style="--object-top: 35px; --object-left: 168px;"></div>
      <!-- BOOK SHELF -->
      <div class="object book-shelf"
           style="--object-top: 97px; --object-left: 170px;"></div>
      <!-- MAT -->
      <div class="object mat"
           style="--object-top: 175px; --object-left: 157px;"></div>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 127px; --object-left: 53px;"></div>
      <!-- DISABLED CLOSET -->
      <div class="closet closet-locked">
        <div class="closet-door closet-door-left"></div>
        <div class="closet-door closet-door-right"></div>
      </div>
      <!-- CLOSED CLOSET -->
      <input type="checkbox" id="stage_5_closet" class="closet-checkbox" />
      <label class="closet closet-close" for="stage_5_closet">
         <div class="closet-door closet-door-left"></div>
         <div class="closet-door closet-door-right"></div>
      </label>
      <!-- OPEN CLOSET -->
      <label class="closet closet-open" for="stage_5_closet">
        <div class="closet-door closet-door-left"></div>
        <div class="closet-door closet-door-right"></div>
        <!-- DOOR KEY TRIGGER -->
        <label class="object key fake-key-trigger"
               for="stage_5_fake_key"
               style="--object-top: 22px; --object-left: 26px;"></label>
      </label>
      <!-- FLOWER VASE -->
      <div class="object flower-vase"
           style="--object-top: 68px; --object-left: 114px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-right" for="stage_5_map_2"></label>
    </div>
    <!-- MAP 2 -->
    <input type="radio"
           name="stage5_radio"
           id="stage_5_map_2"
           class="map-radio"
           checked />
    <div class="map stage-5-map-2">
      <!-- DISABLED WINDOW -->
      <div class="window"
           style="--lockable-bottom: 95px; --lockable-left: 35px;">
        <!-- DOOR KEY FAKE TRIGGER -->
        <div class="object key door-key-trigger"
             style="--object-top: 64px; --object-left: 79px;"></div>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </div>
      <!-- CLOSED WINDOW -->
      <input type="checkbox"
             id="stage_5_map_2_window_curtain_key"
             class="window-checkbox" />
      <label class="window window-close"
             for="stage_5_map_2_window_curtain_key"
             style="--lockable-bottom: 95px; --lockable-left: 35px;">
        <!-- DOOR KEY FAKE TRIGGER -->
        <div class="object key door-key-trigger"
             style="--object-top: 64px; --object-left: 79px;"></div>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </label>
      <!-- OPEN WINDOW -->
      <div class="window window-open"
             style="--lockable-bottom: 95px; --lockable-left: 35px;">
        <!-- CLOSET TRIGGER -->
        <label class="object key closet-key-trigger"
               for="stage_5_map_1_closet_key"
               style="--object-top: 64px; --object-left: 79px;"></label>
        <!-- DOOR KEY TRIGGER -->
        <label class="object key door-key-trigger"
               for="stage_5_map_4_key"
               style="--object-top: 80px; --object-left: 50px;"></label>
        <!-- CONCEAL FLOOR -->
        <input type="checkbox"
               id="stage_5_map_2_conceal_tree"
               class="conceal-tree-checkbox" />
        <label class="object conceal-tree"
               for="stage_5_map_2_conceal_tree"
               style="--object-top: 80px; --object-left: 50px;"></label>
        <div class="window-curtain window-curtain-left"></div>
        <div class="window-curtain window-curtain-right"></div>
      </div>
      <!-- MAT -->
      <div class="object mat"
           style="--object-top: 166px; --object-left: 82px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 81px; --object-left: 170px;"></div>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 134px; --object-left: 77px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_5_map_1"></label>
      <label class="nav nav-right" for="stage_5_map_3"></label>
    </div>
    <!-- MAP 3 -->
    <input type="radio"
           name="stage5_radio"
           id="stage_5_map_3"
           class="map-radio" />
    <div class="map stage-5-map-3">
      <!-- BOOK SHELF -->
      <div class="object book-shelf"
           style="--object-top: 97px; --object-left: 20px;"></div>
      <!-- DESK -->
      <div class="object desk"
           style="--object-top: 115px; --object-left: 121px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 81px; --object-left: 79px;"></div>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 134px; --object-left: 93px;"></div>
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- WINDOW KEY TRIGGER -->
      <label class="object scissors window-key-trigger"
             for="stage_5_map_2_window_key"
             style="--object-top: 190px; --object-left: 30px;"></label>
      <!-- CONCEAL FLOOR -->
      <input type="checkbox"
             id="stage_5_map_3_conceal_floor"
             class="conceal-floor-checkbox" />
      <label class="object conceal-floor"
             for="stage_5_map_3_conceal_floor"
             style="--object-top: 190px; --object-left: 30px;"></label>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_5_map_2"></label>
      <label class="nav nav-right" for="stage_5_map_4"></label>
    </div>
    <!-- MAP 4 -->
    <input type="radio"
           name="stage5_radio"
           id="stage_5_map_4"
           class="map-radio" />
    <div class="map stage-5-map-4">
      <!-- WALL CLOCK -->
      <div class="object wall-clock"
           style="--object-top: 30px; --object-left: 103px;"></div>
      <!-- MAT -->
      <div class="object mat"
           style="--object-top: 170px; --object-left: 80px;"></div>
      <!-- DISABLED DOOR -->
      <div class="door-way">
        <div class="door"></div>
      </div>
      <!-- CLOSED DOOR -->
      <input type="checkbox" id="stage_5_door" class="door-way-checkbox" />
      <label class="door-way door-way-close" for="stage_5_door">
        <div class="door"></div>
      </label>
      <!-- OPEN DOOR -->
      <label class="door-way door-way-open" for="finish">
        <div class="door"></div>
      </label>
      <!-- FLOOR VASE -->
      <div class="object floor-vase"
           style="--object-top: 130px; --object-left: 55px;"></div>
      <!-- LAMP -->
      <div class="object lamp"
           style="--object-top: 100px; --object-left: 158px;"></div>
      <!-- NAVIGATION -->
      <label class="nav nav-left" for="stage_5_map_3"></label>
    </div>
    <!-- RESET -->
    <input type="reset" class="nav nav-reset" value="" />
    <!-- STAGE LABEL -->
    <div class="stage-label stage-label-5"></div>
  </form>
  <input type="radio" name="stage" id="finish" class="stage-radio" />
  <div class="stage finish" type="reset" value=""></div>
</div>

CSS Code

:root {
  --width: 240px;
  --height: 240px;
  --door-background-image: url("https://assets.codepen.io/430361/css-room-escape-door.png");
  --door-way-background-image: url("https://assets.codepen.io/430361/css-room-escape-door-way.png");
  --mat-background-image: url("https://assets.codepen.io/430361/css-room-escape-mat.png");
  --key-background-image: url("https://assets.codepen.io/430361/css-room-escape-key.png");
  --front-background-image: url("https://assets.codepen.io/430361/css-room-escape-front.png");
  --instructions-background-image: url("https://assets.codepen.io/430361/css-room-escape-instructions.png");
  --map-background-image: url("https://assets.codepen.io/430361/css-room-escape-map-background.png");
  --navigation-background-image: url("https://assets.codepen.io/430361/css-room-escape-navigation.png");
  --closet-background-image: url("https://assets.codepen.io/430361/css-room-escape-closet.png");
  --closet-door-background-image: url("https://assets.codepen.io/430361/css-room-escape-closet-door.png");
  --stage-label-background-image: url("https://assets.codepen.io/430361/css-room-escape-stage-label.png");
  --frame-background-image: url("https://assets.codepen.io/430361/css-room-escape-frame.png");
  --scissors-background-image: url("https://assets.codepen.io/430361/css-room-escape-scissors.png");
  --window-background-image: url("https://assets.codepen.io/430361/css-room-escape-window.png");
  --window-curtain-background-image: url("https://assets.codepen.io/430361/css-room-escape-window-curtain.png");
  --finish-background-image: url("https://assets.codepen.io/430361/css-room-escape-finish.png");
  --lamp-background-image: url("https://assets.codepen.io/430361/css-room-escape-lamp.png");
  --wall-clock-background-image: url("https://assets.codepen.io/430361/css-room-escape-wall-clock.png");
  --floor-vase-background-image: url("https://assets.codepen.io/430361/css-room-escape-floor-vase.png");
  --flower-vase-background-image: url("https://assets.codepen.io/430361/css-room-escape-flower-vase.png");
  --flower-vase-background-image: url("https://assets.codepen.io/430361/css-room-escape-flower-vase.png");
  --book-shelf-background-image: url("https://assets.codepen.io/430361/css-room-escape-book-shelf.png");
  --conceal-floor-background-image: url("https://assets.codepen.io/430361/css-room-escape-conceal-floor.png");
  --conceal-tree-background-image: url("https://assets.codepen.io/430361/css-room-escape-conceal-tree.png");
  --desk-background-image: url("https://assets.codepen.io/430361/css-room-escape-desk.png");
}

body {
  background-color: #202020;
  width: 100vw;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

body:after {
  /* preload assets */
  content:
    url("https://assets.codepen.io/430361/css-room-escape-door.png")
    url("https://assets.codepen.io/430361/css-room-escape-door-way.png")
    url("https://assets.codepen.io/430361/css-room-escape-mat.png")
    url("https://assets.codepen.io/430361/css-room-escape-key.png")
    url("https://assets.codepen.io/430361/css-room-escape-front.png")
    url("https://assets.codepen.io/430361/css-room-escape-instructions.png")
    url("https://assets.codepen.io/430361/css-room-escape-map-background.png")
    url("https://assets.codepen.io/430361/css-room-escape-navigation.png")
    url("https://assets.codepen.io/430361/css-room-escape-closet.png")
    url("https://assets.codepen.io/430361/css-room-escape-closet-door.png")
    url("https://assets.codepen.io/430361/css-room-escape-stage-label.png")
    url("https://assets.codepen.io/430361/css-room-escape-frame.png")
    url("https://assets.codepen.io/430361/css-room-escape-scissors.png")
    url("https://assets.codepen.io/430361/css-room-escape-window.png")
    url("https://assets.codepen.io/430361/css-room-escape-window-curtain.png")
    url("https://assets.codepen.io/430361/css-room-escape-finish.png")
    url("https://assets.codepen.io/430361/css-room-escape-lamp.png")
    url("https://assets.codepen.io/430361/css-room-escape-wall-clock.png")
    url("https://assets.codepen.io/430361/css-room-escape-floor-vase.png")
    url("https://assets.codepen.io/430361/css-room-escape-flower-vase.png")
    url("https://assets.codepen.io/430361/css-room-escape-book-shelf.png")
    url("https://assets.codepen.io/430361/css-room-escape-conceal-floor.png")
    url("https://assets.codepen.io/430361/css-room-escape-conceal-tree.png")
    url("https://assets.codepen.io/430361/css-room-escape-desk.png")
  ;
  width: 0;
  height: 0;
  position: absolute;
  overflow: hidden;
}

.container {
  width: var(--width);
  height: var(--height);
}

.stage-radio {
  display: none;
}

.stage {
  height: var(--height);
  display: none;
  flex-wrap: wrap;
  position: relative;
}

.stage-radio:checked + .stage {
  display: flex;
}

.map-radio {
  display: none;
}

.map {
  background-image: var(--map-background-image);
  width: var(--width);
  height: var(--height);
  display: none;
  position: relative;
}

.map-radio:checked + .map {
  display: block;
}

.object {
  width: var(--object-width);
  height: var(--object-height);
  background-image: var(--object-background-image);
  position: absolute;
  top: var(--object-top);
  left: calc(var(--object-left) + var(--object-move-left));
}

label.object:hover {
  background-position-x: calc(var(--object-width) * -1);
}

.stage-label {
  --stage-label-width: 62px;
  --stage-label-height: 15px;
  background-image: var(--stage-label-background-image);
  width: var(--stage-label-width);
  height: var(--stage-label-height);
  position: absolute;
  top: 10px;
  left: 10px;
}

/****************/ /******************/
/***** DOOR *****/ /***** CLOSET *****/
/****************/ /******************/

.door {
  --door-width: 42px;
  --door-height: 76px;
  background-image: var(--door-background-image);
  width: var(--door-width);
  height: var(--door-height);
  position: absolute;
  left: calc(50% - calc(var(--door-width) / 2));
  bottom: 0;
}

.closet-door {
  --door-width: 30px;
  --door-height: 49px;
  background-image: var(--closet-door-background-image);
  width: var(--door-width);
  height: var(--door-height);
  position: absolute;
  bottom: 7px;
}

.closet-door-left {
  left: 2px;
}

.closet-door-right {
  right: 2px;
  transform: scaleX(-1);
}

.window-curtain {
  --door-width: 77px;
  --door-height: 130px;
  background-image: var(--window-curtain-background-image);
  width: var(--door-width);
  height: var(--door-height);
  position: absolute;
  top: 0;
}

.window-curtain-left {
  left: 8px;
  transform-origin: top left;
}

.window-curtain-right {
  right: 8px;
  transform-origin: top right;
}

.door-way,
.closet,
.window {
  background-image: var(--lockable-background-image);
  width: var(--lockable-width);
  height: var(--lockable-height);
  position: absolute;
  left: var(--lockable-left);
  bottom: var(--lockable-bottom);
}

.door-way {
  --lockable-background-image: var(--door-way-background-image);
  --lockable-width: 50px;
  --lockable-height: 80px;
  --lockable-bottom: 80px;
  --lockable-left: calc(50% - calc(var(--lockable-width) / 2))
}

.closet {
  --lockable-background-image: var(--closet-background-image);
  --lockable-width: 63px;
  --lockable-height: 68px;
  --lockable-bottom: 60px;
  --lockable-left: calc(50% - calc(var(--lockable-width) / 2))
}

.window {
  --lockable-background-image: var(--window-background-image);
  --lockable-width: 170px;
  --lockable-height: 130px;
}

label.door-way-open:hover > .door,
label.closet-open:hover > .closet-door,
label.window-open:hover > .window-curtain {
  background-position-x: calc(var(--door-width) * -1);
}

label.door-way:hover,
label.closet:hover,
label.window:hover {
  background-position-x: calc(var(--lockable-width) * -1);
}

.door-way-open,
.closet-open,
.window-open {
  display: none;
}

.door-way-open > .door {
  transform-origin: top left;
  animation: door-way-open 125ms ease-out forwards;
}

@keyframes door-way-open {
  100% {
    transform: rotateY(45deg) skewY(25deg);
  }
}

.closet-open > .closet-door-left {
  transform-origin: top left;
  animation: closet-open-left 125ms ease-out forwards;
}

@keyframes closet-open-left {
  100% {
    transform: rotateY(135deg) skewY(25deg);
  }
}

.closet-open > .closet-door-right {
  transform-origin: top left;
  animation: closet-open-right 125ms ease-out forwards;
}

@keyframes closet-open-right {
  100% {
    transform: scaleX(-1) translateX(-100%) rotateY(135deg) skewY(25deg);
  }
}

.window-open > .window-curtain {
  animation: window-curtain-open 125ms ease-out forwards;
}

@keyframes window-curtain-open {
  100% {
    transform: scaleX(0.4);
  }
}

.door-way-checkbox,
.closet-checkbox,
.window-checkbox {
  display: none;
}

.door-way-checkbox:checked ~ .door-way-close,
.door-key:checked ~ .map .door-way-checkbox:checked ~ .door-way-close,
.closet-checkbox:checked ~ .closet-close,
.closet-key:checked ~ .map .closet-checkbox:checked ~ .closet-close,
.window-checkbox:checked ~ .window-close,
.window-key:checked ~ .map .window-checkbox:checked ~ .window-close {
  display: none;
}

.door-way-checkbox:checked ~ .door-way-open,
.door-key:checked ~ .map .door-way-checkbox:checked ~ .door-way-open,
.closet-checkbox:checked ~ .closet-open,
.closet-key:checked ~ .map .closet-checkbox:checked ~ .closet-open,
.window-checkbox:checked ~ .window-open,
.window-key:checked ~ .map .window-checkbox:checked ~ .window-open {
  display: block;
}

.door-key:not(:checked) ~ .map label.door-way,
.closet-key:not(:checked) ~ .map label.closet,
.window-key:not(:checked) ~ .map label.window {
  display: none;
}

.door-key:checked ~ .map div.door-way,
.closet-key:checked ~ .map div.closet,
.window-key:checked ~ .map div.window {
  display: none;
}

/***************/
/***** MAT *****/
/***************/

.mat-checkbox {
  display: none;
}

.mat {
  --object-background-image: var(--mat-background-image);
  --object-width: 80px;
  --object-height: 40px;
  --object-move-left: 0px;
  transition: left 125ms ease-out;
}

.mat-checkbox:checked + .mat {
  --object-move-left: 50px;
}

/***************/ /********************/
/***** KEY *****/ /***** SCISSORS *****/
/***************/ /********************/

.key-checkbox {
  display: none;
}

.key {
  --object-background-image: var(--key-background-image);
  --object-width: 12px;
  --object-height: 32px;
  --object-move-left: 0px;
  transition: transform 125ms ease-out;
}

.scissors {
  --object-background-image: var(--scissors-background-image);
  --object-width: 21px;
  --object-height: 30px;
  --object-move-left: 0px;
  transition: transform 125ms ease-out;
}

.door-key:checked ~ .map .door-key-trigger,
.closet-key:checked ~ .map .closet-key-trigger,
.window-key:checked ~ .map .window-key-trigger,
.fake-key:checked ~ .map .fake-key-trigger {
  transform: scale(0);
}

/*****************/
/***** FRAME *****/
/*****************/

.frame-checkbox {
  display: none;
}

.frame {
  --object-background-image: var(--frame-background-image);
  --object-width: 60px;
  --object-height: 55px;
  --object-move-left: 0px;
  transition: transform 125ms ease-out;
  transform-origin: 30px 2px;
}

.frame-checkbox:checked + .frame {
  transform: rotate(60deg);
}

/****************/
/***** LAMP *****/
/****************/

.lamp {
  --object-background-image: var(--lamp-background-image);
  --object-width: 31px;
  --object-height: 90px;
  --object-move-left: 0px;
}

/**********************/
/***** WALL CLOCK *****/
/**********************/

.wall-clock {
  --object-background-image: var(--wall-clock-background-image);
  --object-width: 35px;
  --object-height: 35px;
  --object-move-left: 0px;
}

/**********************/
/***** FLOOR VASE *****/
/**********************/

.floor-vase {
  --object-background-image: var(--floor-vase-background-image);
  --object-width: 24px;
  --object-height: 50px;
  --object-move-left: 0px;
}

/***********************/
/***** FLOWER VASE *****/
/***********************/

.flower-vase {
  --object-background-image: var(--flower-vase-background-image);
  --object-width: 12px;
  --object-height: 50px;
  --object-move-left: 0px;
}

/***********************/
/***** FLOWER VASE *****/
/***********************/

.book-shelf {
  --object-background-image: var(--book-shelf-background-image);
  --object-width: 55px;
  --object-height: 75px;
  --object-move-left: 0px;
}

/*************************/
/***** CONCEAL FLOOR *****/
/*************************/

.conceal-floor {
  --object-background-image: var(--conceal-floor-background-image);
  --object-width: 21px;
  --object-height: 30px;
  --object-move-left: 0px;
  transition: left 125ms ease-out;
}

.conceal-floor-checkbox:checked + .conceal-floor {
  --object-move-left: 21px;
}

.conceal-floor-checkbox {
  display: none;
}

/************************/
/***** CONCEAL TREE *****/
/************************/

.conceal-tree {
  --object-background-image: var(--conceal-tree-background-image);
  --object-width: 12px;
  --object-height: 32px;
  --object-move-left: 0px;
  transition: left 125ms ease-out;
}

.conceal-tree-checkbox:checked + .conceal-tree {
  --object-move-left: 21px;
}

.conceal-tree-checkbox {
  display: none;
}

/****************/
/***** DESK *****/
/****************/

.desk {
  --object-background-image: var(--desk-background-image);
  --object-width: 71px;
  --object-height: 67px;
  --object-move-left: 0px;
}

/***********************/
/***** NAVIGATION *****/
/***********************/
.nav {
  --navigation-width: 29px;
  --navigation-height: 29px;
  --navigation-spacing: 5px;
  background-image: var(--navigation-background-image);
  width: var(--navigation-width);
  height: var(--navigation-height);
  position: absolute;
  top: calc(50% - calc(var(--navigation-height) / 2));
}

.nav-left {
  left: var(--navigation-spacing);
}

.nav-right {
  background-position-y: calc(var(--navigation-height) * -1);
  right: var(--navigation-spacing);
}

.nav-reset {
  background-color: transparent;
  background-position-y: calc(var(--navigation-height) * -2);
  padding: 0;
  border: 0;
  margin: 0;
  outline: 0;
  top: var(--navigation-spacing);
  right: var(--navigation-spacing);
}

.nav-left:hover,
.nav-right:hover,
.nav-reset:hover {
  background-position-x: calc(var(--navigation-width) * -1);
}

/***********************/
/***** STAGE IMAGE *****/
/***********************/

.front {
  background-image: var(--front-background-image);
}

.instructions {
  background-image: var(--instructions-background-image);
}

.finish {
  background-image: var(--finish-background-image);
}

/* STAGE 1 */

.stage-1-map-1 {
  background-position-x: 0px;
}

/* STAGE 2 */

.stage-label-2 {
  background-position-y: calc(var(--stage-label-height) * -1);
}

.stage-2-map-1 {
  background-position-x: 0px;
}

/* STAGE 3 */

.stage-label-3 {
  background-position-y: calc(var(--stage-label-height) * -2);
}

.stage-3-map-1 {
  background-position-x: calc(var(--width) * -1);
}

.stage-3-map-2 {
  background-position-x: calc(var(--width) * -3);
}

/* STAGE 4 */

.stage-label-4 {
  background-position-y: calc(var(--stage-label-height) * -3);
}

.stage-4-map-1 {
  background-position-x: calc(var(--width) * -1);
}

.stage-4-map-2 {
  background-position-x: calc(var(--width) * -2);
}

.stage-4-map-3 {
  background-position-x: calc(var(--width) * -3);
}

/* STAGE 5 */

.stage-label-5 {
  background-position-y: calc(var(--stage-label-height) * -4);
}

.stage-5-map-1 {
  background-position-x: calc(var(--width) * -1);
}

.stage-5-map-2 {
  background-position-x: calc(var(--width) * -2);
}

.stage-5-map-3 {
  background-position-x: calc(var(--width) * -3);
}

.stage-5-map-4 {
  background-position-x: calc(var(--width) * -0);
}

Source at CodePen.io

Tags