Llegó el día. Por fin te aburriste de los largos textos en desplazamiento y quieres un formato nuevo. Algo elegante. Algo compacto. Algo que tome el desplazamiento largo, lo corte en rectángulos pequeños y los una. A esta invención la llamo “libro”.
Con el poder de las regiones de CSS (CanIUse, ve a chrome://flags
y habilita las regiones de CSS) y las transformaciones 3D de CSS, la tecnología de libros de vanguardia finalmente está disponible en navegadores modernos. Solo necesitas unas pocas líneas de JavaScript y mucho CSS.
Comencemos por definir la estructura de nuestro libro. El libro consta de páginas y las páginas constan de dos lados. Los lados contienen el contenido del libro:
<div class="book">
<div> <!-- first page -->
<div> <!-- front cover -->
# My Fancy Book
</div>
<div> <!-- backside of cover -->
# By Me I. Myself
## 2012 Bogus HTML Publishing Ltd
</div>
</div>
<!-- content pages -->
<div>
<!-- front side of page -->
<div class="book-pages"></div>
<!-- back side of page -->
<div class="book-pages"></div>
</div>
<div>
<div class="book-pages"></div>
<div class="book-pages"></div>
</div>
<div>
<div class="book-pages"></div>
<div class="book-pages"></div>
</div>
</div>
Usaremos regiones de CSS para que el texto del libro fluya en las páginas del libro. Pero primero necesitamos el texto del libro.
<span id="book-content">
blah blah blah ...
</span>
Ahora que escribimos nuestro libro, definamos el CSS del flujo. Estoy usando el carácter + como marcador de posición de prefijo de proveedor. Reemplázalo por -webkit-
para navegadores WebKit, -moz-
para Firefox, etcétera:
#book-content {
+flow-into: book-text-flow;
}
.book-pages {
+flow-from: book-text-flow;
}
Ahora, el contenido del intervalo #book-content irá a los divs .book-pages. Sin embargo, es un libro bastante malo. Para un libro más literario, debemos embarcarnos en una búsqueda. Nuestro viaje nos llevará por el puente arcoíris de las transformaciones de CSS al reino de relojería de JavaScript. En los salones de los señores de las hadas mecanistas, desataremos magias de transición épicas y obtendremos las tres llaves legendarias que controlan la interfaz del mundo superior.
El guardián del puente arcoíris nos imparte la sabiduría de los selectores estructurales elegantes para que podamos convertir nuestra estructura de libro HTML en una forma más parecida a un libro:
html {
width: 100%;
height: 100%;
}
body {
/* The entire body is clickable area. Let the visitor know that. */
cursor: pointer;
width: 100%;
height: 100%;
/* Set the perspective transform for the page so that our book looks 3D. */
+perspective: 800px;
/* Use 3D for body, the book itself and the page containers. */
+transform-style: preserve-3d;
}
.book {
+transform-style: preserve-3d;
position: absolute;
}
/* Page containers, contain the two sides of the page as children. */
.book > div {
+transform-style: preserve-3d;
position: absolute;
}
/* Both sides of a page. These are flat inside the page container, so no preserve-3d. */
.book > div > div {
/* Fake some lighting with a gradient. */
background: +linear-gradient(-45deg, #ffffff 0%, #e5e5e5 100%);
width: 600px;
height: 400px;
overflow: hidden;
/* Pad the page text a bit. */
padding: 30px;
padding-bottom: 80px;
}
/* Front of a page */
.book > div > div:first-child {
/* The front side of a page should be slightly above the back of the page. */
+transform: translate3d(0px, 0px, 0.02px);
/* Add some extra padding for the gutter. */
padding-left: 40px;
/* Stylish border in the gutter for visual effect. */
border-left: 2px solid #000;
}
/* Back of a page */
.book > div > div:last-child {
/* The back side of a page is flipped. */
+transform: rotateY(180deg);
padding-right: 40px;
border-right: 2px solid #000;
}
/* Front cover of the book */
.book > div:first-child > div:first-child {
/* The covers have a different color. */
background: +linear-gradient(-45deg, #8c9ccc 0%, #080f40 100%);
/* Put a border around the cover to make it cover the pages. */
border: 2px solid #000;
/* And center the cover. */
margin-left: -1px;
margin-top: -1px;
}
/* Back cover of the book */
.book > div:last-child > div:last-child {
background: +linear-gradient(-45deg, #8c9ccc 0%, #080f40 100%);
border: 2px solid #000;
margin-left: -1px;
margin-top: -1px;
}
De esta manera, creamos un estilo algo en forma de papel para nuestro HTML y llegamos a las puertas de trillones de engranajes del reino de JavaScript. Para pasar por la puerta, debemos convertir nuestro libro plano en un volumen adecuado. Para agregar volumen al libro, desplazamos cada página ligeramente en el eje Z.
(function() {
var books = document.querySelectorAll('.book');
for (var i = 0; i < books.length; i++) {
var book = books[i];
var pages = book.childNodes;
for (var j = 0; j < pages.length; j++) {
if (pages[j].tagName == "DIV") {
setTransform(pages[j], 'translate3d(0px, 0px, ' + (-j) + 'px)');
}
}
}
})();
Lanzar magia de transición para impresionar a los señores de las hadas no es la invocación más difícil. Sin embargo, los resultados hacen que las páginas de nuestro libro animen su giro de forma fluida.
.book > div {
+transition: 1s ease-in-out;
}
Por último, para que las páginas realmente giren, debemos vincular los eventos a nuestra causa.
(function(){
// Get all the pages.
var pages = document.querySelectorAll('.book > div');
var currentPage = 0;
// Go to previous page when clicking on left side of window.
// Go to the next page when clicking on the right side.
window.onclick = function(ev) {
if (ev.clientX < window.innerWidth/2) {
previousPage();
} else {
nextPage();
}
ev.preventDefault();
};
var previousPage = function() {
if (currentPage > 0) {
currentPage--;
// Rotate the page to closed position and move it to its place in the closed page stack.
setTransform(pages[currentPage], 'translate3d(0px,0px,' + (-currentPage) + 'px) rotateY(0deg)');
}
};
var nextPage = function() {
if (currentPage < pages.length) {
// Rotate the page to open position and move it to its place in the opened stack.
setTransform(pages[currentPage], 'translate3d(0px,0px,' + currentPage + 'px) rotateY(-150deg)');
currentPage++;
}
};
})();
Con eso, adquirimos la tecnología del “libro” y podemos evacuar las torres de cristal del mundo superior y dejar atrás su deslumbrante brillo y los feroces incendios nucleares de Achenar, la gran estrella azul del nexo del mundo superior. Regresamos a nuestras casas en triunfo, agitando nuestros libros sobre nuestras cabezas, listos para la inevitable cascada de desfiles y celebraciones en nuestro honor.
Puedes ver un ejemplo en línea aquí y obtener el código fuente completo de los ejemplos. Si no tienes regiones de CSS en tu navegador, el ejemplo se verá bastante desconectado. En ese caso, puedes probar este ejemplo.