Search code examples
htmlcssgridtouch

Issues with flipping grid titles and what to do when it comes to touch devices


I have created a grid that flips and on each side will be a different picture, with a title. How can I overcome the issues I will face when it comes to viewing this on a touch device?

Also, I am having troubles getting the writing to not be in reverse when the square is flipped. If someone can help with that too that would be great.

Thanks for any help in advance!

.grid{
  width:calc(95vw + 10px);
  display:inline-block;
  position:relative;
  background-color:transparent;
  perspective:1000px;
  padding-left: 35px;
  padding-top: 10px;
    
}
.griditem{
  display:block;
  width:15vw;
  margin:5px;
  height:15vw;
  float:left;
}
.front{
  width:100%;
  height:100%;
  background: url('https://static.pexels.com/photos/279315/pexels-photo-279315.jpeg') no-repeat;
  background-attachment:fixed;
  background-position: center;
  background-size:cover;
  transform:rotateY(0deg);
  transition:.4s ease-in-out;
  cursor:pointer;
}
.back{
  width:100%;
  height:100%;
  transform:rotateY(180deg);
  background:#fff url('http://www.dentoncorkermarshall.com/wp-content/uploads/2013/12/Asia-Square-06.jpg?x92178') no-repeat;
  background-size:cover;
  backface-visibility:hidden;
  transition:.4s ease-in-out;
  position:absolute;
  top:0;
  z-index:2;
  font-family: montserrat;
}
.griditem:hover .front{
  transform:rotateY(180deg);
  transition:.4s ease-in-out;
}
.griditem:hover .back{
  transform:rotateY(0deg);
  transition:.4s ease-in-out;
}
      <div class="grid">
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back">olleh</div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
  <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
    <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
        <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
       <div class="griditem">
    <div class="front">
      <div class="back"></div>
    </div>
  </div>
</div>


Solution

  • Try accomplishing this with jQuery. This will work the same on desktop, but should allow the user to tap/click to rotate images on mobile/tablet devices.

    if (matchMedia) { // media query event handler
      var mq = window.matchMedia("(max-width: 768px)"); // whatever your definition of mobile/tablet is
      mq.addListener(WidthChange);
      WidthChange(mq);
    }
    
    function WidthChange(mq) { // media query change
    
      var $gridItem = $('.griditem');
    
      if (mq.matches) { // if screen is bigger than 768px (iPad)
        $gridItem.mouseenter(function() { // user hovers on gridItem
          $(this).addClass('is-flipped'); // add mod class
        });
        $gridItem.mouseleave(function() { // user stops hovering
          $(this).removeClass('is-flipped'); // remove mod class
        });
      } else { // device bigger than iPad
        $gridItem.click(function() { // user clicks/taps gridItem
          $(this).toggleClass('is-flipped'); // toggle mod class
        });
      }
    }
    * {
      font-family: sans-serif;
    }
    
    .grid {
      width: calc(95vw + 10px);
      display: inline-block;
      position: relative;
      background-color: transparent;
      perspective: 1000px;
      padding-left: 35px;
      padding-top: 10px;
    }
    
    .grid h1 {
      position: absolute;
      top: 5%;
      left: 5%;
      color: white;
      z-index: 2;
      font-size: 4.2em;
      pointer-events: none;
    }
    
    .griditem {
      display: block;
      width: 15vw;
      margin: 5px;
      height: 15vw;
      float: left;
      position: relative;
    }
    
    .front,
    .back {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      transition: 0.4s ease-in-out;
    }
    
    .front {
      z-index: 1;
      background: url('https://static.pexels.com/photos/279315/pexels-photo-279315.jpeg') no-repeat;
      background-attachment: fixed;
      background-position: center;
      background-size: cover;
      cursor: pointer;
    }
    
    .back {
      transform: rotateY(-180deg);
      /* Negative value to make it spin the right way */
      background: #fff url('http://www.dentoncorkermarshall.com/wp-content/uploads/2013/12/Asia-Square-06.jpg?x92178') no-repeat;
      background-size: cover;
      backface-visibility: hidden;
      transition: .4s ease-in-out;
      z-index: 0;
      /* position behind .front */
      font-family: montserrat;
      text-align: center;
    }
    
    .griditem.is-flipped .front {
      transform: rotateY(180deg);
    }
    
    .griditem.is-flipped .back {
      transform: rotateY(0deg);
      z-index: 2;
      /* Position in front of .front */
    }
    
    .back span {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: #fff;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <div class="grid">
    <h1>Title goes here</h1>
      <div class="griditem">
        <div class="front">
        </div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
      <div class="griditem">
        <div class="front"></div>
        <div class="back">
          <span>Hello</span>
        </div>
      </div>
    </div>

    The reason that .back is showing up with flipped text is because you have it a a child of .front instead of as a child of .griditem. So when we flip .front around 180deg, then .back is getting flipped again.