Блог для начинающих веб разработчиков. HTML, СSS, Jquery, Drupal и другое.

→ Адаптивная вёрстка. Пример вёрстки макета.

Опубликовано: 04 июля 2014

Приветствую всех читателей блога HeavenWeb. Сегодня в блоге я приведу пример так называемой адаптивной вёрстки, а также, в качестве примера я покажу как сверстать простой макет с учётом адаптивности под разные разрешения экрана.

Если говорить простыми словами, под адаптивной или «отзывчивой» вёрсткой понимают такое расположение блоков и элементов, которое подстраивается под размер и разрешение экрана устройства, при помощи которого страница открыта.

С ростом популярности планшетных пк и смартфонов, от веб мастеров требуется поддержка новых форматов отображения сайтов, и соответственно новых разрешений экранов, в которых эти сайты открываются.

Самая критичная величина — это ширина окна браузера. Минимально, на самых бюджетных смартфонах это 240-360px, но в большинстве случаев всё же 480 px и выше. И это более чем в два раза меньше, чем стандарт мониторов с шириной 1024 пикселей.

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

Этого можно достичь на счёт медиа запросов CSS, а так же стилевых свойств ограничивающих минимальную и максимальную ширину и высоту в заданных пределах.

Но всё лучше показать на примере. Давайте сверстаем простой адаптивный макет с минимумом элеменов, внешний вид готового примера можно посмотеть на демо-странице:

ДемоСкачать

Итак, наши требования к его адаптивности таковы:

  • Ширина основной части должна растягиваться на больших разрешениях, но до определенной величины, ведь слишком длинные строки не удобно читать.
  • При уменьшении ширины браузера изображения должны пропорционально сжиматься, чтобы не выходить за границы области.
  • При ширине менее 700 пикселей (минимум – планшет или смартфон с hd экраном в портретной ориентации) три блока внизу должны выстроиться друг за другом и занимать 100% ширины основного блока.
  • Так же, при этом левый сайдбар должен сворачиваться, в узкую полосу освобождая место для основной части.
  • Предусмотреть кнопку, тап по которой раскрывает и закрывает сайдбар, который теперь должен быть позиционирован над основным блоком, в виде всплывающего меню.

Начнём. Я создал файл index.html, и папки css и images, куда поместил соответственно файл стилей и вырезанные из макета картинки.

В HTML файле создадим два корневых контейнера .left_side и .wrapper соответственно для левого меню и основной части. В .left_side поместим некоторую разметку логотипа, социальных ссылок и ненумерованного списка меню.

<!DOCTYPE html>
<html>
	<body>
		<div class="left_side">
		</div>
		<a href="#" class="left_swap"></a>
		<div class="wrapper">
                </div>
	</body>
</html>

В правом основном блоке каждый пост обернём div-ом с классом .text_block, добавим текст-заполнитель с инструмента яндекс-рефераты, и изображения для примера.

В низ добавим три блока .footer_block, обернём их в общий .footer. Статьям добавим заголовки H2, H3, и в итоге получим разметку подобную этой:

<!DOCTYPE html>
<html>
	<head>
		<title>Пример адаптивной вёрстки макета. Heaven Web - блог для веб мастера.</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
		<link rel="stylesheet" href="css/style.css">
		<script src="js/jquery-2.0.3.min.js"></script>
		<script src="js/sstu_script.js"></script>
	</head>
	<body>
		<div class="left_side">
			<h1 class="logo_text">
				<a href=""><img src="images/logo.png" height="150" width="177" alt=""></a>
				<span>Блог о веб разработке</span>
			</h1>
			<div class="social_img">
				<a href="#" class="tw_icon"></a>
				<a href="#" class="go_icon"></a>
			</div>
			<div class="left_menu">
				<ul>
					<li><a href="index.html" id="link_top">Главная</a></li>
					<li><a href="index.html">Вёрстка</a></li>
					<li><a href="index.html">Jquery</a></li>
					<li><a href="index.html">Drupal</a></li>
					<li><a href="index.html">Другое</a></li>
					<li><a href="index.html">Контакты</a></li>
				</ul>
			</div>
		</div>
		<a href="#" class="left_swap"></a>
		<div class="wrapper">
			<div class="text_block">
				<h2>Из ряда вон выходящий план размещения: методология и особенности</h2>
					<p>Здесь текст с яндекс рефераты...</p>
					<img src="images/watch_dogs.jpg" alt="" class="auto_img">
					<p>Ещё некоторое кол-во текста с картинками</p>
			</div>
			<div class="footer">
				<div class="footer_block">
					<h4><a href="#">Первый заголовок</a></h4>
					<img src="images/img_min_1.png" alt="">
					<p>При этом построение бренда упорядочивает сублимированный опрос, учитывая результат предыдущих медиа-кампаний.</p>
				</div>
				<div class="footer_block">
					<h4><a href="#">Второй заголовок</a></h4>
					<img src="images/img_min_2.png" alt="">
					<p>Исходя из структуры пирамиды Маслоу, лидерство в продажах упорядочивает принцип восприятия, отвоевывая свою долю рынка.</p>
				</div>
				<div class="footer_block">
					<h4><a href="#">Третий заголовок</a></h4>
					<img src="images/img_min_3.png" alt="">
					<p>Повышение жизненных стандартов, как следует из вышесказанного, развивает формирование имиджа, не считаясь с затратами.</p>
				</div>
			</div>
		</div>
	</body>
</html>

Обратите внимание на 6 строку. Дело в том, что мобильные устройства масштабируют веб страницы для удобного просмотра, однако, нам это не нужно. Этой meta записью мы запрещаем масштабирование страницы.

Теперь займёмся стилями CSS. Оформим левый блок:

.left_side{
	background: #1d282b;
	width: 300px;
	position: fixed;
	left: 0;
	top: 0;
	height: 100%;
	z-index: 5;
}
.logo_text{
	padding: 20px 10px;
	color:#ffffff;
	font-size: 24px;
	line-height: 30px;
	font-weight: normal;
	font-family: myPTNarrow;
	text-align: center;
}
.logo_text a{
	display: inline-block;
}
.logo_text span{
	color:#72898f;
	font-size: 18px;
	line-height: 24px;
	padding: 0 10px 18px;
	text-align: center;
	display: block;
}
.left_menu{
	margin-top: 30px;
}
.left_menu ul{
	display: block;
	list-style-type: none;
}
.left_menu li{
	display: block;
	height: 30px;
	line-height: 30px;
}
.left_menu li a{
	display: block;
	line-height: 30px;
	font-size: 18px;
	font-family: myPTNarrow;
	color:#ffffff;
	text-decoration: none;
	padding-left: 60px;
}
.left_menu li a:hover{
	background: #343e41;
}
.social_img{
	text-align: center;
}
.social_img a{
	display: inline-block;
	margin: 0 10px;
	width: 30px;
	height: 30px;
	overflow: hidden;
}
.social_img a:hover{
	opacity: 0.7;
}
.tw_icon{
	background: url("../images/social.png") top left no-repeat;
}
.go_icon{
	background: url("../images/social.png") top right no-repeat;
}
.left_swap{
	display: none;/* По умолчанию блок не виден,
	он показывается, если срабатывает медиазапрос */
	position: fixed;
	width: 50px;
	left: 0;
	top: 0;
	height: 100%;
	z-index: 6;
	background: url(../images/swipe.png) #1d282b center 20px no-repeat;
}

Здесь для контейнера .left_side мы указали position: fixed. Это свойство позволит блоку всегда оставаться слева (благодаря left: 0; top: 0; и height: 100%;) и не прокручиваться с основным контентом. Чтобы блок наверняка не перекрывался ничем добавим z-index: 5.

Так как ширина левого блока 300 пикселей, то центральный блок (.wrapper) должен иметь внутренний отступ от левого края - padding-left: 300px, чтобы не «попадать» под левое меню.

Общий код центрального блока:

.wrapper{
	position: relative;
	background: #ffffff;
	min-height: 200%;
	min-width: 400px;
	max-width: 1200px;
	padding-left: 300px;
	padding-right: 0px;
	box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
.wrapper a{
	color:#576a6f;
}
.wrapper a:hover{
	color:#1d282b;
}
.text_block{
	overflow: hidden;
	color:#4a4a4a;
	font-size: 18px;
	line-height: 24px;
	min-height: 200px;
	background: url("../images/hr.png") left bottom repeat-x;
	padding: 10px 40px 10px;
}
p{
	margin-bottom: 24px;
}
.cent_img{
	display: block;
	margin: 0 auto 40px;
}
.auto_img{
	display: block;
	max-width: 100%;
	margin: 0 auto 24px;
}

Здесь самое важное это оформление ширины этого блока. Для .wrapper укажем свойства

min-width: 480px;
max-width: 1200px;

То есть при увеличении экрана в ширину блок будет расширятся вместе с контентом до 1200 пикселей, затем он останется в левой стороне, а справа будет просто фон. При уменьшении же его, сжиматься он будет до 400px, если сильнее – появится горизонтальный скроллинг.

Изображения внутри центрального блока, должны иметь класс .auto_img. Если они не будут умещаться в ширину, то будут пропорционально сжиматься и будут равны 100% ширины контейнера.

Далее разберёмся с медиа запросами СSS. Все такие запросы выглядят следующим образом. Вначале идёт заголовок @media, затем указывается тип устройства на котором требуется применить css код этого запроса. Для обычного цветного экрана это слово screen (или чаще пишут all то есть для всех устройств). Затем в круглых скобках указываются условия и параметры.

Сейчас нас интересует условие max-device-width которое указывает, что последующие правила будут применяться только для режима, когда максимальная ширина браузера меньше определенного значения, указанного после двоеточия.

То есть одно наше условие будет выглядеть вот так:

@media screen and (max-width:800px){
 	.left_side{
 		display: none;
	}
	.left_swap{
		display: block;
	}
	.wrapper{
		padding-left: 50px;
	}
}

В фигурных скобках мы уже проставили нужные CSS правила, а именно скрываем левое меню, и показываем скрытый ранее вспомогательный узкий левый блок - .left_swap.

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

@media screen and (max-width:720px){
	.footer_block{
		display: block;
		width: 96%;
	}
}

Т.е. элементы перестают быть инлайновыми, и становятся блочными, благодаря чему, выстраиваются друг за другом. Свойством width: 96%, мы увеличиваем их ширину до максимума (не до 100%, т.к. у нас сохраняются паддинги – внутренние поля).

Здесь я отталкивался от того факта, что разрешение планшетов и смартфонов HD - это обычно 800 пикселей в портретной ориентации, поэтому для всего что ниже, блок меню скрывается.

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

На последок, оформим с помощью jQuery открытие левого меню по клику на свёрнутом узком левом блоке – на .left_swap. Например так:

jQuery(function($) {
	$(".left_swap").click(function (){
		$(".left_side").toggle();
		return false;
	});
})

Здесь всё предельно просто, мы обрабатываем клик по блоку и показываем, либо скрываем блок с меню. Код возможно слишком прост и его можно улучшить, но в качестве примера сойдёт.

ДемоСкачать

Таким образом мы рассмотрели пример вёрстки адаптивного сайта, а полученный результат можно как обычно посмотреть на демо-странице. Попробуйте увеличить или уменьшить ширину окна браузера и понаблюдайте за поведением блоков при этом.

PS: В последнее время на блоге очень много спама в комментариях, не всегда успеваю его чистить, но всё равно все ваши комментарии по делу читаю и постараюсь ответить.

Не забудьте подписаться на HeavenWeb!

Поделиться:
Комментарии

Комментарии открыты, на спам внимания не обращайте, я всё почищу.
А как будет время разберусь как избавиться от него полностью :)

Faraday
пт, 2014-07-04 18:51

Спасибо за пример! Всё легко и доступно для понимания. Продолжайте в том же духе!

Екатерина
пн, 2014-08-04 13:42

Очень рад, что понравилось :) На подходе статья про медиазапросы CSS. Возможно тоже будет полезной.

Faraday
пн, 2014-08-04 19:47

Спасибо. Статья класс. Сверстал по ней свой шаблон.

s2xs
ср, 2015-02-11 14:12

Спасибо! Особенно за jQuery))

Алекс
ср, 2015-03-18 10:54

Макет даже в качестве примера вызывает вопросы. При ширине 768px и менее меню отображается свёрнутой полосой. Если с ней взаимодействовать (открыть, закрыть), а затем перейти к ширине 980px и более (например, перевернув планшет), "полная" версия меню не появится вовсе. Если увеличить ширину, не взаимодействуя с меню - всё ок, оно отображается. (смоделировано в Мозилле с помощью инструмента "Адаптивный дизайн")

Betty
ср, 2015-10-21 10:54

Да, с меню действительно такой баг. Пусть скрипт написан довольно упрощённо, но придётся доработать.

Faraday
чт, 2015-10-22 12:08

Я написал статью как под любые аппараты сделать свой сайт, не много проще!
http://web-rubik.ru адаптировать сайт

вс, 2015-11-15 18:10

Добрый день, спасибо за статью, очень доходчиво и по делу )!

В комментариях упоминалось:
/* На подходе статья про медиазапросы CSS */,
если можно напишите ссылку на данную статью )?

Valera
пн, 2015-11-16 15:00

Отличная статья, спасибо.
Только есть вопрос, скажите, а как добавить правый сайт бар?
Чтобы получилось левый,контент,правый

пн, 2015-11-30 17:04

Если сузить страницу, а потом снова расширить, то меню исчезает. Скрипт нужно дописать.

Михаил
сб, 2016-01-02 10:46

Точнее: "Если сузить страницу, нажать на меню, закрыть меню и расширить страницу, то меню исчезнет. Скрипт не дописан."

Михаил
сб, 2016-01-02 10:48

Да но только как это сделать ???

Raif
чт, 2016-03-10 17:25

Да но только как это сделать ???

чт, 2016-03-10 17:26

Как шрифт myPTNarrow подключить на своем сайте?

Славик
ср, 2016-02-10 22:49

"Если сузить страницу, нажать на меню, закрыть меню и расширить страницу, то меню исчезнет. Скрипт не дописан."

пт, 2016-03-11 16:21

Ну если так на скорую руку, то можно добавить

@media only screen and (min-width : 800px) {
	.left_side{
		display: block !important;
	}
}

в стили, чтобы когда ширина экрана была больше 800 то блок принудительно появлялся, даже если был выключен из js

Faraday
ср, 2016-03-16 23:07

Попробуйте демо открыть в проклятых и криворуких браузерах Internet Explorer, конкретно в 8 версии и ниже (выше не пробовал)... Все верстальщики походу люто ненавидят недобраузер Internet Explorer... Им не пользуюсь, скорей всего и Микрософт не пользуется никто, зато очень много пользователей на подобных сидят...

Владимир
пт, 2016-05-06 10:34

Спасибо большое! Хорошо верстаю на таблицах, но только теперь потихонечку перехожу на правильные методы. Очень толковый пример.

Женька
вс, 2016-11-06 03:16
Комментировать