Flip Cards o Tarjetas Giratorias con CSS3

Un efecto cada vez más usado el de las “Flip Cards”, muy vistoso y con muchas posibilidades, para muestra este pen de Virgil Pana, donde exprime esas posibilidades al máximo.

Nosotros vamos a ver algo más simple y no usaremos Javascript para hacer los efectos de giro, solo usaremos transiciones de CSS3.

Ver Demo

HTML

La estructura HTML de las tarjetas es muy simple, para crearla solo usaremos elementos div anidados:

1. Creamos un contenedor para meter las cajas donde irán las tarjetas, de esta forma las separamos del resto de contenido de la página. Le ponemos la clase .boxesContainer.

2. Dentro irán todas las cajas que queramos, una por cada tarjeta, y a cada una de ellas le ponemos la clase .cardBox.

  • La razón de meter cada tarjeta dentro de una caja es para poder hacer :hover sobre la caja y no sobre la tarjeta directamente, ya que si lo hacemos sobre la tarjeta esta reduce su ancho al girar y el efecto :hover deja de ejecutarse sobre ella, resultando un bloqueo “palante-patrás” que no mola nada, como en esta imagen de la derecha:

3. Ahora dentro de cada caja ponemos un elemento que será la tarjeta, yo las he nombrado con la clase .card.

4. Dentro de cada tarjeta y a la misma altura o nivel ponemos dos elementos más que serán las dos caras de la tarjeta; .front y .back, esta última (luego veremos como) la giraremos 180 grados en su eje Y para que haga las veces de «cara trasera» de la tarjeta.

5. Finalmente dentro de cada cara (dentro de los elementos front y back) pondremos el contenido que queramos, encabezados, parrafos, imágenes, etc… eso será cosa vuestra. Para este artículo pondremos un contenido muy básico.

El código para una tarjeta queda tal que así:

<div class="boxesContainer">
 
  <div class="cardBox">
    <div class="card">
      <div class="front">
        <!-- contenido front -->
      </div>
      <div class="back">
        <!-- contenido back -->
      </div>
    </div>
  </div>
 
</div>

Y para cuatro tarjetas con algo de contenido básico quedaría de la siguiente manera:

<div class="boxesContainer">
 
  <div class="cardBox">
    <div class="card">
      <div class="front">
        <h3>Card One</h3>
        <p>Hover to flip</p>
        <strong>&#x21bb;</strong>
      </div>
      <div class="back">
        <h3>Back Side One</h3>
        <p>Content in card one</p>
        <a href="#">Button 1</a>
      </div>
    </div>
  </div>
 
  <div class="cardBox">
    <div class="card">
      <div class="front">
        <h3>Card Two</h3>
        <p>Hover to flip</p>
        <strong>&#x21bb;</strong>
      </div>
      <div class="back">
        <h3>Back Side Two</h3>
        <p>Content in card two</p>
        <a href="#">Button 2</a>
      </div>
    </div>
  </div>
 
  <div class="cardBox">
    <div class="card">
      <div class="front">
        <h3>Card Three</h3>
        <p>Hover to flip</p>
        <strong>&#x21bb;</strong>
      </div>
      <div class="back">
        <h3>Back Side Three</h3>
        <p>Content in card three</p>
        <a href="#">Button 3</a>
      </div>
    </div>
  </div>
 
  <div class="cardBox">
    <div class="card">
      <div class="front">
        <h3>Card Four</h3>
        <p>Hover to flip</p>
        <strong>&#x21bb;</strong>
      </div>
      <div class="back">
        <h3>Back Side Four</h3>
        <p>Content in card four</p>
        <a href="#">Button 4</a>
      </div>
    </div>
  </div>
 
</div>

CSS

El giro de la tarjeta lo haremos con CSS y más concretamente con algunas propiedades de CSS3.

Empezamos con las cajas contenedoras de las tarjetas: .cardBox.
Con la propiedad float y el valor left colocamos las tarjetas en línea. La propiedad perspective ajusta el punto de vista desde donde se ve un elemento, podemos omitir esta propiedad pero el efecto no será tridimensional. Como vamos a poner cuatro tarjetas en línea jugamos con el width y el margin para que todo cuadre al 100% sin pasarnos. También podemos suavizar el giro añadiendo la propiedad transition.

.cardBox {
  float: left;
  font-size: 1.2em;
  margin: 1% 0 0 1%;
  perspective: 800px;
  transition: all 0.3s ease 0s;
  width: 23.7%;
}

Aquí está la primera parte del truco:
Al hacer :hover sobre el elemento .cardBox giramos el elemento .card que está dentro de cardBox, lo giramos 180 grados sobre el eje Y, esto lo hacemos con la propiedad transform y pasándole como valor el método rotateY(), entre los paréntesis hay que poner el numero de grados que queremos que gire.

.cardBox:hover .card {
  transform: rotateY(180deg);
}

Vamos ya con la tarjeta .card.
Este elemento contiene nuestras dos caras de la tarjeta (front y back). Lo necesario aquí es la propiedad transform-style que deja que los elementos hijos transformados conserven las transformaciones 3D. Le añadimos el valor preserve-3d que especifica que los elementos hijos conserven su posición 3D. También es importante poner la propiedad width al 100% para abarcar el ancho total de la tarjeta y height para marcar la altura fija que va a tener. Esto de la altura fija a priori es una pega que nos limita bastante, aunque podemos cambiar esa altura para las diferentes medidas de dispositivos (movil, tablet, escritorio), lo ideal sería que esa altura fuera también proporcional (he hecho algunas pruebas y lo tengo casi apunto, pronto lo veremos por el blog). Por último la propiedad animation que es opcional, y que usaremos más adelante para crear una animación inicial. A esa animación le ponemos un nombre: giro, un tiempo de duración en segundos: 1s, y un número de iteraciones: 1, que nos indica las veces que se va repetir la animación.

.card {
  background: #222;
  cursor: default;
  height: 300px;
  transform-style: preserve-3d;
  transition: transform 0.4s ease 0s;
  width: 100%;
  -webkit-animation: giro 1s 1;
  animation: giro 1s 1;
}

Llegamos a las dos cara de la tarjeta .front y .back.
Así de primeras como las queremos iguales aplicamos los mismos estilos a las dos juntas. Principalmente lo que no debemos olvidar es la propiedad backface-visibility que con el valor hidden oculta la parte trasera de un elemento previamente girado. Aquí también es importante poner la propiedad height al 100% para abarcar el alto total de la tarjeta.

.front, .back {
  backface-visibility: hidden;
  box-sizing: border-box;
  color: white;
  display: block;
  font-size: 1.2em;
  height: 100%;
  padding: 0.8em;
  position: absolute;
  text-align: center;
  width: 100%;
}

Y la segunda parte del truco:
Giramos previamente el elemento .back, que es la cara trasera de la tarjeta, para que inicialmente se encuentre volteada detrás de la cara delantera.

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

Añadimos unos estilos básicos para el contenido de la tarjeta, como títulos, párrafos, enlaces… Esto será cosa vuestra dependiendo del contenido que queráis incluir, yo pondré estos:

h1 {
  background: #333;
  color: #fff;
  text-align: center;
  margin: 0 0 5% 0;
  padding: 0.5em;
  margin: 0 0 5% 0;
}
 
p {
  margin-bottom: 1.8em;
}
 
strong {
  background: #fff;
  border-radius: 100%;
  color: #222;
  font-size: 1.5em;
  line-height: 30px;
  padding: 0 7px 4px 6px;
}
 
a {
  padding: 0.3em 0.5em;
  background: #333;
  color: #fff;
  text-decoration: none;
  border-radius: 1px;
  font-size: 0.9em;
  transition: all 0.2s ease 0s;
}
 
a:hover {
  background: #fff;
  color: #333;
  text-shadow: 0 0 1px #333;
}

Podemos añadir unos colores personalizados para cada tarjeta:

.cardBox:nth-child(1) .card .back {
  background: cornflowerblue;
}
 
.cardBox:nth-child(2) .card .back {
  background: orange;
}
 
.cardBox:nth-child(3) .card .back {
  background: yellowgreen;
}
 
.cardBox:nth-child(4) .card .back {
  background: tomato;
}

También podemos añadir la animación inicial que comentábamos antes. Lo que hacemos es girar las tarjetas todas a la vez pero cada una medio segundo más tarde que la anterior. Como a la primera tarjeta ya le pusimos que tardaba tardaba 1 segundo en girar, la segunda tardará 1,5 segundos, la tercera 2 segundos y la cuarta 2,5 segundos.

.cardBox:nth-child(2) .card {
  -webkit-animation: giro 1.5s 1;
  animation: giro 1.5s 1;
}
 
.cardBox:nth-child(3) .card {
  -webkit-animation: giro 2s 1;
  animation: giro 2s 1;
}
 
.cardBox:nth-child(4) .card {
  -webkit-animation: giro 2.5s 1;
  animation: giro 2.5s 1;
}

Y con con la regla @keyframes y nombrando a nuestra animación por el nombre que previamente la dimos (giro) hacemos que inicialmente se reproduzca la animación:

@keyframes giro {
  from {
    transform: rotateY( 180deg);
  }
  to {
    transform: rotateY( 0deg);
  }
}

@-webkit-keyframes giro {
  from {
    transform: rotateY( 180deg);
  }
  to {
    transform: rotateY( 0deg);
  }
}

Para ajustar el diseño responsive añadimos unas @media queries de CSS3.

@media screen and (max-width: 767px) {
  
  .cardBox {
    margin-left: 2.8%;
    margin-top: 3%;
    width: 46%;
  }

  .card {
    height: 285px;
  }

  .cardBox:last-child {
    margin-bottom: 3%;
  }

}


@media screen and (max-width: 480px) {

  .cardBox {
    width: 94.5%;
    height: 290px;
  }

}

Y eso es todo… en teoría ya tenemos nuestras tarjetas giratorias o Flip Cards solo con CSS.

Demo

Aquí está la demo en la que, por exigencias del ancho del blog, solo funcionan dos media queries… y no es posible ver las cuatro tarjetas en línea… Pero en Codepen podéis ver la demo a tamaño completo.

Ver Flip Cards Responsive de Josetxu (@josetxu) en CodePen.

En próximos artículos veremos estas mismas tarjetas pero proporcionales, al redimensionar la pantalla cambiarán su anchura y también su altura proporcionalmente.

Datos de CANIUSE.COM