Адаптивная вёрстка сайта, урок первый. Вёрстка главной страницы

Адаптивная вёрстка сайта позволяет веб-страницам автоматически подстраиваться под экраны планшетов и смартфонов. Мобильный интернет-трафик растёт с каждым годом и чтобы эффективно обрабатывать этот трафик, нужно предлагать пользователям адаптивные сайты с удобным интерфейсом.
Поисковые системы используют ряд критериев для оценки адаптивности сайта при просмотре на мобильных устройствах. Google старается упростить пользование Интернетом для владельцев смартфонов и планшетов, отмечая в мобильной выдаче адаптированные под мобильные устройства сайты специальной пометкой mobile-friendly. В Яндексе также работает алгоритм, который отдает предпочтение сайтам с мобильной/адаптивной версией для пользователей в мобильном поиске.
Проверить отображение страницы на мобильных устройствах можно на сервисах Яндекс.Вебмастер и Google Developers.

Что такое адаптивная вёрстка
Адаптивная вёрстка предполагает отсутствие горизонтальной полосы прокрутки и масштабируемых областей при просмотре на любом устройстве, читабельный текст и большие области для кликабельных элементов. С помощью медиазапросов можно управлять компоновкой и расположением блоков на странице, перестраивая шаблон таким образом, чтобы он адаптировался под разные размеры экранов устройств.
Основные приёмы создания адаптивного сайта приведены в статье Отзывчивый и адаптивный дизайн сайта. Для отзывчивого дизайна ширина основного контейнера сайта задаётся в %, при этом она может быть равна как 100% ширины окна браузера, так и меньше. Ширина столбцов сетки также задаётся в %. В адаптивном дизайне ширина основного контейнера и столбцов сетки фиксируется с помощью значений в px.
Рассматриваемый в данном уроке приём адаптивной резиновой вёрстки отлично сработает на двухколоночном шаблоне, сделав сайт адаптивным и удобным для просмотра на мобильных устройствах. Шаблон предполагает различную компоновку основного содержимого страниц, в этом уроке будет разобрана вёрстка главной страницы.
Вёрстка главной страницы
Страница состоит из трёх основных блоков: верхний колонтитул (шапка), контейнер-обёртка для основного содержимого и сайдбара, и нижний колонтитул (футер). В качестве переломных точек дизайна возьмём 768px и 480px.
В первой точке скроем верхнее меню и переместим сайдбар под контейнер с постами. Во второй точке изменим расположение элементов шапки, отменим позиционирование кнопок социальных сетей в постах и отменим обтекание столбцов подвала страницы.

1. Метатеги и раздел <head>
1) Добавим в раздел <head> необходимые файлы — ссылку на используемые шрифты, библиотеку jQuery, а также плагин prefixfree (чтобы не писать для свойств браузерные префиксы):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Адаптивная вёрстка сайта</title> <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,600,600italic,700,700italic|Playfair+Display:400,700&subset=latin,cyrillic"> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.css"> <link rel="stylesheet" type="text/css" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> </head> <body>
2. Шапка страницы
В шапке страницы <header> поместим следующие элементы-контейнеры:
логотип <a class="logo">;
кнопку для показа/скрытия главного меню <div class="nav-toggle">;
главное меню <ul id="menu">;
форму поиска по сайту <form id="searchform">.
<header> <nav class="container"> <a class="logo" href=""> <span>L</span> <span>O</span> <span>G</span> <span>O</span> </a> <div class="nav-toggle"><span></span></div> <form action="" method="get" id="searchform"> <input type="text" placeholder="Искать на сайте..."> <button type="submit"><i class="fa fa-search"></i></button> </form> <ul id="menu"> <li><a href="">Блог</a></li> <li><a href="">Портфолио</a></li> <li><a href="">Об авторе</a></li> </ul> </nav> </header>
3. Блок с кратким содержанием статьи
Анонс статей обернём элементом <article id="post-1" class="post">:
<div class="container"> <div class="posts-list"> <article id="post-1" class="post"> <div class="post-image"><a href=""><img src="https://html5book.ru/wp-content/uploads/2016/05/rasskaz_slovar_rodnoy_prirodi.jpg"></a></div> <div class="post-content"> <div class="category"><a href="">Дизайн</a></div> <h2 class="post-title">Весна</h2> <p>Очень богат русский язык словами, относящимися к временам года и к природным явлениям, с ними связанным.</p> <div class="post-footer"> <a class="more-link" href="">Продолжить чтение</a> <div class="post-social"> <a href="" target="_blank"><i class="fa fa-facebook"></i></a> <a href="" target="_blank"><i class="fa fa-twitter"></i></a> <a href="" target="_blank"><i class="fa fa-pinterest"></i></a> </div> </div> </div> </article> <article id="post-2" class="post"> ... </article> </div> <!-- конец div class="posts-list"-->
4. Боковая колонка
В боковую колонку <aside> добавим список категорий, последние записи и форму подписки на рассылку:
<aside> <div class="widget"> <h3 class="widget-title">Категории</h3> <ul class="widget-category-list"> <li><a href="">Дизайн</a> (2)</li> <li><a href="">Вёрстка</a> (5)</li> <li><a href="">Видео</a> (1)</li> </ul> </div> <div class="widget"> <h3 class="widget-title">Последние записи</h3> <ul class="widget-posts-list"> <li> <div class="post-image-small"> <a href=""><img src="https://html5book.ru/wp-content/uploads/2016/05/rasskaz_slovar_rodnoy_prirodi.jpg"></a> </div> <h4 class="widget-post-title">Весна</h4> </li> <li> <div class="post-image-small"> <a href=""><img src="https://html5book.ru/wp-content/uploads/2016/05/rasskaz_Russia.jpg"></a> </div> <h4 class="widget-post-title">Лето</h4> </li> <li> <div class="post-image-small"> <a href=""><img src="https://html5book.ru/wp-content/uploads/2016/05/rasskaz_rodnaya_priroda_osen.jpg"></a> </div> <h4 class="widget-post-title">Осень</h4> </li> </ul> </div> <div class="widget"> <h3 class="widget-title">Подписка на рассылку</h3> <form action="" method="post" id="subscribe"> <input type="email" name="email" placeholder="Ваш email" required> <button type="submit"><i class="fa fa-paper-plane-o"></i></button> </form> </div> </aside> </div> <!-- конец div class="container"-->
5. Нижний колонтитул
В подвале страницы разместим информацию о копирайте, кнопки социальных сетей и ссылку на электронную почту:
<footer> <div class="container"> <div class="footer-col"><span>Мой блог © 2016</span></div> <div class="footer-col"> <div class="social-bar-wrap"> <a title="Facebook" href="" target="_blank"><i class="fa fa-facebook"></i></a> <a title="Twitter" href="" target="_blank"><i class="fa fa-twitter"></i></a> <a title="Pinterest" href="" target="_blank"><i class="fa fa-pinterest"></i></a> <a title="Instagram" href="" target="_blank"><i class="fa fa-instagram"></i></a> </div> </div> <div class="footer-col"> <a href="mailto:admin@yoursite.ru">Написать письмо</a> </div> </div> </footer> <script> $('.nav-toggle').on('click', function(){ $('#menu').toggleClass('active'); }); </script> </body> </html>
6. Общие CSS-стили
Общие стили, сброс стилей браузера по умолчанию:
*, *:after, *:before { box-sizing: border-box; padding: 0; margin: 0; transition: .5s ease-in-out; /* добавим плавность переходов для всех элементов страницы*/ } ul { list-style: none; } a { text-decoration: none; outline: none; } img { display: block; width: 100%; } h1, h2, h3, h4, h5, h6 { font-family: 'Playfair Display'; font-weight: normal; letter-spacing: 1px; } body { font-family: 'Open Sans', arial, sans-serif; font-size: 14px; line-height: 1; color: #373737; background: #f7f7f7; } /* добавим очистку потока для всех контейнеров, внутри которых задано обтекание дочерних элементов */ header:after, .container:after, footer:after, .widget-posts-list li:after, #subscribe:after { content: ""; display: table; clear: both; } /* стилевой класс, который управляет шириной контейнера сетки*/ .container { margin: 0 auto; width: 100%; max-width: 960px; padding: 0 15px; }
7. Стили для шапки и её содержимого
header { width: 100%; background: white; box-shadow: 3px 3px 1px rgba(0,0,0,.05); padding: 15px 0; margin-bottom: 30px; position: relative; } /* логотип */ .logo { display: block; float: left; } .logo span { color: white; display: inline-block; width: 30px; height: 30px; line-height: 30px; border-radius: 50%; margin: 5px 0; text-align: center; text-shadow: 2px 2px 1px rgba(0,0,0,.4); } .logo span:nth-child(odd) { background: #EF5A42; } .logo span:nth-child(even) { background: #F8B763; } /* меню */ #menu { float: right; } #menu li { display: inline-block; margin-right: 30px; } #menu a { color: #111; text-transform: uppercase; letter-spacing: 1px; font-weight: 600; display: block; line-height: 40px; } #menu a:hover { color: #EF5A42; } #menu li:last-child { margin-right: 0; } /* форма поиска */ #searchform { float: right; margin-left: 46px; display: inline-block; position: relative; } #searchform input { width: 170px; float: left; border: none; padding-left: 10px; height: 40px; overflow: hidden; outline: none; color: #9E9C9C; font-style: italic; } #searchform button { background: transparent; height: 40px; border: none; position: absolute; right: 10px; color: #EF5A42; cursor: pointer; font-size: 18px; } #searchform input:focus { outline: 2px solid #EBEBE3; } /* кнопка переключения меню, появляющаяся при ширине 768px */ .nav-toggle { display: none; position: relative; float: right; width: 40px; height: 40px; margin-left: 20px; background: #EF5A42; cursor: pointer; } .nav-toggle span { display: block; position: absolute; top: 19px; left: 8px; right: 8px; height: 2px; background: white; } .nav-toggle span:before, .nav-toggle span:after { content: ""; position: absolute; display: block; left: 0; width: 100%; height: 2px; background: white; } .nav-toggle span:before { top: -10px; } .nav-toggle span:after { bottom: -10px; } /* класс, который будет добавлен в верхнему меню при нажатии на кнопку и покажет скрытое меню*/ #menu.active { max-height: 123px; }
8. Стили для блока с основным содержимым
/* левый контейнер */ .posts-list { margin-bottom: 30px; width: 64%; float: left; } /* блок для статьи */ .post { margin-bottom: 35px; } .post-content p { line-height: 1.5; padding-bottom: 1em; } .post-image { margin-bottom: 30px; } .category { margin-bottom: 15px; } .category a { color: #F8B763; text-transform: uppercase; } .post-title { margin-bottom: 12px; font-size: 26px; } /* блок с кнопкой "продолжить чтение" и кнопками социальных сетей */ .post-footer { border-top: 1px solid #EBEBE3; border-bottom: 1px solid #EBEBE3; position: relative; margin-top: 15px; } .more-link { position: relative; display: inline-block; font-size: 10px; text-transform: uppercase; color: white; line-height: 44px; padding: 0 22px; background: #3C3D41; letter-spacing: 0.1em; white-space: nowrap; } .more-link:after { content: ''; display: block; position: absolute; width: 0; height: 0; top: 0; right: 0; border: solid transparent; border-width: 22px 18px; border-left-color: #3C3D41; transform: translateX(100%); } .post-social { position: absolute; left: auto; top: 50%; right: 0; text-align: right; transform: translateY(-50%); padding: 0; font-size: 12px; } .post-social a { display: inline-block; margin-left: 8px; color: #F8B763; width: 25px; height: 25px; line-height: 23px; text-align: center; border-radius: 50%; border: 1px solid; }
9. Стили для боковой колонки
/* правый контейнер */ aside { width: 33%; float: right; } /* блок для виджетов */ .widget { padding: 20px 15px; background: white; font-size: 13px; margin-bottom: 30px; box-shadow: 3px 3px 1px rgba(0,0,0,.05); } .widget-title { font-size: 18px; padding: 10px; margin-bottom: 20px; text-align: center; border: 2px solid #F8B763; box-shadow: 3px 3px 0 0 #F8B763; } .widget-category-list li { border-bottom: 1px solid #EBEBE3; padding: 10px 0; color: #c6c6c6; font-style: italic; } .widget-category-list li:last-child { border-bottom: none; } .widget-category-list li a { color: #626262; margin-right: 6px; font-style: normal; } .widget-category-list li a:before { content: "\f105"; display: inline-block; font-family: 'FontAwesome'; margin-right: 10px; color: #c6c6c6; } .widget-posts-list li { border-top: 1px solid #EBEBE3; padding: 15px 0; } .widget-posts-list li:nth-child(1) { border-top: none; } .post-image-small { width: 30%; float: left; margin-right: 15px; } .widget-post-title { float: left; } /* форма подписки */ #subscribe { position: relative; width: 100%; padding: 15px 0; } #subscribe input { width: 100%; display: block; float: left; border: 2px solid #EBEBE3; padding: 0 0 0 10px; height: 40px; position: relative; outline: none; color: #9E9C9C; font-style: italic; } #subscribe button { padding: 0 15px; background: transparent; height: 40px; border: none; position: absolute; right: 0; color: #EF5A42; cursor: pointer; font-size: 18px; } #subscribe input:focus + button { background: #EF5A42; color: white; }
10. Стили для нижнего колонтитула
Подвал сайта разделим на три равных столбца:
footer { padding: 30px 0; background: #3C3D41; color: white; } .footer-col { width: 33.3333333333%; float: left; } .footer-col a { color: white; } .footer-col:last-child { text-align: right; } .social-bar-wrap { text-align: center; } .social-bar-wrap a { padding: 0 7px; font-size: 18px; }
11. Медиа-запросы
@media (max-width: 768px) { /* показываем кнопку для переключения верхней навигации */ .nav-toggle { display: block; } header { padding: 10px 0; } /* скрываем верхнее меню, отменяем обтекание, позиционируем его, сместив на высоту шапки сайта */ #menu { max-height: 0; background: white; float: none; position: absolute; overflow: hidden; top: 63px; right: 0; left: 0; margin: 0; padding: 0; z-index: 3; } /* делаем элементы списка блочными, чтобы они располагались друг под другом */ #menu li { display: block; text-align: center; border-bottom: 1px solid #EBEBE3; margin-right: 0; } /* отменяем обтекание левой и правой колонок, устанавливаем им ширину 100%*/ .posts-list, aside { width: 100%; float: none; } .widget-post-title { font-size: 1.5em; } } @media (max-width: 480px) { /* отменяем обтекание для логотипа и выравниваем по центру*/ .logo { float: none; margin: 0 auto 15px; display: table; } .logo span { margin: 0 2px; } /* позиционируем меню на увеличившуюся высоту шапки */ #menu { top: 118px; } /* позиционируем форму поиска по левому краю */ #searchform { float: left; margin-left: 0; } /* убираем верхнюю и нижнюю границы и выравниваем кнопку по центру */ .post-footer { border-top: none; border-bottom: none; text-align: center; } /* отменяем позиционирование кнопок соцсетей */ .post-social { position: static; text-align: center; transform: none; margin-top: 20px; } .widget-post-title { font-size: 1.2em; } /* отменяем обтекание для столбцов подвала страницы */ .footer-col { float: none; margin-bottom: 20px; width: 100%; text-align: center; } .footer-col:last-child { text-align: center; margin-bottom: 0; } }
12. Скрипт для мобильного меню
За показ-скрытие верхнего меню при клике на кнопку (переключается высота меню — от нулевой до равной её содержимому) отвечает код jQuery, который мы ранее добавили в разметку страницы перед закрывающим тегом </body>:
<script> $('.nav-toggle').on('click', function(){ $('#menu').toggleClass('active'); }); </script>