Всплывающее окно на HTML/CSS/jQuery

На многих сайтах в Сети можно встретить так называемые всплывающие окна (англ. popup). Таким окнам легко найти применение — это всевозможные формы обратной связи, регистрации, корзины, реклама чего-либо и т.д. и т.п. В этой статье займемся реализацией всплывающего окна на простом примере.

Демо

Содержание статьи

  1. Разметка
  2. Полупрозрачный фон
  3. Скрипты jQuery

Последнее обновление — 24.06.2013.

Разметка

Для примера я взял несложный макет premiumpixels.com. Вы также можете найти любые другие варианты, набрав в Гугле «popup window free psd» или что-то в этом роде, ну или нарисовать свой вариант, если вы хоть немного дизайнер. Это не важно.

Так как окно у нас будет простое, сверстаем его обычным HTML (хотя можно сделать динамически через JS/jQuery). Мое окошко состоит из заголовка, текста и двух кнопок, HTML-код такой:

<div id="popup" class="popup">
  <h2 class="popup-title">Are You Sure?</h2>
  <div class="popup-content">
    <p class="popup-warning">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
    <div class="popup-choice">
      <button id="btn-yes" class="btn-yes">Yes</button>
      <button id="btn-no" class="btn-no">No</button>
    </div>
  </div>
  <div class="btn-close"></div>
</div>

На мой взгляд неплохая разметка — используются семантичные элементы и классы, идентификаторы добавлены для работы со скриптами. Если не планируется поддержка браузеров Internet Explorer ниже 8-ой версии, <div class="btn-close"></div> можно заменить псевдоэлементами :after/:before.

Добавим немного стилей CSS для нашего окна:

Пример всплывающего окна
Всплывающее окно

По отношению к старым браузерам Internet Explorer применим принцип graceful degradation.

Полупрозрачный фон

Приступим к созданию затемняющего полупрозрачного фона на всю страницу. Впоследствии организуем его появление вместе со всплывающим окном — это будет выглядеть весьма эффектно.

Добавим в конец документа перед закрывающим тегом </body> пустой элемент <div> с id и class:

<div id="hide-layout" class="hide-layout"></div>

Растянем его на всю ширину и высоту документа, добавим прозрачность, фиксированное позиционирование и большой z-index для перекрытия всех элементов на странице — больший z-index должен быть только у всплывающего окна:

.hide-layout {
  background: #000; /* фон */
  bottom: 0;  /* координата снизу */
  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50); /* прозрачность для IE */
  height: 100%; /* высота на всю страницу */
  opacity: 0.5;  /* прозрачность слоя */
  position: fixed; /* фиксируем элемент на странице*/
  top: 0; /* координата сверху */
  width: 100%; /* ширина на всю страницу */
  z-index: 998; /* z-index для перекрытия остальных элементов */
}

Обратите внимание на то что одним из ключевых свойств здесь является position: fixed, чтобы темный фон прокручивался при скролле страницы. Поэтому такой способ не будет работать в IE6 — он это свойство не поддерживает и придется обращаться за помощью к JS. Но ведь мы уже оставили в покое этот браузер, верно?

И еще момент — кроссбраузерную прозрачность далее я реализую через jQ, в IE был обнаружен небольшой недочет при показе скрытого блока.

Результат проделанной работы, пока без скриптов:

Смотреть пример

Скрипты jQuery

Базовый функционал

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

Кликните здесь для открытия всплывающего окна

Почему я не использую тег ссылки <a> в данном случае? Потому что использование нейтрального элемента грамотнее, подробнее читайте здесь — «Не все то ссылки, что подчеркнуто».

Начнем скриптовать наше всплывающее окно:

<!-- подключили jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
  $(function() {
    // здесь последующий код...
  })
</script>

Сперва скроем окно и добавим кроссбраузерную прозрачность контейнеру с фоном:

$('#popup').hide();
$('#hide-layout').css({opacity: .5});

Конечно можно скрыть необходимые элементы CSS-свойством display: none, но при выключенном JS мы не сможем открыть окно. Хотя все зависит от поставленной задачи.

Для удобства пользователя можно добавить в разметку сообщение тем, у кого выключен JS, что-то вроде этого:

<!-- сообщаем пользователю -->
<noscript>Для корректной работы страницы включите JavaScript в настройках браузера</noscript>

Примечание: а слой с фоном все-таки скрываем через CSS, иначе при выключенном JavaScript он все перекроет.

Следующий шаг — повесим обработчики на событие click элементам #click-me для показа окна и #btn-close, #hide-layout, соответственно для скрытия. Воспользуемся готовыми методами fadeIn/fadeOut:

$('#click-me').click(function() {
  $('#hide-layout, #popup').fadeIn(300);  // плавно показываем окно/фон
})
$('#btn-close, #hide-layout').click(function() {
  $('#hide-layout, #popup').fadeOut(300); // плавно скрываем окно/фон
})

Также необходимо повесить обработчики на кнопки выбора, при клике производим какое-то действие, после выполнения снова скрываем окно:

// повесили обработчики на кнопки
$('#btn-yes, #btn-no').click(function() {
  alert('Выполнили какое-то действие, затем скрываем окно...');
  $('#hide-layout, #popup').fadeOut(300);
})

Как видите, с использованием jQuery все становится просто до безобразия. Даже ваша бабушка разберет этот код.

Расширенный функционал — центрирование окна по центру страницы

Теперь все работает как надо, но сделаем еще кое-что, а именно центрируем окно посередине страницы на jQ. Опять же можно обойтись обычным CSS, но JS/jQuery позволяет сделать все гибче — динамически высчитаем размеры окна и элемента и подставим нужные координаты, оформив все это простенькой функцией:

// функция принимает элемент, который необходимо центрировать
function alignCenter(elem) {
  elem.css({ // назначение координат left и top
    left: ($(window).width() - elem.width()) / 2 + 'px',
    top: ($(window).height() - elem.height()) / 2 + 'px'
  })
}

Особенного внимания заслуживают значения координат left и top, в которых мы выссчитываем ширину/высоту окна браузера, отнимаем от нее ширину/высоту принимаемого элемента и делим полученные значения на два — это и будет центр страницы. В качестве параметра функции добавим элемент #popup. Осталось внести изменения в код — вызовем функцию в начале скрипта, а также повесим ее на обработчик resize (изменение размеров окна) объекта window, чтобы окошко всегда находилось по центру. Полный код:

$(function() {
  $('#popup').hide(); // скрыли фон и всплывающее окно
  $('#hide-layout').css({opacity: .5}); // кроссбраузерная прозрачность
  alignCenter($('#popup')); // центрировали окно
  $(window).resize(function() {
    alignCenter($('#popup')); // центрирование при ресайзе окна
  })
  $('#click-me').click(function() {
    $('#hide-layout, #popup').fadeIn(300); // плавно открываем
  })
  $('#btn-close, #hide-layout').click(function() {
    $('#hide-layout, #popup').fadeOut(300); // плавно скрываем
  })
  $('#btn-yes, #btn-no').click(function() {
    alert('Выполнили какое-то действие, затем скрываем окно...'); // сделали что-то...
    $('#hide-layout, #popup').fadeOut(300); // скрыли
  })
  // функция центрирования
  function alignCenter(elem) {
    elem.css({
      left: ($(window).width() - elem.width()) / 2 + 'px', // получаем координату центра по ширине
      top: ($(window).height() - elem.height()) / 2 + 'px' // получаем координату центра по высоте
    })
  }
})

Итоги

Проверено

  • Internet Explorer 7+
  • Opera
  • Firefox
  • Chrome
  • Safari

Обновление 24.06.2013

По замечанию читателей для всплывающего окна не был учтен скроллинг документа. Чтобы заставить перемещаться наше окошко вверх-вниз при прокрутке, нужно просто добавить элементу .popup свойство position: fixed.

Спасибо пользователям Андрей и ebragim.

Рейтинг статьи

Похожие статьи

Комментарии читателей

  1. Спасибо очень хорошая статья. Вы показали очень интересный способ для отображения всплывающего окна.

  2. Элл:

    А почему если сделать вывод нескольких оконо, то центрируется только первое, а остальные прижимаются куда то сверху?

  3. Здравствуйте! Подскажите, пожалуйста. Хочу добавить на свой сайт кнопку «Телевизор». Собственно, после нажатия на эту кнопку ‘выпадало’ всплывающие окно с телевизором (Не переходя на какую-то страну, т.е оставаясь на текущей).

  4. Dirada:

    Privet, mojet kto pomojet… u menya vsplyvayushee okoshko pokazyvaet kakie imenna vnasilis uje. Sdelala kartinku chtob udalat ne nujnye imena. No pri klike na kartinku udalit imena ne kak ne poluchaetsa. Pomogiteeeee

  5. Я прописала разные id и в скрипт, соответственно, тоже:

    $('#click-me').click(function() {
    $('#hide-layout, #popup').fadeIn(300);
    })
    $('#clickme').click(function() {
    $('#hide-layout, #popup').fadeIn(300);
    })

    Но что-то это как-то не изящно… :)

    • Добавьте не id, а класс элементу:
      <span class="click-me">Открыть</span>
      И скрипт соответственно подправьте

  6. А что нужно сделать, чтобы можно было вызывать это окошко из разных мест на странице? Из двух элементов с одним id=»click-me» второй не работает.

  7. Endryu:

    Спасибо, гуглил, однако получалось странно либо у меня отправляется код (сообщение) либо попап окно) два в одном ну вот как ни крути не получалось. :) На самом деле решение нашел (слава богу есть кодер очень опытный в друзьях), помог объяснил, поэтому если будут у кого вопросы пишите я попробую выдавить из своей головы чем он помог)

  8. Endryu:

    Привет. Хотел узнать. Я делаю всплывающее окно. Оно отлично получается. но не понимаю. Как сделать вдобавок чтобы были поля для добавки информации (к примеру номер телефона) + при нажатии отправить форма отправлялась на почту и появлялось это окно. у меня получается либо это окно либо отправка на почту. никак не то что я хочу(

  9. muss:

    Ребята подскажите как сделать всплывающее окно на сайте для лайков в фейсбуке? Заранее спасибо….

  10. Приветствую, Вадим ) А можно для тех, кто не до конца понимает, как всё сделано, выложить исходники? Просто сами файлы. У вас получилось красиво, а у меня, например, не получается сделать такое )

  11. Владимир:

    Здравствуйте!
    Где в статье стили css?
    Вашим статьям не хватает исходников =) Спасибо.

  12. ebragim:

    Андрей, это можно сделать гораздо проще: сделайте для всплывающего окна position: fixed
    D такие окна как правило не выводят очень много информации, так что пусть оно висит как и затемнённая подложка всегда в центре. А если хотите вывести очень много информации сразу — лучше оформить в отдельную страницу. Или скрывать информацию по мере ввода, например окно чекаута магазина: спросить у пользователя личные данные, и скрыть, открыть второе окно итд…

  13. Андрей:

    Спасибо, взял за основу Ваш скрипт. Однако при реализации выяснилось, что не учтен скроллинг в функции центрирования. Поэтому, пришлось немного изменить расчет координаты по высоте:

    top: $(document).scrollTop() + ($(window).height() — elem.height()) / 2 + ‘px’

    ну и как следствие, чтобы вычислялся scrollTop в момент вызова окна, пришлось перенести выполнение центрирования и центрирование при ресайзе на обработчик ‘#click-me’. На тот же обработчик добавил еще одну строку, чтобы не скролилось при работе #popup:

    $(«body»).css({«overflow»:»hidden»});

    ну и отмену на обработчик ‘#btn-close, #hide-layout’:

    $(«body»).css({«overflow»:»auto»});

    А вообще-то, для меня, как для новичка, материал изложен очень доступно! Огромное спасибо автору!

    • Андрей, спасибо за исследование и за то что поделились результатами, надо будет дополнить статью. Появились идеи, как реализовать окно еще более гибко, будет время — добавлю.

  14. Спасибо, клевое окошко :)

  15. Igor:

    Спасибо за статью!
    Подскажите пжлст как сделать несколько окон, чтобы можно было по отдельности обрабатывать?

    • Добрый день, Игорь! Мой пример достаточно простой и подходит для создания одного, максимум двух окошек в документе. Можно сделать более расширенный вариант в виде плагина для jQuery или написать свой сценарий на чистом JS. Различие в том, что в этом случае мы будем генерировать HTML-код окон с помощью JS, с применением различных параметров. Вот например хорошая грамотная статья, как это реализовать на jQuery — http://forum.htmlbook.ru/index.php?showtopic=33874. Написано просто и доступно. Может быть позже выложу свой вариант

Добавить комментарий