Всплывающее окно на 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. Написано просто и доступно. Может быть позже выложу свой вариант

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