Search code examples
javascriptjqueryhtmlcssflip

Arrange DIVs adjacent to each other and flip each of them with CSS


Please see the image below.

enter image description here

Hovering over a DIV should flip it, revealing different content (the 'back' of the 'card'.)

With the relevant code below, I've managed to

  • get the arrangement shown by the coloured DIVs, but not adjacent to each other, like the whites.
  • get the flip animation from the beginning of each DIV, while should be from the center of each DIV.

For the flip animation, I used this resource. For the DIV placement, I used, among others, this SO post.

Relevant HTML

<html>
    <head>
      <title>My Website</title>
      <script src="my.js"></script>
      <script src="jq_js/jquery-3.1.1.min.js"></script>
      <link rel="stylesheet" type="text/css" href="bs/bootstrap.min.css">
      <link rel="stylesheet" type="text/css" href="css/my.css">
      <link href='//fonts.googleapis.com/css?family=Lobster' rel='stylesheet'>
      <link href='//fonts.googleapis.com/css?family=Lobster Two' rel='stylesheet'>
      <script src="bs/js/bootstrap.min.js"></script>
    </head>
    <body onload = "javascript: isLoggedIn();">
      <div class="container">
        :
        :
        :
        :
        <div  id="results">
        </div>
      </div>
    </body>
</html>

Relevant CSS

/* Dealet Card */
.dealet-container
{
  /*display: inline-flex; */
  perspective: 1000px;  
}

.dealet-container, .front, .back
{
  width: 200px;
  height: 170px;
}

.dealet 
{
    /*width: 18%;*/
    margin-left: 14px;
    float: left;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    box-sizing: border-box;
    display: table-cell;
    flex-flow: row wrap;
    transition: 0.9s;
}

.dealet:hover 
{
  background-color: lightblue;
  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
/*  transform: rotateY(180deg);
*/}

.dealet-container:hover .flipper, .dealet-container.hover .flipper 
{
  transform: rotateY(180deg);
}

.flipper
{
  transition: 0.9s;
  transform-style: preserve-3d;
  position: relative;
}

.front
{
  z-index: 2;
  transform:rotateY(0deg);
}

.back
{
  transform:rotateY(180deg);
}

.front, .back
{
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;  
}

.dealet_box 
{
  padding: 6px 6px;
}

.dealet_img
{
  width: 100%;
}

.dealet_logo
{
  width: 60%;
}

.dTop
{
  font-family: 'Lobster';
  font-size: 16px; 
}

.dBot
{
  font-family: 'Lobster Two';
  font-size: 14px;
}

Relevant JavaScript / JQuery

function drawCard(myArray)
{
  var resultsDiv = document.getElementById('results');
  resultsDiv.innerHTML = "";

  var html = [""];

  $.each(myArray, function(cardNum, value)
  {
    dealet = myArray[cardNum].dealet;
    dealetID = "dealet" + cardNum;
    dTopID = "dTop" + cardNum;
    dBotID = "dBot" + cardNum;

    logo = myArray[cardNum].logo;
    addr = myArray[cardNum].address;
    mob = myArray[cardNum].mobile;

    // Card front
    htmlFString = [  '<div class="dealet-container">',
              '<div class="flipper">',
              '<div class="dealet front" id=f' + cardNum + '>',
                      '<img id="' + dealetID + '" src="' + dealet +  '" class="dealet_img">',
                      '<div class="dealet_box">',
                        '<span class="dTop" id="' + dTopID + '">' + myArray[cardNum].name_top + '</span><br>',
                        '<span class="dBot" id="' + dBotID + '">' + myArray[cardNum].name_bottom + '</span>',
                      '</div>',
                      '</div>'
                     ].join('');
    // Card back                     
    htmlBString = [ '<div class="dealet back" id=b' + cardNum + '>',
                      '<img src="' + logo +  '" class="dealet_logo" align="center">',
                      '<div class="dealet_box">',
                        '<span>' + addr + '</span><br>',
                        '<span>' + mob + '</span>',
                      '</div>',
                      '</div>',
                      '</div>',
                      '</div>'
                     ].join('');
    html += htmlFString;
    html += htmlBString;
  });

  resultsDiv.innerHTML = html;

} // of drawCard()

Greatly appreciate if someone can look in and help complete what I've set out to. Been stuck for sometime now. Many thanks in advance!


Solution

  • Phew! Got the desired result finally.

    To place DIVs adjacent to each other, this is the style that worked. The display and flex-flow elements clinched it.

    /* Dealet Card */
    .dealet-container
    {
      display: inline-table; 
      perspective: 1000px;  
    }
    
    .dealet 
    {
        margin: 14px;
        float: left;
        box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
        box-sizing: border-box;
        display: table-cell;
        flex-flow: row wrap;
        transition: 0.6s;
    }
    

    For the flip animation, the z-index for the 'back' of the 'card' was the clincher. This is what worked (Ref: CSS Layout: The Position Property):

    .back
    {
      transform:rotateY(180deg);
      position: absolute;
      z-index: -1;
    }
    

    Hope this is of help to someone. Thanks to all who looked in!