Статьи

Как создать презентационные слайды с помощью HTML и CSS

Когда я проанализировал различные части программного обеспечения, предназначенные для создания слайдов презентации, мне пришло в голову: зачем изучать еще одну программу, если вместо этого я могу использовать инструменты, с которыми я уже знаком? Немного повозившись, мы можем легко создавать красивые презентации с помощью HTML и CSS. Я покажу вам, как сегодня!

Прежде чем мы начнем, давайте продолжим и создадим нашу структуру папок; это должно быть довольно просто. Нам понадобится:

  • index.html
  • CSS / style.css
  • JS / scripts.js
  • IMG /
  • слайды /

Простой базовый шаблон. Ваши slides/ каталог могут пока оставаться пустыми. Мы скоро заполним это.


Давайте начнем с создания базовой разметки для нашей страницы презентации. Вставьте следующий фрагмент в файл index.html .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<!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>

Выше у нас есть некоторые чистые, HTML5 совершенства. Больше никаких атрибутов type в нашем script и элементах link , короткого DOCTYPE , смехотворно простого тега meta charset и т. Д.


Метод load() — это метод AJAX, который загружает данные с вашего сервера и вставляет возвращенный HTML-код в выбранный элемент.

Теперь вам может быть интересно, как мы будем работать с каждым слайдом. У нас есть несколько вариантов здесь. Хотя мы могли бы обернуть каждый слайд в отдельный div и поместить массивный блок HTML в контейнер #slides , мой инстинкт заключается в том, что это сделает процесс редактирования отдельных слайдов более трудоемким, так как тогда нам придется искать все это. разметка для слайда, который нам нужен.

Вместо этого для этого урока я решил поместить каждый слайд в свой собственный файл .html . Затем мы можем использовать метод load() jQuery для добавления каждого слайда и добавления их в наш контейнер.

Создайте несколько пронумерованных HTML-файлов и поместите их в каталог slides/ , например, так:

  • слайды /
    • 0.html
    • 1.html
    • 2.html
    • 3.html
    • 4.html

В каждом из этих файлов мы вставим разметку для вашего желаемого слайда. В качестве примера давайте вместе создадим слайд «Обо мне».

1
2
3
4
5
6
7
8
9
<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>

Не стесняйтесь смешивать и сочетать, как вы хотите.


Прежде чем мы сможем сосредоточиться на стилизации нашей презентации, нам нужно load эти слайды в наш документ с помощью jQuery. Но вместо того, чтобы создавать кучу глобальных переменных и методов, мы будем хранить все в объекте, который называется Slides .

1
2
3
var Slides = {
 
};

Затем процесс загрузки этих слайдов в наш документ будет сохранен, скажем, в loadContent() . Давайте создадим это сейчас.

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

Чтобы загрузить все слайды в каталоге slides/ , нам сначала нужно узнать, сколько слайдов существует; тем не менее, JavaScript не имеет доступа к файловой системе. Вместо этого мы передадим общее количество слайдов, когда начнем работу с нашим объектом.

Имея это в виду, давайте создадим метод init() который будет своего рода контроллером. Этот метод также получит аргумент, который указывает общее количество слайдов. Затем он будет присвоен свойству объекта Slides .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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() {
 
   }
}

Так-то лучше. Но, конечно, ни один из этого кода не будет выполняться, пока мы не вызовем метод init() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
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;
Slides.init( 6 );

Давайте сначала попробуем загрузить эти слайды — и затем мы будем постепенно улучшать наш код по мере продолжения.

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

Выше мы создаем новый элемент div для общего количества слайдов, которые мы указали. Каждый div будет иметь id #slide-n . После того как мы создали каждый элемент, мы загружаем содержимое нужного слайда, который мы сохранили в каталоге slides/ . Как только этот блок HTML был получен с сервера, мы добавляем созданный div в контейнер #slides .

Этот код действительно будет работать, но мы можем сделать лучше. Есть несколько проблем с кодом выше:

  • Обход: для каждого слайда мы #slides DOM для элемента #slides . Это расточительно и ненужно. Кроме того, поскольку мы, безусловно, будем работать с этим #slides контейнера #slides в нашем проекте, имеет смысл сохранить его как свойство нашего объекта Slides . Мы сделаем это в ближайшее время.
  • Reflows: этот код создаст любое количество страниц, которые могут увеличить время загрузки нашей страницы. Вместо того, чтобы вызывать метод appendTo() десятки раз (или в нашем случае: шесть), давайте ограничим наши рефлокирования одним.

Давайте сначала исправим проблему обхода.

1
2
3
4
5
6
7
var Slides = {
   totalSlides : »,
   container : $( «#slides» ),
 
   init() { … },
   loadContent() { … }
}

Таким образом, мы ищем в нашем документе элемент #slides ровно один раз, а не снова и снова.

Если вы все еще не уверены в преимуществах, подумайте о том, чтобы прыгнуть в бассейн и найти монету. Каждый раз, когда вы вызываете $('#slides') , движок JavaScript запрыгивает в пул и снова ищет эту монету. Снова и снова. Но если мы вместо этого сохраняем местоположение переменной $('#slides') в переменной, ей никогда не придется возвращаться в этот пул. Он помнит, где находится эта монета.

Далее мы позаботимся об этой досадной проблеме с оплавлением. Есть два способа ограничить наши возвраты. Мы рассмотрим оба метода.

Фрагменты документов JavaScript позволяют нам хранить фрагменты HTML. Затем, вместо того, чтобы обновлять DOM несколько раз, как мы делали раньше, с помощью этого метода, мы вызываем appendTo() только один раз.

Обратитесь сюда для получения дополнительной информации о фрагментах документов.

01
02
03
04
05
06
07
08
09
10
11
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);
}

Обратите внимание, что мы больше не вызываем appendTo() внутри оператора for . Вместо этого он вызывается только один раз. Единственное примечание, которое стоит упомянуть, это раздел [0] после вызова метода load() . Зачем нам это нужно?

Храните фрагменты документа — ждите его — фрагменты HTML или элементы. Однако когда мы вызвали метод load() выше, объект jQuery, конечно же, возвращается. Это не совместимо. Вместо этого мы хотим отфильтровать сам элемент HTML. Мы можем сделать это, используя [0] или метод get() . Любой вариант подойдет.

Наш второй вариант — скрыть элемент контейнера. Когда мы делаем это, независимо от того, сколько раз вы добавляете новые элементы к этому элементу, никакие дополнительные повторы страницы не вступают в силу … потому что элемент скрыт! Это хороший маленький трюк в поясе инструментов.

01
02
03
04
05
06
07
08
09
10
11
12
13
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();
}

Так что любой из этих двух вариантов подойдет просто отлично. Выберите тот, который вы предпочитаете.

Если вы сейчас просматриваете наш проект в браузере — при условии, что вы добавили несколько пустых слайдов в каталог slides/ — вы увидите что-то вроде:

Загруженный контент

Если мы используем такой инструмент, как Firebug или инструменты разработчика Chrome, мы увидим, что, как и ожидалось, слайды были вставлены в div контейнера #slides .

Исходный код

Наш следующий шаг происходит в нашей таблице стилей. Здесь мы сосредоточимся как на эстетике, так и на функционировании. Чтобы каждый слайд переводился слева направо, нам нужно быть умным с нашим стилем.

Мы начнем с создания нашего холста. Если вы вернетесь к нашей разметке …

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<!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>

… наш упаковочный контейнер для нашего проекта — это div с class wrap . Мы предоставим ширину 1180px и 1180px ее по центру на странице.

1
2
3
4
5
.wrap {
   margin: auto;
   width: 1180px;
   overflow: hidden;
}

Далее, поскольку каждый слайд должен переводиться горизонтально, нам нужно сделать наш div как можно более широким.

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

Теперь самое интересное и немного страшное. Подумайте о традиционном слайде презентации. Разве контент не располагается вертикально и горизонтально по центру слайда или страницы? Абсолютно. Поскольку мы имеем 100% контроль над этим проектом, нам не нужно беспокоиться о совместимости браузера. Поскольку слайды будут использоваться только нами (во время нашей презентации), мы можем адаптировать их к нашему любимому браузеру. Таким образом, мы можем использовать множество интересных новых функций, которые еще не вошли во все браузеры, такие как Flexible Box Model .

Мы начнем с определения размеров каждого слайда, плавания каждого слайда и предоставления некоторого пространства для дыхания (поля).

1
2
3
4
5
6
7
#slides > div {
    height: 600px;
    width: 1180px;
    float: left;
    margin-right: 200px;
    text-align: center;
}
Плавающие слайды

Но помните: этот текст должен быть вертикально центрирован. Гибкая коробочная модель на помощь!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
#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;
}
Добавление flexibox

Далее мы добавим хороший радиальный градиентный фон к нашим слайдам. Честно говоря, радиальные градиенты CSS все еще сбивают меня с толку. Я редко помню синтаксис. Поэтому я обычно либо делаю заметки о градиентах в дикой природе, которые мне нравятся, либо использую любой из различных генераторов градиентов в сети, чтобы сделать мои. Не стесняйтесь делать то же самое.

1
2
3
4
5
6
7
8
9
body {
    background-image: -webkit-gradient(
        radial,
        50% 50%, 0,
        50% 50%, 1000,
        from(rgba(245,245,245,1)),
        to(rgba(100,100,100,1))
    );
}
Применение радиального градиента

И с этим у нас есть наша основная структура на месте. На этом этапе я призываю вас разрабатывать заголовки, возможно, создавать минимальную сетку и все остальное, о чем вы можете подумать. Мы закончим наш минимальный стиль, работая над типографикой.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
#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;
}

Удивительно, чего мы можем достичь, когда настраиваем интервал между буквами и применяем некоторые умные тени для текста! Выглядит намного лучше сейчас!

Бизнес WordPress Theme Design
Пользовательский текст

Следующим шагом в этом проекте является управление процессом перехода от слайда к слайду. Естественно, поскольку на месте нет кнопок, мы должны вместо этого прислушиваться к нажатию клавиш со стрелками влево или вправо. Мы будем хранить эту функциональность в новом методе keyPress нашего объекта Slides .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
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 ) ?
         }
      });
   }
 
}

jQuery предоставляет полезный метод keydown , который подключает необходимые прослушиватели событий. Это означает, что переданная функция обратного вызова будет работать для каждой нажатой клавиши; однако нас интересуют только правая и левая клавиши со стрелками или коды клавиш 39 и 37 соответственно. Если нажата одна из этих клавиш, мы сначала отменяем действие по умолчанию клавиши со стрелкой, а затем вызываем метод next() или prev() , в зависимости от того, какая клавиша была нажата.

Давайте теперь поработаем над тем методом next() который мы вызвали выше. Когда этот метод вызывается, ему нужно выполнить несколько операций:

  • Обновите хеш в URL. Таким образом, мы можем легко отправлять ссылки на конкретные слайды.
  • Анимируйте слайд влево и покажите следующий слайд в последовательности.

Но прежде чем двигаться вперед, как мы узнаем, сколько нужно перевести слайд? Это должна быть ширина контейнера #slides , но мы должны стараться не кодировать это значение в нашем JavaScript, если это не нужно. Причина этого заключается в том, что, если мы позже решим изменить размеры нашего холста, нам также нужно будет покопаться в нашем файле JavaScript и обновить размеры. Вместо этого давайте динамически определим, какова ширина и поля контейнера.

Давайте добавим новое свойство к объекту Slides , которое называется slideWidth . Однако мы не сможем определить ширину слайдов, пока они не будут вставлены в DOM, с помощью метода loadContent .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
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 — эта линия выглядит немного страшно!

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

Но не волнуйся; это действительно довольно просто. Мы обновляем свойство Slides.slideWidth и делаем его равным ширине слайда плюс его поле справа. Поскольку извлечение значения margin-right для слайдов (в частности, для первого) также вернет px , нам нужно отрезать его, используя функцию parseInt .

Чтобы прояснить необходимость в приведении, предполагая, что правильное значение маржи равно 200px

1
console.log ( typeof each.css(‘margin-right’).split(‘px’)[0] );

И теперь мы динамически определяем ширину наших слайдов. Вернемся к нашему методу next() ; нам всегда нужно отслеживать расположение наших слайдов. Таким образом, когда мы переходим со слайда 4 на 5, мы точно знаем, сколько нужно перевести слайд. Мы будем хранить это значение в новом свойстве: translateAmount .

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

Давайте разберемся с этим. Когда мы нажимаем клавишу со стрелкой right в первый раз, мы устанавливаем свойство translateAmount равным slideWidth или, в нашем случае, 1380px . Если мы снова нажмем right , это значение будет обновлено до 2760px .

В этом next методе мы также должны обновить значение хеша в нашем URL, например example.com/index.html#slide-1 , затем example.com/index.html#slide-2 и т. Д. Для этого мы необходимо отслеживать текущий слайд, который просматривает читатель.

01
02
03
04
05
06
07
08
09
10
11
currentSlide : 0,
 
next : function() {
   Slides.translateAmount -= Slides.slideWidth;
   Slides.updateHash( ++Slides.currentSlide );
},
 
updateHash : function() {
   location.hash = ‘#slide-‘ + Slides.currentSlide;
}

Обратите внимание, что мы увеличиваем значение currentSlide на единицу, прежде чем передать его в функцию updateHash . Это уместно; когда мы нажимаем клавишу со стрелкой right , хэш должен обновляться до следующего слайда, а не до текущего.

Наконец, теперь, когда мы отследили все необходимые значения, мы можем анимировать слайды.

01
02
03
04
05
06
07
08
09
10
11
next : function() {
   Slides.translateAmount -= Slides.slideWidth;
   Slides.updateHash( ++Slides.currentSlide );
   Slides.animate();
},
 
animate : function() {
   Slides.container
      .children()
         .css( ‘-webkit-transform’, ‘translateX(‘ + Slides.translateAmount + ‘px)’);
}

Для лучшей производительности мы будем использовать CSS3 для перевода слайдов. Чтобы это не было мгновенным переводом, нам нужно обновить наш CSS-файл:

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

Метод prev будет действительно похож на next , за исключением нескольких вещей.

1
2
3
4
5
6
7
8
prev : function() {
  // No more left to go back.
   if ( Slides.translateAmount === 0 ) return;
 
   Slides.translateAmount += Slides.slideWidth;
   Slides.updateHash( —Slides.currentSlide );
   Slides.animate();
}

На этот раз, когда мы возвращаемся к началу слайдов, нам нужно изменить значения translateAmount и hash. Кроме того, мы должны учитывать возможность того, что пользователь нажимает клавишу со стрелкой left даже когда он находится на самом первом слайде. Если это так, мы не должны ничего делать, потому что ничего не осталось для перехода!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 ) ?
         }
      });
   },
 
   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;
Slides.init(6);

Все закончено. Это было не так сложно, как только мы немного покопались! Самое замечательное то, что, если вы просматриваете презентацию в действительно высоком или низком разрешении, вы можете просто увеличить или уменьшить масштаб несколькими щелчками мыши, чтобы компенсировать это, нажав Command или Control +- . Дайте мне знать, если у вас есть какие-либо вопросы или рекомендации!

Бизнес WordPress Theme Design
Пример слайда
Лицензионные слайды