How to Create Presentation Slides with HTML and CSS
plusvideos

How to Create Presentation Slides with HTML and CSS

Tutorial Details
  • Topic: Presentation Slides with HTML
  • Difficulty: Intermediate
  • Estimated Completion Time: 30 Minutes
Download Source Files

As I sifted through the various pieces of software that are designed for creating presentation slides, it occurred to me: why learn yet another program, when I can instead use the tools that I’m already familiar with? With a bit of fiddling, we can easily create beautiful presentations with HTML and CSS. I’ll show you how today!

0 – Directory Structure

Before we get started, let’s go ahead and create our folder structure; it should be fairly simple. We’ll need:

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

A simple base template. Your slides/ directory can remain blank for the time being. We’ll fill that shortly.


1 – Beginning Markup

Let’s begin by creating the base markup for our presentation page. Paste the following snippet into your index.html file.

<!DOCTYPE HTML>
<html>
<head>
   <meta charset="utf-8">
   <link href="style.css" rel="stylesheet" />
   <title>My Great Presentation</title>
</head>

<body>

 <div class="wrap">
   <div id="slides">
      <!-- load in slides -->
   </div>
 </div>  

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
</body>

</html>   

Above we have some clean, HTML5 goodness. No more type attributes in our script and link elements, short DOCTYPE, a laughably simple meta charset tag, etc.


2 – Slides

The load() method is an AJAX method that loads data from your server, and inserts the returned HTML into the selected element.

Now you might be wondering how we’re going to deal with each slide. We have a couple options here. While we could wrap each slide in its own div, and place a massive block of HTML within the #slides container, my instinct is that this will make the process of editing individual slides more time consuming, as we then have to hunt through all that markup for the slide that we need.

Instead, for this tutorial, I’ve opted to place each slide within its own .html file. We can then use jQuery’s load() method to bring in each slide, and append them to our container.

Create a handful of numbered HTML files, and place them within your slides/ directory, like so:

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

Within each of these files, we’ll insert the markup for your desired slide. As an example, together, let’s create an “About Me” slide.

1.html

<div>
   <h3> About Me</h3>
   <ul>
      <li> Nettuts+ Editor</li>
      <li> Envato Marketplaces Manager</li>
      <li>Wicked WordPress Themes</li>
      <li>Theme Tumblr Like a Pro</li>
   </ul>
</div>

Feel free to mix and match how you wish.


3 – Load the Slides

Before we can focus on the styling of our presentation, we need to load those slides into our document with jQuery. But rather than creating a bunch of global variables and methods, we’ll store everything in an object, called Slides.

var Slides = {

};

Next, the process of loading those slides into our document will be stored within, say, a loadContent() method. Let’s create that now.

var Slides = {
   loadContent : function() {

   }
}

To load all of the slides within the slides/ directory, we first need to know how many slides there are; though, JavaScript doesn’t have the ability to access the file system. Instead, we’ll pass in our total number of slides when we initiate our object.

With that in mind, let’s create an init() method that will serve as our controller, of sorts. This method will also receive an argument that specifies the total number of slides. This will then be assigned to a property of our Slides object.

var Slides = {
   totalSlides : '',

   init : function( totalSlides ) {
      // If nothing was passed to this function, we can't continue. 
      if ( !totalSlides ) throw new Error('Please pass the total number of slides to the init method');
      Slides.totalSlides = totalSlides;

      // Load the slides
      Slides.loadContent();
   },

   loadContent : function() {

   }
}

That’s better. But, of course, none of this code will run until we call the init() method.

var Slides = {
   totalSlides : '',

   init : function( totalSlides ) {
      // If nothing was passed to this function, we can't continue. 
      if ( !totalSlides ) throw new Error("Please pass the total number of slides to the init method");
      Slides.totalSlides = totalSlides;

      // Load the slides
      Slides.loadContent();
   },

   loadContent : function() {

   }
}

// All right; let's do this. We'll assume that we've created 6 slides, total.
Slides.init( 6 );

4 – Three Ways to Load the Slides

Let’s take our first crack at loading these slides — and then we’ll slowly improve upon our code, as we continue.

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

Above, we’re creating a new div element for the total number of slides that we’ve specified. Each div will have an id of #slide-n. After we’ve created each element, we then load the contents of the desired slide, which we stored within the slides/ directory. Once this block of HTML has been retrieved from the server, we append the newly created div to the #slides container.

We Can Do Better

This code will indeed work, but we can do better. There are a couple issues with the code above:

  • Traversal: For every slide, we are traversing the DOM for the #slides element. This is wasteful and unnecessary. Also, as we’ll certainly be working with this #slides container element throughout our project, it makes sense to store it as a property of our Slides object. We’ll do this shortly.
  • Reflows: This code will create any number of page reflows, which can increase the load time of our page. Rather than calling the appendTo() method dozens of times (or in our case: six), let’s limit our reflows to one.

Traversal

Let’s first fix the traversal issue.

var Slides = {
   totalSlides : '',
   container : $( "#slides" ),

   init() { ... },
   loadContent() { ... }
}

This way, we search our document for the #slides element exactly once, rather than over and over.

If you’re still confused about the advantages to this, think of it as jumping into a pool, and searching for a coin. Every time you call $('#slides'), the JavaScript engine jumps in the pool and looks for that coin again. Over and over. But, if we instead store the location of $('#slides') in a variable, it never has to jump back into that pool. It remembers where that coin is.

Reflows

Next, we’ll take care of that pesky reflow issue. There are two ways to limit our reflows. We’ll examine both methods.

Document Fragments

JavaScript document fragments allow us to store chunks of HTML. Then, rather than updating the DOM multiple times, as we did before, with this method, we only call appendTo() once.

Refer here for more information on document fragments.

loadContent : function() {
   var frag = document.createDocumentFragment(),
      bit;

   for ( var i = 0; i < Slides.totalSlides; i++ ) {
      bit = $('<div id="#slide-' + i + '">'</div>')
         .load('slides/' + i + '.html')[0];
      frag.appendChild(bit);
      }
   Slides.container.append(frag);
}

Note that we’re no longer calling appendTo() within the for statement. Instead, it’s only being called once. The only note worth mentioning is the [0] section, after we call the load() method. What do we need that for?

Document fragments store — wait for it — HTML fragments, or elements. However, when we called the load() method above, the jQuery object is, of course, returned. That’s not compatible. Instead, we want to filter down to the HTML element, itself. We can do so by using [0], or the get() method. Either option will do.

Hide the Container

Our second option is to hide the container element. When we do so, regardless of how many times you append new elements to that element, no additional page reflows will take effect…because the element is hidden! It’s a nice little trick to have in your tool belt.

loadContent : function() {
  // Hide the container. 
   Slides.container.hide();

   for ( var i = 0; i < Slides.totalSlides; i++ ) {
      $(''<div id="#slide-' + i + '">'</div>')
         .load('slides/' + i + '.html')
         .appendTo(Slides.container);
      }

   // Now display the slides container again - causing exactly one reflow.
   Slides.container.show();
}

So either of these two options will do just fine. Choose whichever you prefer.

If you now view our project in the browser — assuming you’ve added some dummy slides to the slides/ directory — you’ll see something along the lines of:

Loaded Content

If we use a tool like Firebug or Chrome’s developer tools, we’ll see that, as expected, the slides have been inserted into the #slides container div.

Source code

5 – Make it Pretty

Our next step takes place within our stylesheet. We’ll be focusing on both aesthetics as well as function here. To make each slide translate from left to right, we’ll need to be clever with our styling.

We’ll begin by creating our canvas. If you refer back to our markup…

<!DOCTYPE HTML>
<html>
<head>
   <meta charset="utf-8">
   <link href="style.css" rel="stylesheet" />
   <title>My Great Presentation</title>
</head>

<body>

 <div class="wrap">
   <div id="slides">
      <!-- load in slides -->
   </div>
 </div>  

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
</body>

</html>   

…our wrapping container for our project is the div with a class of wrap. We’ll provide a width of 1180px and center it on the page.

.wrap {
   margin: auto;
   width: 1180px;
   overflow: hidden; /* because children will be floated */
}   

Next, because each slide should translate horizontally, we need to make our #slides div as wide as possible.

#slides {
	width: 999999px;
}

Now, the fun — and a little scary — part. Think of a traditional presentation slide. Isn’t the content typically both vertically and horizontally centered on the slide, or page? Absolutely. Because we have 100% control over this project, we don’t need to worry about browser compliance. As the slides will only ever be used by us (during our presentation), we’re free to tailor it to our favorite browser. This way, we get to use lots of fun new features that haven’t yet made their way into all the browsers, such as the Flexible Box Model.

We’ll begin by specifying the dimensions for each slide, floating each slide, and providing some breathing room (margins).

#slides > div {
	height: 600px;
	width: 1180px;
	float: left;
	margin-right: 200px;
	text-align: center;
}   
Floating Slides

But remember: that text needs to be vertically centered. Flexible Box Model to the rescue!

#slides > div {
	height: 600px;
	width: 1180px;
	float: left;
	margin-right: 200px;
	text-align: center;

        /* Flexible Box Model */        
        display: -webkit-box;
	-webkit-box-align: center;
	-webkit-box-orient: horizontal;
	-webkit-box-pack: center;

	display: box;
	box-align: center;
	box-orient: horizontal;
	box-pack: center;
}   
Adding flexibox

Next, we’ll add a nice radial gradient background to our slides. To be honest, CSS radial gradients still baffle me. I rarely remember the syntax. As such, I typically either make note of gradients in the wild that I like, or use any of the various gradient generators on the web to make mine. Feel free to do the same.

body {
	background-image: -webkit-gradient(
		radial, 
		50% 50%, 0, 
		50% 50%, 1000, 
		from(rgba(245,245,245,1)), 
		to(rgba(100,100,100,1))
	);
}   
Applying a radial gradient

And, with that, we have our basic structure in place. At this point, I encourage you to being styling your headings, perhaps creating a minimal grid, and anything else you can think of. We’ll finish our minimal styling by working on typography.

#slides h1,
#slides h2,
#slides h3,
#slides h4,
#slides h5 {
	color: #292929;
	font-family: 'League Gothic', sans-serif;
	letter-spacing: -5px;
	margin-top: 0;
	text-shadow: 5px 3px 0 white;
}
#slides > div h2 {
	font-size: 180px;
	line-height: 1em;
	margin: 0;
}

It’s amazing what we can achieve when we tweak letter-spacing, and apply some clever text shadows! Looks much better now!

The Business of WordPress Theme Design
Custom Text

6 – Next Slide, Please

The next step in this project is to handle the process of transitioning from slide to slide. Naturally, as there are no buttons in place, we should instead listen for when either the left or right arrow keys are pressed. We’ll store this functionality in a new keyPress method of our Slides object.

var Slides = {
   ...
   init : function() { ... },
   loadContent: function() { ... },
   keyPress : function() {
      $(document.body).keydown(function(e) {
         // if left or right arrow key is pressed
         if ( e.keyCode === 39 || e.keyCode === 37 ) {
            e.preventDefault();
            ( e.keyCode === 39 ) ? Slides.next() : Slides.prev();
         }
      });
   }

}

jQuery provides the helpful keydown method, which will attach the necessary event listeners. This means that the passed callback function will run for every key that is pressed; however, we’re only interested in the right and left arrow key, or key codes 39 and 37, respectively. If one of these keys is pressed, we first cancel the default action of the arrow key, and then call either the next() or prev() method, dependent upon which key was pressed.

Next Slide

Let’s now work on that next() method that we called above. When this method is called, it needs to execute a few operations:

  • Update the hash in the URL. That way, we can easily send out links to specific slides.
  • Animate the slide to the left, and reveal the next slide in the sequence.

But before moving forward, how do we know how much to translate the slide? It needs to be the width of the #slides container, but we should try not to hardcode that value into our JavaScript if we don’t have to. The reason for this is because, if we later decide to change the dimensions of our canvas, we’d also need to dig into our JavaScript file and update the dimensions as well. Instead, let’s dynamically determine what the width and margins of the container is.

Let’s add a new property to the Slides object, called slideWidth. However, we won’t be able to determine the width of the slides until they’ve been inserted into the DOM, via the loadContent method.

var Slides = {
   ...
   // New property stores the width of each slide
   slideWidth : '',
   ...

   init : function( totalSlides ) { ... },
   
   loadContent : function() { ... },

   // Determine the width of the slide...
   setSlideWidth : function() {
      var each = Slides.container.children( 'div' );
      Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );
   }
   
}

Yikes – this line looks a bit scary!

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

But don’t worry; it’s really quite simple. We’re updating the Slides.slideWidth property, and are making it equal to the width of the slide plus its margin right. Because retrieving the margin-right value of the slides (specifically the first one) will return px as well, we need to slice that off, by using the parseInt function.

To clarify the need for casting, assuming that the margin right value is equal to 200px

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

And with that out of the way, we’re now dynamically determining the width of our slides. Back to our next()method; at all times, we need to track the positioning of our slides. That way, when we transition from slide four to five, we know exactly how much to translate the slide. We’ll store this value in a new property: translateAmount.

translateAmount : '',
next : function() {
   Slides.translateAmount -= Slides.slideWidth;
}

Let’s break it down. When we press the right arrow key the first time, we set the translateAmount property equal to the slideWidth, or in our case, 1380px. If we press right again, this value will be updated to 2760px.

Update the Hash

Within this next method, we should also update the hash value in our url, such as example.com/index.html#slide-1, then example.com/index.html#slide-2, etc. To do so, we need to keep track of the current slide that the reader is viewing.

currentSlide : 0,

...
next : function() {
   Slides.translateAmount -= Slides.slideWidth;
   Slides.updateHash( ++Slides.currentSlide );
},

updateHash : function() {
   location.hash = '#slide-' + Slides.currentSlide;
}

Note that we’re increasing the value of currentSlide by one before passing it to the updateHash function. This is appropriate; when we press the right arrow key, the hash should be updated to the next slide, not the current one.

Animate the Slide

Finally, now that we’ve tracked all of the necessary values, we can animate the slides.

next : function() {
   Slides.translateAmount -= Slides.slideWidth;
   Slides.updateHash( ++Slides.currentSlide );
   Slides.animate();
},

animate : function() {
   Slides.container
      .children()
         .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)');
}

For best performance, we’ll take advantage of CSS3 to translate the slides. In order for this to not be an instant translation, we need to update our CSS file:

#slides div {
   ...
   -webkit-transition: all 1s linear;
   transition: all 1s linear;
}   

And the Previous Slide, Please

The prev method will be really similar to the next method, except for a couple things.

prev : function() {
  // No more left to go back.
   if ( Slides.translateAmount === 0 ) return;

   Slides.translateAmount += Slides.slideWidth;
   Slides.updateHash( --Slides.currentSlide );
   Slides.animate();
}

This time, as we’re transitioning back to the beginning of the slides, we need to reverse the translateAmount and hash value. Also, we must consider the possibility that the user is pressing the left arrow key even when they’re on the very first slide. If that happens to be the case, we shouldn’t do anything, as there’s nothing left to transition to!

Final JavaScript

var Slides = {
   container : $('#slides'),

   totalSlides : '',

   translateAmount : 0,

   currentSlide : 0,

   slideWidth : '',

   init : function(totalSlides) {
      var each;

      if ( !totalSlides ) throw new Error('Please pass the total number of slides.');
      Slides.totalSlides = totalSlides;

      Slides.loadContent();

      each = Slides.container.children('div');
      
      // Determine the width of our canvas
      Slides.slideWidth = each.width() + ( parseInt( each.css('margin-right'), 10 ) );

      Slides.keyPress();
   },

   loadContent : function() {
      Slides.container.hide();
      for ( var i = 0; i < Slides.totalSlides; i++ ) {
         $('<div id="#slide-' + i + '"></div>')
            .load('slides/' + i + '.html')
            .appendTo(Slides.container);
         }
      Slides.container.show();
   },

   keyPress : function() {
      $(document.body).keydown(function(e) {
         // if left or right arrow key is pressed
         if ( e.keyCode === 39 || e.keyCode === 37 ) {
            e.preventDefault();
            ( e.keyCode === 39 ) ? Slides.next() : Slides.prev();
         }
      });
   },

   next : function( ) {
      Slides.translateAmount -= Slides.slideWidth;
      Slides.updateHash( ++Slides.currentSlide );
      Slides.animate();
   },

  prev : function() {
     // No more left to go back.
      if ( Slides.translateAmount === 0 ) return;

      Slides.translateAmount += Slides.slideWidth;
      Slides.updateHash( --Slides.currentSlide );
      Slides.animate();
  },

  animate : function() {
     Slides
      .container
      .children()
         .css( '-webkit-transform', 'translateX(' + Slides.translateAmount + 'px)' );
  },

  updateHash : function( direction ) {
     // Update current Slides and hash.
     location.hash = '#slide-' + Slides.currentSlide;
  }
};

// All right; let's do this. 
Slides.init(6);

Complete

All finished. That wasn’t too hard, once we dug in a bit! The great thing is that, if you view the presentation on a really high or low resolution, you can simply zoom in or out a few clicks to compensate, by pressing Command or Control +-. Let me know if you have any questions or recommendations!

The Business of WordPress Theme Design
A Slide Example
License Slides

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Mike Saky

    Jef, I really appreciate your time and phenomenal tutorials. You are boss. You are able to build y our own business!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Thanks, Mike! But I’m happy at Envato right now. :)

  • http://twitter.com/mamunabms Abdullah Al Mamun

    Great! Thanks Jeff! :)

  • http://www.templatejuice.com J.F. Herrera

    Great tutorial! Did I miss the demo button somewhere? I would really like to see the demo.

    • http://pangomedia.se Christian

      And i Video tut… :)

    • http://www.siteoptimo.com Pieter Carette

      +1 for a demo

    • Jeremy

      another +1 for a demo. I don’t have time right now to build a test even form your files. I understand that it might fail in certain browsers… just be clear about what browser to test ‘your’ demo version in to reduce the “doesn’t work in **** browser” even though it’s already stated…

      • Weihemann

        +1 for a demo!

  • http://www.idomain.co.il avi cohen

    nice guide… thanks :)

  • http://www.modernooze.com sam – dorset web design

    Very good i like how you assume that i dont know much about what you are trying to do. I read to many articles where the write makes assumptions about what you know and what you dont.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yeah – that’s a pet peeve of mine too, as a reader.

  • http://markpopkes.com Mark

    Pretty cool! I’d like to take this and tweak it with CSS3 media queries so the slides fit perfect based on the user resolution! And maybe hide the horizontal scrollbar to make it feel like a presentation (dare I say Power Point?).

    Awesome tut!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Hey Mark – Or just zoom in a few clicks with Command +, dependent upon the resolution. I had planned on using media queries, but then I decided not to bother, since this is mostly a personal project.

  • http://www.sojournoxnard.com Tiffany

    I can’t get it to work in Firefox v3.16… updating to Firefox 4 right now. In Firefox 3 though when you use the arrow key it inches along instead of advancing.

  • Zach Smith

    Sweet tutorial! Couple questions:
    Should you check in the Slides.next() function to see if you are at the end, just like you did in the Slides.previous() function? Somethink like this maybe?


    next: function() {
    if ( Slides.currentSlide === Slides.totalSlides – 1 ) return;

    Also, I thought the double bitwise operator trick was pretty sweet; I’d never seen that before. I’m used to just using parseInt(’10px’, 10); to get the integer. Is there an advantage to your method? Other than being more badass?

    • http://www.magentix.be Kristiaan Van den Eynde

      The double bitwise NOT operator is commonly used as a faster/cooler way of parseInt() on a DECIMAL float, NOT parseInt(x,10) on just any string!

      Octagonal (parseInt != ~~)
      ~~(’010′) = 10
      parseInt(’010′) = 8
      parseInt(’010′,10) = 10

      Decimal ( duh :) )
      ~~(’10′) = 10
      parseInt(’10′) = 10
      parseInt(’10′,10) = 10

      Decimal float (most common use)
      ~~(10.3) = 10
      parseInt(10.3) = 10
      parseInt(10.3,10) = 10

      Hexadecimal (parseInt = ~~)
      ~~(’0×10′) = 16
      parseInt(’0×10′) = 16
      parseInt(’0×10′,10) = 0

      As you can see, the results can be very unpredictable.

  • http://rockstarsteam.com Grom

    I think you saw Pol’s Irish video about performance, and he has this cool effects in presentation.. any chance you make tutorial how to do it?)

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      The 3D effect in his presentation? Not sure. I’d imagine he’s using CSS 3D translations to achieve that look.

  • http://www.magentix.be Kristiaan Van den Eynde

    Nice article with some very nice CSS3 candy!
    However, there are a few pitfalls in your code..

    Unsafe parameter checking:

    // Will fail when 0 is passed in, won’t fail when a string is passed in
    if ( !totalSlides ) throw new Error(‘Please pass the total number of slides to the init method’);

    // Will work with any valid number, but not with any other primitive/reference type
    if ( typeof totalSlides != “number” ) throw new Error(‘Please pass the total number of slides to the init method’);

    It may be best to promote the use of e.which when using jQuery. The property is normalized for maximum cross-browser compliance and works for both keyUp/keyDown (keyCode) as keyPress (charCode + keyCode). Although, according to the comments, it is said to be buggy in IE9.

    if ( e.which === 39 || e.which === 37 ) {
    e.preventDefault();
    ( e.which === 39 ) ? Slides.next() : Slides.prev();
    }

    (Quote)
    However, we won’t be able to determine the width of the slides until they’ve been inserted into the DOM, via the loadContent method.
    (End quote)

    It may be important to note that, when you hide content, some browsers may no longer correctly read CSS properties such as width and height either. Especially when you talk about using .hide() to reduce the amount of browser repaints.

    Then again, I’m splitting hairs here as it’s a very nice article nontheless :)
    Great read!

  • http://itcutives.com Jatin

    Even I miss the demo.

    Nice article, BTW.

  • http://www.hanami.be Thomas

    Nice tuts !
    To avoid the bottom scrollbar I just add some stuff :


    Slides.loadContent();
    Slides.setSlideWidth();

    Slides.setContainerWidth();

    Slides.keyPress();

    setContainerWidth : function(){
    Slides.container.width(Slides.totalSlides * Slides.slideWidth);
    }

    body {

    overflow:hidden;
    }

    #slides {
    /* width: 999999px; */
    }

    Thats it ;-)

  • http://www.nouveller.com/ Benjamin Reid

    Some really nice practices going on in their, great stuff!

  • kankaro

    WTF!!! jeffrey you’re the man… can i borrow your mind for a while? peace:D by the way i have a question but this is out of your article… can you site me an idea on how to capture the “X” button in the browser? using JavaScript or any JavaScript framework… thanks a lot :D you can hit me in my email…

  • http://www.matiasmancini.com.ar Matias Mancini

    no demo?

  • http://www.downloadwebsitetemplates.co.uk Kevin

    Very nice tutorial, it might come in handy for uni =) Thanks

  • Carlos Vazquez

    Thanks for sharing, I’m (sick) tired of using Power Point, this is a great starting point for others to follow and improve this basic template.

  • http://www.arnaud-olivier.fr Arnaud

    Thanks for this tuto ;)

  • David

    Its pretty but doesnt work in Opera and Firefox 3.6.XX. In Firefox die Keys dont work and in my favorite browser Opera there is nothing in the window i think its a bug or code mistake in the javascript or?
    It would be better if i can show it in any browser. Yes CSS 3 must be supported but Opera 11.10 supports many css3 selectors and arguments. So what is Operas problem?^^ I think its great browser.

  • Yorick

    Pretty and very nice, but doesn’t work in Google Chrome either (Latest version).

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yes it does – but you have to upload the files to your server first.

      • Jim

        Nope it does not work for me either in Chrome. I’m using version 11.0.696.60
        Great idea though if it worked

  • Eric

    Why not just use:

    S5: A Simple Standards-Based Slide Show System
    http://meyerweb.com/eric/tools/s5/

    • http://jason.karns.name Jason

      I can’t believe that only one person so far has mentioned S5.

      • Eric

        I was surprised as well since S5 is truly great.

    • http://nathanbweb.com Nathan B

      Very glad to learn about this. Looks much simpler/easier/nicer.

  • http://www.ifadey.com Fawad Hassan

    I like the way you extract ideas.
    BTW nice article!

  • http://3xpro.co.cc/ Jone PI

    Thanks Jeffrey Way !

  • http://www.bloggerschmidt.de Alex

    This works in Firefox too:

    http://slides.html5rocks.com

  • http://www.revistatruta.com Truta101

    How do i go to next slide??? should i add a button???

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Press the left and right arrow keys.

  • http://www.noyasystem.com طراحی وب سایت

    nice, cool.
    I love your style of coding and writing post
    Best regards
    Ramin

  • ibura

    Greate Tut Jeff

  • http://m6method.com/ David Walsh

    For anyone looking for a live demo (like I was), I’ve uploaded the files here:

    http://m6method.com/shared/html5-slides/

    I can’t get further than a pretty blank screen though (screenshot), in both Chrome 11 and Safari 5.0.4.

    Anyone else?

    (Admin: Feel free to delete/edit this comment if an official demo-link is posted.)

    • Jai

      Its not working for me? Anyone know how? there have any browser specification?

  • http://isbkch.com vladimire

    Gave me some ideas, thank you

  • AL

    goodness grace too much work for creating a presentation…..
    obviously you can create presentation slides with any tools, even flash, silverlight, or even HTML but usability tanked once you do that. need to change the font? oh i should edit CSS or do inline CSS in HTML. need to make it Bold or Italic or dare i suggest animation? JQUERY coding again.

    software was supposed to make things easier…

    • Mark V.

      Al, there are plenty of WYSIWYG editors available out there, currently based on HTML but I’m sure HTML5/CSS3 editors are not far away either. You can build a nice presentation authoring system that will be available to use on your mobile phones, iPads, you name it. PowerPoint is growing heavier, works on Windows only, requires specific version to display correctly, and it’s simply not cool anymore.

      To be agile and able to do anything, on-the-spot, wherever you are, the method presented by Jeffrey here is the way to go. S5 works too (with no fancy animations and styles of course, but more browser compatible).

      Cheers.

      • AL

        Again, i do not bash the author. This is quite an amazing way to create presentation. What I’m saying is that exist a million way to create presentation and their level of maturity and usability of the software to the users.

        HTML CSS is good, but for ordinary users, it’s too much of a hassle to create presentation this way. Even worse is that positioning in HTML differ greatly from normal program (they use pixel based location, HTML use table or DIV). To add animation, you have to tinker with CSS (simple Hover) or Javascript (JQUERY transition or behaviour library). Normal users expects a toolbar, a list of icon of what they can do.

        Powerpoint (and their derivatives for Mac, or open office) work for user because their level of usability is actually very high. Compared these to Web Based presentation (HTML, Flash, Silverlight, etc) aren’t mature enough for ordinary users to use. You and me and the author surely have no problem whipping these kind of applications, but unless it worked for normal users, it TANKED :D.

  • http://rahul.upakare.com/ Rahul Upakare

    I have developed a similar web-based presentation tool (jqyery.presenter) using jQuery (I think the very first) long back and just did minor updates today. Your approach is different though.

    You can find my approach at: http://code.google.com/p/jquery-presenter
    And the demo at: http://rahul.upakare.com/projects/jquery.presenter/demo/

    All the best for your efforts.

  • http://www.ctyeung.com/wordpress/ CT Yeung

    Jeff,

    This must be a very good idea. Adobe Flex also recently has a new feature StageWebView where raw html can be loaded and displayed for flash content. I created a slide show that looks very much like yours for a talk at MNSWF Camp and Minnebar 2011. A write up and source code is available in my blog.
    http://www.ctyeung.com/wordpress/

    The advantage of an html slide show is that one can include all types of content, video, flash apps, html, etc.

    In addition to the slideshow, a colleague and I had the idea of advancing the slideshow features by adding SWF to SWF communication. This will allow interactive slide show ! i.e. drawing on a slide, interact with the flash app in the current slide, or pause, scrub video in the slide!

    So what do you think ? Maybe an opportunity to collaborate ?

    CT

  • http://http//aykak.com aykak

    Nice Tuts and great But too bad source is only available for premuim :( anyways the guid is enough ..

    thanks

  • http://thedevelopertuts.com Bratu Sebastian

    Great ideea! I was thinking of a framework for making presentations with jquery too. :)

  • http://www.sstudio.me Web dizajn Crna Gora

    I need this. Thanks

  • Tekku

    For me in Chrome Dev it doesn’t work right :( I have been checking and re-checking the code all morning, the thing loads the back ground, and in the address bar the address changes from /index.html to /index.html#slide-1 and keeps changing the right way i think, but nothing loads, i have text in all the html files and nothing :(

    Can you help me out?

    Cheers and thanks in advance!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Are you testing on your local server? If so, try using Safari.

      • Tekku

        Ok i was not testing in my local server, but i will try once i get home, i was just testing with a bunch of browsers and didn’t work LOL was thinking i did something wrong, maybe forgot that i needed the local server LOL

      • Tekku

        Ok thank you for your help, you where right, i forgot to test it on my localserver :P

        Sorry and thanks once again :)

  • http://www.rickgrossman-blog.com D. Lukow

    This is a great way to create a presentation. There are other methods but I appreciate the thought that went into it.

  • Athtar
  • http://themeforest.net/user/hayatbiralem Ömür Yanikoglu

    Nice tutorial, thanks :)

  • http://www.jguiss.com Créer un site de rencontre

    +1 for this tutorial !

  • naser abbasi

    tanks .very perfect for me.

  • http://joseph.yy.blog.163.com Puriney

    I’ve downloaded the sources, but how to put all single slide into one file, let’s say “presentation.html” which functions like the real slides?

    Or, could you tell me how to see the slide effect ? In the “slide” folder, the four html files looks like plain texts.

  • Carlo

    just to point to other similar tool: in this case a compiler from markdown to html5 presentation: landslide on github

    https://github.com/adamzap/landslide

  • http://www.krupar.net krupar

    Nice tutorial, but no demo :-(
    Your Article should be called “How to Create Presentation Slides with jQuery, HTML and CSS”

  • http://adeveloper.org Hossein Baghayi

    Hello,
    In linux/Gnu systems because file names are sensitive for the uppercase of lowercase of the file/folder name and, this makes a problem for this presentation,

    The problem is that the Slides folder in this presentation starts with capital letter but in the source files it is linked to the lowe case one (slides),

    Please solve it and then it will work for some developers,

    I hope this might help,

  • http://neatinfo.com jwzumwalt

    The key press does not work using Win7-IE9-Logitech cordless keyboard :(

  • http://www.nzbload.com Usenet Download Free

    Wow, this paragraph is nice, my younger sister is analyzing these things, so I am going to let know her.

  • http://www.html5bydemo.com bowie

    Cool I’m looking of this to create my HTML5 presentation. I’m thinking using HTML5 and css3 instead webkit.

  • leming

    dont forget to run chrome with key
    chrome.exe –allow-file-access-from-files
    otherwise it want let you to get access to localfilesystem

    firefox with firebug is useless couse firebug just jump on functions names dont wanna stop on each statemet.

    except this nice tut

  • Daniel

    Uhm can anyone give me the complete codes needed? Im a little confused. Been trying to create presentations using html5 cause they gave me this assignment. ive been trying and looking for tutorials all week. please, can anyone give a detailed info about the css and js? I really dont get it. Where do i put the codes? Whats style.css? script.js? Is this where i put the final javascript you mentioned? Thanks alot. Hoping for an early response.