The Modal — правильные модальные окна

в 9:59, , рубрики: javascript, jquery, интерфейсы, модальные окна, метки: , , ,

Очень часто модальные окна и диалоги делаются при помощи плагинов jQuery. Например, SimpleModal или jqModal. К сожалению, все они, в варианте по умолчанию, работают неправильно.

Что же такое «правильно»?

Если окно модальное, то оно обязано быть модальным:

  1. Пользователю нельзя позволять прокручивать страницу под ним.
  2. При этом, если содержимого в модальном окне очень много, нужно позволить прокручивать содержимое.

По этому принципу работает просмотр фото в Facebook и Вконтакте и, я считаю, что для модальных окон это правильный вариант.

Чтобы не мучать вас заранее деталями реализации, покажу сначала демо плагина jQuery: http://rmcreative.ru/playground/modals_plugin/demo.html.

Ну а теперь немного про реализацию.

Идея достаточно проста. В открытом состоянии разметка получается примерно вот такая:

<html>
  <head>
    ...    
  </head>
  <body class="lock">
    <div class="shim">
      <div class="modal">
        ...
        <h1>Hi, I'm the modal demo.</h1>
        ...
      </div>
    </div>
    ...
  </body>
</html>

К ней применяется CSS:

/* Данный класс навешивается на контейнер при открытии модального окна. Для нормальных браузеров это body, для стырах IE — html */
.lock {
    /* убираем скроллбары с основнового содержимого страницы */
    overflow: hidden;
}

/* ширма (полупрозрачное затенение под модальным окном) */
.shim {
    /* фиксируем, растягиваем на весь доступный экран */
    position: fixed;
    bottom: 0; left: 0; top: 0; right: 0;

    /* если в модальном окне много содержимого, показываем скроллбар */
    overflow: auto;

    /* однопальцевый скролл для iPad*/
    -webkit-overflow-scrolling: touch;
}

/* фикс для странностей в iPad */
.shim > * {
    -webkit-transform: translateZ(0px);
}

/* декоративная часть ширмы: делаем полупрозрачной и чёрной */
.shim {
    background: rgba(0,0,0,0.5);

    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7F000000,endColorstr=#7F000000); /* IE6–IE8 */
    zoom: 1;
}

Вот и всё. Остаётся завернуть в удобный для использования плагин jQuery и добавить плющем вроде закрытия по ESC. У меня получился плагин вот с таким API:

$.modal().open({
    onOpen: function(el, options){
        $.get('http://example.com/', function(data){
            el.html(data);
        });
    }
});

Забрать его можно на github.

На данный момент имеется некоторое количество нехорошестей, которые, надеюсь, поможет исправить сообщество:

  • Скролл клавиатурой в FF скроллит страницу вместо модального окна.
  • На iPad скролл работает не очень стабильно (иногда скроллит страницу).
  • Скролл нажатием средней кнопки мыши работает неверно.
  • Открытие модального окна сдвигает страницу в том случае, если появляется или убирается скролл.

Конструктивная критика и советы очень приветствуются.

Автор: SamDark

* - обязательные к заполнению поля