Advertisement
  1. Web Design
  2. JavaScript

Cómo Crear Diapositivas de Presentación con HTML y CSS

Scroll to top
Read Time: 17 min

() translation by (you can also view the original English article)

A medida que examinaba las distintas piezas de software diseñadas para crear presentaciones de diapositivas, se me ocurrió: ¿por qué aprender otro programa, cuando puedo usar las herramientas que ya conozco? Con unos pocos arreglos, podemos crear fácilmente presentaciones hermosas con HTML y CSS. ¡Hoy le mostraré cómo!

0 - Estructura de Directorio

Antes de comenzar, vamos a crear nuestra estructura de carpetas; debería ser bastante simple. Necesitaremos:

  • index.html
  • css/style.css
  • js/script.js
  • img/
  • slides/

Una simple plantilla de base. El directorio slides/ pueden permanecer en blanco por el momento. Lo llenaremos en breve.


1 - Comenzando son el Marcado

Comencemos creando el marcado base para nuestra página de presentación. Pegue el siguiente fragmento en su archivo index.html.

1
2
<!DOCTYPE HTML>
3
<html>
4
<head>
5
   <meta charset="utf-8">
6
   <link href="style.css" rel="stylesheet" />
7
   <title>My Great Presentation</title>
8
</head>
9
10
<body>
11
12
 <div class="wrap">
13
   <div id="slides">
14
      <!-- load in slides -->
15
   </div>
16
 </div>  
17
18
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
19
</body>
20
21
</html>

Arriba tenemos algo de buen HTML5 limpio. No más atributos type en nuestros elementos script y link, DOCTYPE corto, una etiqueta meta charset muy graciosa por su sencillez, etc.


2 - Diapositivas

El método load()  es un método AJAX que carga datos desde su servidor e inserta el HTML devuelto en el elemento seleccionado.

Ahora usted puede ser que se esté preguntando cómo vamos a tratar a cada diapositiva. Tenemos un par de opciones aquí. Si bien podríamos envolver cada diapositiva en su propio div, y colocar un bloque masivo de HTML dentro del contenedor #slides, mi instinto es que esto hará que el proceso de edición de diapositivas individuales consuma más tiempo, ya que entonces tenemos que buscar a través de todo ese marcado para encontrar la diapositiva que necesitamos.

En su lugar, para este tutorial, he optado por colocar cada diapositiva dentro de su propio archivo .html. Podemos utilizar el método load() de jQuery para incluir cada diapositiva y anexarlas a nuestro contenedor.

Cree un puñado de archivos HTML numerados y colóquelos en el directorio de slides/, así:

  • slides/
    • 0.html
    • 1.html
    • 2.html
    • 3.html
    • 4.html

Dentro de cada uno de estos archivos, insertaremos el marcado para la diapositiva deseada. Como ejemplo, creemos una diapositiva "Acerca de mí".

1.html

1
2
<div>
3
   <h3> About Me</h3>
4
   <ul>
5
      <li> Nettuts+ Editor</li>
6
      <li> Envato Marketplaces Manager</li>
7
      <li>Wicked WordPress Themes</li>
8
      <li>Theme Tumblr Like a Pro</li>
9
   </ul>
10
</div>

Siéntase libre de mezclar y combinar cómo usted desee.


3 - Cargue las diapositivas

Antes de poder centrarnos en el estilo de nuestra presentación, necesitamos cargar - load - esas diapositivas en nuestro documento con jQuery. Pero en lugar de crear un montón de variables y métodos globales, almacenaremos todo en un objeto, denominado Slides.

1
2
var Slides = {
3
4
};

A continuación, el proceso de cargar esas diapositivas en nuestro documento se almacenará dentro de un método, digamos loadContent(). Vamos a crear eso ahora.

1
2
var Slides = {
3
   loadContent : function() {
4
5
   }
6
}

Para cargar todas las diapositivas dentro del directorio slides/, primero necesitamos saber cuántos diapositivas hay; sin embargo, JavaScript no tiene la capacidad para acceder al sistema de archivos. En su lugar, pasaremos nuestro número total de diapositivas cuando inicialicemos nuestro objeto.

Con eso en mente, vamos a crear un método init() que servirá como nuestro controlador, de clases. Este método también recibirá un argumento que especifica el número total de diapositivas. Esto se asignará a una propiedad de nuestro objeto Slides.

1
2
var Slides = {
3
   totalSlides : '',
4
5
   init : function( totalSlides ) {
6
      // If nothing was passed to this function, we can't continue. 

7
      if ( !totalSlides ) throw new Error('Please pass the total number of slides to the init method');
8
      Slides.totalSlides = totalSlides;
9
10
      // Load the slides

11
      Slides.loadContent();
12
   },
13
14
   loadContent : function() {
15
16
   }
17
}

Así está mejor. Pero, por supuesto, nada de este código se ejecutará hasta que invoquemos al método init().

1
2
var Slides = {
3
   totalSlides : '',
4
5
   init : function( totalSlides ) {
6
      // If nothing was passed to this function, we can't continue. 

7
      if ( !totalSlides ) throw new Error("Please pass the total number of slides to the init method");
8
      Slides.totalSlides = totalSlides;
9
10
      // Load the slides

11
      Slides.loadContent();
12
   },
13
14
   loadContent : function() {
15
16
   }
17
}
18
19
// All right; let's do this. We'll assume that we've created 6 slides, total.

20
Slides.init( 6 );

4 - Tres Maneras de Cargar las Diapositivas

Vamos a dar nuestro primer golpe al cargar estas diapositivas - y luego vamos a mejorar lentamente nuestro código, a medida que continuamos.

1
2
loadContent : function() {
3
   for ( var i = 0; i < Slides.totalSlides; i++ ) {
4
      $('<div id="#slide-' + i + '"></div>')
5
         .load('slides/' + i + '.html')
6
         .appendTo( $('#slides') );
7
   }
8
}

Arriba, estamos creando un nuevo elemento div para el número total de diapositivas que hemos especificado. Cada div tendrá un id de #slide-n. Luego de haber creado cada elemento, cargamos el contenido de la diapositiva deseada, que almacenamos en el directorio slides/. Una vez que este bloque de HTML haya sido recuperado del servidor, agregamos el div recién creado al contenedor #slides.

Podemos Hacerlo Mejor

Este código realmente funciona, pero podemos hacerlo mejor. Hay un par de problemas con el código anterior:

  • Atravesando: Para cada diapositiva, estamos atravesando el DOM para el elemento #slides. Esto es inútil e innecesario. Además, como ciertamente estaremos trabajando con este elemento de contenedor #slides en todo nuestro proyecto, tiene sentido almacenarlo como una propiedad de nuestro objeto Slides. Lo haremos en breve.
  • Reflujos: Este código creará cualquier número de reflujos de página, lo que puede aumentar el tiempo de carga de nuestra página. En lugar de invocar el método appendTo() docenas de veces (o en nuestro caso: seis), limitemos nuestros reflujos a uno.

Atravesando

Primero arreglaremos el problema del recorrido.

1
2
var Slides = {
3
   totalSlides : '',
4
   container : $( "#slides" ),
5
6
   init() { ... },
7
   loadContent() { ... }
8
}

De esta manera, buscamos nuestro documento el elemento #slides exactamente una vez, en lugar de una y otra vez.

Si todavía está confundido acerca de las ventajas de esto, piense en él como saltar en una piscina y buscar una moneda. Cada vez que usted invoque  $('#slides'), el motor de JavaScript salta a la piscina y busca esa moneda de nuevo. Una y otra vez. Sin embargo, si en lugar de ello almacenamos la ubicación de $('#slides') en una variable, nunca tendrá que volver a saltar a esa piscina. La variable recuerda dónde está esa moneda.

Reflows

A continuación, nos encargaremos de ese molesto problema de reflujo. Hay dos formas de limitar nuestros reflujos. Examinaremos ambos métodos.

Fragmentos de Documentos

Los fragmentos de documentos JavaScript nos permiten almacenar trozos de HTML. Entonces, en lugar de actualizar el DOM varias veces, como hicimos antes, con este método, sólo invocamos appendTo() una vez.

Consulte aquí para obtener más información sobre fragmentos de documentos.

1
2
loadContent : function() {
3
   var frag = document.createDocumentFragment(),
4
      bit;
5
6
   for ( var i = 0; i < Slides.totalSlides; i++ ) {
7
      bit = $('<div id="#slide-' + i + '">'</div>')

8
         .load('slides/' + i + '.html')[0];
9
      frag.appendChild(bit);
10
      }
11
   Slides.container.append(frag);
12
}

Note que ya no invocamos a appendTo() dentro de la declaración for. En su lugar, sólo se invoca una vez. La única nota digna de mención es la sección [0], después de invocar al método load(). ¿Para qué necesitamos eso?

Los fragmentos de documentos alamcenan- espere por ello - fragmentos HTML o elementos. Sin embargo, cuando invocamos el método load() anterior, el objeto jQuery es, por supuesto, devuelto. Eso no es compatible. En su lugar, queremos filtrar hasta el elemento HTML mismo. Podemos hacerlo utilizando [0] o el método get(). Cualquier opción lo hará.

Oculte el Contenedor

Nuestra segunda opción es ocultar el elemento de contenedor. Cuando lo hacemos, independientemente de cuántas veces agregue elementos nuevos a ese elemento, no habrá reflujos de página adicionales...¡porque el elemento está oculto! Es un pequeño bonito truco que debe tener en su cinturón de herramientas.

1
2
loadContent : function() {
3
  // Hide the container. 

4
   Slides.container.hide();
5
6
   for ( var i = 0; i < Slides.totalSlides; i++ ) {
7
      $(''<div id="#slide-' + i + '">'</div>')
8
         .load('slides/' + i + '.html')
9
         .appendTo(Slides.container);
10
      }
11
12
   // Now display the slides container again - causing exactly one reflow.

13
   Slides.container.show();
14
}

Así que cualquiera de estas dos opciones hará el trabajo bien. Elija la que prefiera.

Si ahora ve nuestro proyecto en el navegador - asumiendo que ha agregado algunos diapositivas falsas al directorio slides/  - verá algo a lo largo de las líneas de:

Loaded ContentLoaded ContentLoaded Content

Si utilizamos una herramienta como Firebug o las herramientas de desarrollo de Chrome, veremos que como se esperaba, las diapositivas se han insertado en el div del contenedor #slides.

Source codeSource codeSource code

5 - Adórnelo

Nuestro próximo paso tiene lugar dentro de nuestra hoja de estilos. Nos centraremos tanto en la estética como en la función aquí. Para que cada diapositiva se desplace de izquierda a derecha, tendremos que ser inteligentes con nuestro estilo.

Comenzaremos creando nuestro lienzo. Si se remite a nuestro marcado...

1
2
<!DOCTYPE HTML>
3
<html>
4
<head>
5
   <meta charset="utf-8">
6
   <link href="style.css" rel="stylesheet" />
7
   <title>My Great Presentation</title>
8
</head>
9
10
<body>
11
12
 <div class="wrap">
13
   <div id="slides">
14
      <!-- load in slides -->
15
   </div>
16
 </div>  
17
18
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
19
</body>
20
21
</html>

... nuestro contenedor envoltorio para nuestro proyecto es el div con una class de wrap. Le proporcionaremos un ancho de 1180px y lo centraremos en la página.

1
2
.wrap {
3
   margin: auto;
4
   width: 1180px;
5
   overflow: hidden; /* because children will be floated */
6
}

A continuación, debido a que cada diapositiva debe desplazarse horizontalmente, necesitamos hacer que nuestro div #slides sea lo más ancho posible.

1
2
#slides {
3
  width: 999999px;
4
}

Ahora, la parte diversión - y de un poco de miedo. Piense en una diapositiva de presentación tradicional. ¿No está el contenido típicamente centrado verticalmente y horizontalmente en la diapositiva, o la página? Absolutamente. Debido a que tenemos el 100% de control sobre este proyecto, no necesitamos preocuparnos por los estándares de navegador. Como las diapositivas sólo serán utilizadas por nosotros (durante nuestra presentación), somos libres de adaptarlo a nuestro navegador favorito. De esta manera, podremos utilizar muchas funciones nuevas y divertidas que aún no han llegado a todos los navegadores, como el Flexible Box Model.

Empezaremos especificando las dimensiones de cada diapositiva, flotando cada diapositiva y proporcionando espacio de respiración (márgenes).

1
2
#slides > div {
3
	height: 600px;
4
	width: 1180px;
5
	float: left;
6
	margin-right: 200px;
7
	text-align: center;
8
}
Floating SlidesFloating SlidesFloating Slides

Pero recuerde: ese texto debe centrarse verticalmente. ¡Flexible Box Model al rescate!

1
2
#slides > div {
3
	height: 600px;
4
	width: 1180px;
5
	float: left;
6
	margin-right: 200px;
7
	text-align: center;
8
9
        /* Flexible Box Model */        
10
        display: -webkit-box;
11
	-webkit-box-align: center;
12
	-webkit-box-orient: horizontal;
13
	-webkit-box-pack: center;
14
15
	display: box;
16
	box-align: center;
17
	box-orient: horizontal;
18
	box-pack: center;
19
}
Adding flexiboxAdding flexiboxAdding flexibox

A continuación, añadiremos un bonito fondo de gradiente radial a nuestras diapositivas. Para ser honesto las gradientes radiales CSS todavía me desconciertan. Rara vez recuerdo la sintaxis. Como tal, normalmente bien tomo nota de las gradientes en que me gustan, o utilizo cualquiera de los generadores de gradiente en la web para hacer la mía. Siéntase libre de hacer lo mismo.

1
2
body {
3
	background-image: -webkit-gradient(
4
		radial, 
5
		50% 50%, 0, 
6
		50% 50%, 1000, 
7
		from(rgba(245,245,245,1)), 
8
		to(rgba(100,100,100,1))
9
	);
10
}
Applying a radial gradientApplying a radial gradientApplying a radial gradient

Y, con eso, tenemos nuestra estructura básica en su lugar. En este punto, le animo a que le de estilo a sus encabezados, tal vez la creación de una rejilla mínima, y ​​cualquier otra cosa que se pueda imaginar. Terminaremos nuestro estilo mínimo trabajando en tipografía.

1
2
#slides h1,
3
#slides h2,
4
#slides h3,
5
#slides h4,
6
#slides h5 {
7
	color: #292929;
8
	font-family: 'League Gothic', sans-serif;
9
	letter-spacing: -5px;
10
	margin-top: 0;
11
	text-shadow: 5px 3px 0 white;
12
}
13
#slides > div h2 {
14
	font-size: 180px;
15
	line-height: 1em;
16
	margin: 0;
17
}

¡Es increíble lo que podemos lograr cuando modificamos el espaciado de letras y aplicamos sombras de texto inteligentes! ¡Se ve mucho mejor ahora!

The Business of WordPress Theme DesignThe Business of WordPress Theme DesignThe Business of WordPress Theme Design
Custom TextCustom TextCustom Text

6 - Siguiente Diapositiva, Por Favor

El siguiente paso en este proyecto es manejar el proceso de transición entre diapositivas. Naturalmente, como no hay botones en su lugar, debemos detectar cuando se presionan las teclas de flecha izquierda o derecha. Guardaremos esta funcionalidad en un nuevo método keyPress de nuestro objeto Slides.

1
2
var Slides = {
3
   ...
4
   init : function() { ... },
5
   loadContent: function() { ... },
6
   keyPress : function() {
7
      $(document.body).keydown(function(e) {
8
         // if left or right arrow key is pressed

9
         if ( e.keyCode === 39 || e.keyCode === 37 ) {
10
            e.preventDefault();
11
            ( e.keyCode === 39 ) ? Slides.next() : Slides.prev();
12
         }
13
      });
14
   }
15
16
}

JQuery proporciona el útil método keydown, que conectará los detectores de eventos necesarios. Esto significa que la función de devolución pasada funcionará para cada tecla que se presione; sin embargo, sólo nos interesa la tecla de flecha derecha e izquierda, o los códigos de tecla 39 y 37 respectivamente. Si se presiona alguna de estas teclas, primero cancelaremos la acción por defecto de la tecla de flecha e invocaremos bien sea el método next() o prev() , dependiendo de qué tecla hayamos presionado.

Siguiente Diapositiva

Ahora vamos a trabajar en ese método next() que hemos invocado anteriormente. Cuando se invoca este método, necesita ejecutar algunas operaciones:

  • Actualizar el hash en la URL. De esta manera, podemos enviar fácilmente enlaces a diapositivas específicas.
  • Animar la diapositiva a la izquierda y revelar la siguiente diapositiva en la secuencia.

Pero antes de seguir adelante, ¿cómo sabemos cuánto desplazar la diapositiva? Debe ser el ancho del contenedor #slides, pero debemos intentar no codificar ese valor en nuestro JavaScript si no tenemos que hacerlo. La razón de esto es porque, si más tarde decidimos cambiar las dimensiones de nuestro lienzo, también tendríamos que cavar en nuestro archivo de JavaScript y actualizar las dimensiones también. En vez de eso, determinemos dinámicamente cuál es el ancho y los márgenes del contenedor.

Añadamos una nueva propiedad al objeto Slides, llamada slideWidth. Sin embargo, no podremos determinar el ancho de las diapositivas hasta que se hayan insertado en el DOM, a través del método loadContent.

1
2
var Slides = {
3
   ...
4
   // New property stores the width of each slide

5
   slideWidth : '',
6
   ...
7
8
   init : function( totalSlides ) { ... },
9
   
10
   loadContent : function() { ... },
11
12
   // Determine the width of the slide...

13
   setSlideWidth : function() {
14
      var each = Slides.container.children( 'div' );
15
      Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );
16
   }
17
   
18
}

¡Guau - esa línea asusta un poco!

1
2
Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );

Pero no se preocupe; es realmente muy simple. Estamos actualizando la propiedad Slides.slideWidth y estamos haciendo que sea igual al ancho de la diapositiva más su margen derecho. Debido a que recuperar el valor margin-right de las diapositivas (específicamente el primero) devolverá px también, tenemos que retirar eso, utilizando la función parseInt.

Para aclarar la necesidad de retirar, suponiendo que el valor del margen derecho es igual a 200px ...

1
2
console.log ( typeof each.css('margin-right').split('px')[0] ); // value is 200. Typeof is still string, not integer.

Y con eso fuera del camino, ahora estamos determinando dinámicamente el ancho de nuestras diapositivas. Volvamos a nuestro método next(); en todo momento necesitamos rastrear el posicionamiento de nuestras diapositivas. De esa manera, cuando pasemos de la diapositiva cuatro a cinco, sabemos exactamente cuánto desplazar la diapositiva. Guardaremos este valor en una nueva propiedad: translateAmount.

1
2
translateAmount : '',
3
next : function() {
4
   Slides.translateAmount -= Slides.slideWidth;
5
}

Vamos a separarlo. Cuando presionamos la tecla de flecha derecha right la primera vez, establecemos la propiedad translateAmount igual a slideWidth o en nuestro caso, 1380px. Si pulsamos nuevamente right, este valor se actualizará a 2760px.

Actualice el Hash

Dentro de este método next, también debemos actualizar el valor de hash en nuestra url, como example.com/index.html#slide-1, luego example.com/index.html#slide-2, etc. Para esto necesitamos llevar la cuenta de la diapositiva actual que el lector está viendo.

1
2
currentSlide : 0,
3
4
...
5
next : function() {
6
   Slides.translateAmount -= Slides.slideWidth;
7
   Slides.updateHash( ++Slides.currentSlide );
8
},
9
10
updateHash : function() {
11
   location.hash = '#slide-' + Slides.currentSlide;
12
}

Tenga en cuenta que estamos aumentando el valor de currentSlide en uno antes de pasarlo a la función updateHash. Esto es apropiado; cuando presionamos la tecla de flecha derecha right, el hash se debería actualizar a la siguiente diapositiva, no a la actual.

Anime la Diapositiva

Finalmente, ahora que hemos llevado la cuenta de todos los valores necesarios, podemos animar los diapositivas.

1
2
next : function() {
3
   Slides.translateAmount -= Slides.slideWidth;
4
   Slides.updateHash( ++Slides.currentSlide );
5
   Slides.animate();
6
},
7
8
animate : function() {
9
   Slides.container
10
      .children()
11
         .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)');
12
}

Para mejor rendimiento, aprovecharemos CSS3 para transicionar las diapositivas. Para que esto no sea una transición instantánea, necesitamos actualizar nuestro archivo CSS:

1
2
#slides div {
3
   ...
4
   -webkit-transition: all 1s linear;
5
   transition: all 1s linear;
6
}

Y la Diapositiva Anterior Por Favor

El método prev será realmente similar al método next, excepto por un par de cosas.

1
2
prev : function() {
3
  // No more left to go back.

4
   if ( Slides.translateAmount === 0 ) return;
5
6
   Slides.translateAmount += Slides.slideWidth;
7
   Slides.updateHash( --Slides.currentSlide );
8
   Slides.animate();
9
}

Esta vez, mientras regresemos de vuelta al principio de las diapositivas, necesitamos invertir el valor de translateAmount y hash. Además, debemos considerar la posibilidad de que el usuario presione la tecla de flecha izquierda left incluso cuando esté en la primera diapositiva. Si ese es el caso, no deberíamos hacer nada, ¡ya que no queda nada hacia dónde poder desplazarse!

JavaScript Final

1
2
var Slides = {
3
   container : $('#slides'),
4
5
   totalSlides : '',
6
7
   translateAmount : 0,
8
9
   currentSlide : 0,
10
11
   slideWidth : '',
12
13
   init : function(totalSlides) {
14
      var each;
15
16
      if ( !totalSlides ) throw new Error('Please pass the total number of slides.');
17
      Slides.totalSlides = totalSlides;
18
19
      Slides.loadContent();
20
21
      each = Slides.container.children('div');
22
      
23
      // Determine the width of our canvas

24
      Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );
25
26
      Slides.keyPress();
27
   },
28
29
   loadContent : function() {
30
      Slides.container.hide();
31
      for ( var i = 0; i < Slides.totalSlides; i++ ) {
32
         $('<div id="#slide-' + i + '"></div>')
33
            .load('slides/' + i + '.html')
34
            .appendTo(Slides.container);
35
         }
36
      Slides.container.show();
37
   },
38
39
   keyPress : function() {
40
      $(document.body).keydown(function(e) {
41
         // if left or right arrow key is pressed

42
         if ( e.keyCode === 39 || e.keyCode === 37 ) {
43
            e.preventDefault();
44
            ( e.keyCode === 39 ) ? Slides.next() : Slides.prev();
45
         }
46
      });
47
   },
48
49
   next : function( ) {
50
      Slides.translateAmount -= Slides.slideWidth;
51
      Slides.updateHash( ++Slides.currentSlide );
52
      Slides.animate();
53
   },
54
55
  prev : function() {
56
     // No more left to go back.

57
      if ( Slides.translateAmount === 0 ) return;
58
59
      Slides.translateAmount += Slides.slideWidth;
60
      Slides.updateHash( --Slides.currentSlide );
61
      Slides.animate();
62
  },
63
64
  animate : function() {
65
     Slides
66
      .container
67
      .children()
68
         .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)' );
69
  },
70
71
  updateHash : function( direction ) {
72
     // Update current Slides and hash.

73
     location.hash = '#slide-' + Slides.currentSlide;
74
  }
75
};
76
77
// All right; let's do this. 

78
Slides.init(6);

Completo

Todo terminado. ¡Eso no fue demasiado difícil, una vez que excavamos un poco! Lo mejor es que, si ve la presentación en una resolución muy alta o baja, puede simplemente acercar o alejar algunos clics para compensar, presionando Command o Control +-. ¡Hágame saber si usted tiene cualquier preguntas o recomendación!

The Business of WordPress Theme DesignThe Business of WordPress Theme DesignThe Business of WordPress Theme Design
A Slide ExampleA Slide ExampleA Slide Example
License SlidesLicense SlidesLicense Slides
Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.