18 июля (обновлено 18 июля)

Модальные окна / popup

Продолжая серию статей "для начинающих", хочу рассказать про верстку модальных окон.

На всякий случай поясню, что под модальными (popup) окнами понимаются слои, которыенакладываются на все остальные и требуют какого-либо действия от пользователя - что-то ввести, что-то подтвердить или отклонить и т.д. Тоесть функционально это либо "отдельное окно" внутри основного окна или alert\confirm окно.

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

Демо Скачать

В общем виде html-код страницы с popup_ом будет иметь вид:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>popup</title>
</head>  
<body> 
	<div id="list">	
		<!-- Наш сайт -->
	</div>
	<div class="overflow"><!-- Затемнение --></div>
	<div class="popup"><a href="#" class="close"></a></div>
</body>
</html>

Первая проблема, с которой мы столкнемся, это будет невозвожность открыть popup, который больше высоты окна браузера, если мы используем фиксироованное позиционирование. Если же окно попапа меньше, то очень неприятно будет выглядеть скролл фона, при скроле окна.

Эти проблемы особенно актуальны пр отображении окна на экране смартфона, поэому предлагаю следующее решение: мы будем фиксировать не наше модальное окно, а блок со всем содержимым сайта, а модальное окно будет позиционировано абсолютно:

/*Затемнение */
.overflow{
	background: rgba(0, 0, 0, 0.7);
	position:fixed;
	top: 0px;bottom: 0px;
	left: 0px;right: 0px;
	z-index:100;
	display:none;
}
/* модальное окно */
.popup{
	position:absolute;
	z-index:101;
	background: #ffffff;
	width: 600px;
	min-height: 300px;
	margin-left: -300px;
	top: 10%;
	left: 50%;
	display:none;
}
.popup .close{
	position:absolute;
	top: 10px;
	right: 10px;
	display:block;
	width: 17px;
	height: 17px;
	opacity: 0.5;
	background: url(../img/close.png) no-repeat center;
	-webkit-transition:opacity 0.5s;
	-moz-transition:opacity 0.5s;
	transition:opacity 0.5s;
}
.popup .close:hover{
	opacity: 0.8;
}

 А теперь давайте приступим к обработке событий открытия и закрытия нашего окна:

var win_top = 0;
$(document).ready(function(){
	
	// открываем модальное окно при клике по контенту
	$('#list').click(function(){
		popup_open('#myPopup');
	})
	
	// открываем модальное окно сразу при загрузки страницы
	popup_open('#myPopup');
	
	// Добавляем обработчик закрытия модального окна
	$(document).on('click', '.popup .close, .overflow', function(){
		popup_close()
		return false;
	})
	
})
function popup_open(selector){
	if (selector.length){
		win_top = $(window).scrollTop();
		$('#list').css({
			'position'	: 'fixed',
			'left'		: '0',
			'right'		: '0',
			'top'		: '0',
			// Добавляем смещение, чтобы на фоне была именно та часть, что просмаривал пользователь
			'margin-top': '-'+win_top+'px' 
		})
		$('.overflow,'+selector).fadeIn();
	}
}
function popup_close(){
	$('.overflow, .popup').hide();
	$('#list').css({
		'position'	: 'static',
		'margin-top': '0px'
	})
	// Возвращаем скролл на место
	$(window).scrollTop(win_top);
}

Здесь в качестве параметра передается селектор (id) попапа. Такой подход удобен, если на странице есть несколько попапов, которые вызываются кликом по ссылкам. тогда в атрибуте href ссылки можно прописать id блока, который нужно открыть в виде якоря:
href="#myPopup" и при обработки клика смотреть значение данного атрибута

var id = $(this).attr('href');

 И остался последний штрих - мобильная адаптация нашего модального окна. Здесь все совсем просто - при достижении определенной ширины меняем ему выравнивание и даем динамически расчитывать размеры:

@media screen and (max-width: 650px) {
	.popup{
		width: auto;
		margin-left: 0px;
		top: 40px;
		left: 10px;
		right: 10px;
	}
}


Демо Скачать