Создаем адаптивный CSS-шаблон с плавными переходами

На этом уроке мы будем создавать адаптивный CSS-макет с 100% шириной и высотой  и с плавными переходами страниц. Идея состоит в создании секций с содержанием и навигации, которая позволит переключаться между этими секциями. Мы будем использовать радио-кнопки для навигации и создавать анимацию для содержания, создавая эффект "плавной прокрутки". Эта идея может быть полезна для веб-страниц или веб-приложения, где содержание должно строго соответствовать размеру экрана (ширина и высота).

Пожалуйста, обратите внимание: результат этого урока будет работать, как задумано, только в браузерах, которые поддерживают соответствующие свойства CSS.

Также имейте ввиду, что мы опустим префиксы для различных браузеров в примерах кода в этой статье. Но Вы, конечно, можете найти их в исходных файлах.

Разметка

Структура макета будет состоять из основного контейнера с классом st-container, который будет содержать радио-кнопки и ссылки, а блок с классом st-scroll, который будет содержать секции с контентом:

<div class="st-container">
 
 <input type="radio" name="radio-set" checked="checked" id="st-control-1"/>
 <a href="#st-panel-1">Serendipity</a>
 
 <input type="radio" name="radio-set" id="st-control-2"/>
 <a href="#st-panel-2">Happiness</a>
 
 <input type="radio" name="radio-set" id="st-control-3"/>
 <a href="#st-panel-3">Tranquillity</a>
 
 <input type="radio" name="radio-set" id="st-control-4"/>
 <a href="#st-panel-4">Positivity</a>
 
 <input type="radio" name="radio-set" id="st-control-5"/>
 <a href="#st-panel-5">Passion</a>
 
 <div class="st-scroll">
 
 <section class="st-panel" id="st-panel-1">
 <div class="st-deco" data-icon="H"></div>
 <h2>Serendipity</h2>
 <p>Banksy adipisicing eiusmod banh mi sed...</p>
 </section>
 
 <section class="st-panel st-color" id="st-panel-2">
 <!-- ... -->
 </section>
 
 <!-- ... st-panel-3, st-panel-4, st-panel-5 -->
 
 </div><!-- // st-scroll -->
 
</div><!-- // st-container -->

Итак, что мы хотим сделать: переместить блок-оболочку, изменяя его значение top и показывая соответствующую секцию в окне просмотра. Это можно сделать выбрав соответствующую радио-кнопку, которая ссылается на соответствующую секцию в блоке с классом st-scroll.

Причина, по которой мы используем ссылки, а не как обычно лэйблы (тег label), является то, что мы хотим иметь возможность создать своего рода "fallback" для старых браузеров (родственные комбинаторы (sibling combinators) не работают в старых браузерах). Ссылки имеют аттрибут href с идентификатором соответствующий секции, таким образом мы просто скрываем радио-кнопки, делая ссылки кликабельными.

Теперь давайте перейдем к стилям!

CSS

Итак, как нам сделать этот макет гибким и его секции точно соответствующие размеру экрана? Хитрость заключается в том, чтобы сделать главный контейнер с абсолютным позиционированием, и шириной и высотой 100%, внутренние секции будут иметь относительное позиционирование. Но они также будут иметь ширину и высоту 100%. Это позволит каждой секции быть равной в точности размеру экрана.

Так как мы будем создавать навигацию по контенту с помощью анимации секции-оболочки, то мы установим для body свойство overflow:hidden:

 body {
 overflow: hidden;
}

Давайте посмотрим на стили основного контейнера:

 .st-container {
 position: absolute;
 width: 100%;
 height: 100%;
 top: 0;
 left: 0;
 font-family: 'Josefin Slab', 'Myriad Pro', Arial, sans-serif;
}

Мы поместим "навигацию" в нижнюю часть страницы, задав ей фиксированное положение (position: fixed). Обратите внимание, что мы устанавливаем одинаковую ширину и высоту для радио-кнопок и ссылок. Идея состоит в том, чтобы наложить радио-кнопки на ссылки, чтобы они были кликабельными, но задаем им прозрачность равную 0, чтобы они не были видны. Также важно то, что мы устанавливаем z-index для радио-кнопок больше, чем для ссылок:

 .st-container > input,
.st-container > a {
 position: fixed;
 bottom: 0px;
 width: 20%;
 cursor: pointer;
 font-size: 16px;
 height: 34px;
 line-height: 34px;
}
 
.st-container > input {
 opacity: 0;
 z-index: 1000;
}
 
.st-container > a {
 z-index: 10;
 font-weight: 700;
 background: #e23a6e;
 color: #fff;
 text-align: center;
 text-shadow: 1px 1px 1px rgba(151,24,64,0.2);
}

Так как мы используем проценты для "растягивания" ссылок и радио-кнопок по ширине экрана, у нас могут появиться некоторые проблемы с округлением значений, которые вызвали бы появление пробелов. Для того чтобы их скрыть, мы используем псевдо-элемент, который будет находиться под ссылками и радио-кнопками. Он будет иметь тот же цвет фона, что и ссылки:

 .st-container:before {
 content: '';
 position: fixed;
 width: 100%;
 height: 34px;
 background: #e23a6e;
 z-index: 9;
 bottom: 0;
}

Наши ссылки и радио-кнопки все еще не расположены как нужно, так что давайте зададим им соответствующия значения для свойства left:

 #st-control-1, #st-control-1 + a {
 left: 0;
}
 
#st-control-2, #st-control-2 + a {
 left: 20%;
}
 
#st-control-3, #st-control-3 + a {
 left: 40%;
}
 
#st-control-4, #st-control-4 + a {
 left: 60%;
}
 
#st-control-5, #st-control-5 + a {
 left: 80%;
}

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

 .st-container > input:checked + a,
.st-container > input:checked:hover + a{
 background: #821134;
}

Давайте также добавим маленький треугольник с помощью псевдо-класса :after, и зададим ему тот же цвет:

 .st-container > input:checked + a:after,
.st-container > input:checked:hover + a:after{
 bottom: 100%;
 border: solid transparent;
 content: '';
 height: 0;
 width: 0;
 position: absolute;
 pointer-events: none;
 border-bottom-color: #821134;
 border-width: 20px;
 left: 50%;
 margin-left: -20px;
}

Вы можете также использовать CSS Arrow, Please!, если вы хотите быстро создавать подобные стрелки.

Давайте также определим стили при наведении на ссылку:

 .st-container > input:hover + a{
 background: #AD244F;
}
 
.st-container > input:hover + a:after {
 border-bottom-color: #AD244F;
}

Оболочка для секций и секции будут иметь относительное позиционирование, и мы зададим им ширину и высоту 100%. Для оболочки также зададим top и left равные 0.

Transitions будет анимировать значение свойства transform для соответствующей позиции:

 .st-scroll,
.st-panel {
 position: relative;
 width: 100%;
 height: 100%;
}
 
.st-scroll {
 top: 0;
 left: 0;
 transition: all 0.6s ease-in-out;
 
 /* Let's enforce some hardware acceleration */
 -webkit-transform: translate3d(0, 0, 0);
 -webkit-backface-visibility: hidden;
}
 
.st-panel{
 background: #fff;
 overflow: hidden;
}

Хотя я обычно не добавляю префикс браузера к свойствам, я оставил эти Webkit-префиксы, т.к. они помогут в создании сглаживания.

Давайте определим позиции для каждой выбранной радио-кнопки для оболочки st-scroll. Так как мы знаем, что каждая секция имеет высоту 100%, мы знаем её точное положение. Мы будем использовать свойство transform, чтобы переместить секцию-обертку по Y-измерению (вверх и вниз):

 #st-control-1:checked ~ .st-scroll {
 transform: translateY(0%);
}
#st-control-2:checked ~ .st-scroll {
 transform: translateY(-100%);
}
#st-control-3:checked ~ .st-scroll {
 transform: translateY(-200%);
}
#st-control-4:checked ~ .st-scroll {
 transform: translateY(-300%);
}
#st-control-5:checked ~ .st-scroll {
 transform: translateY(-400%);
}

Теперь давайте зададим стили для содержания. Для верхнего треугольника с иконой, мы просто повернем блок с классом st-deco. Мы разместим его в центре верхней части экрана, установив top:0, и left:50%, и придав ему отрицательный левый отступ равный половине его ширины. translateY(-50%) позволит видеть только половину блока, таким образом создавая треугольник:

 .st-deco{
 width: 200px;
 height: 200px;
 position: absolute;
 top: 0px;
 left: 50%;
 margin-left: -100px;
 background: #fa96b5;
 transform: translateY(-50%) rotate(45deg);
}

Для иконки мы будем использовать шрифт Raphaël Icon-Set via @font-face и data-attribute/pseudo-class технику. Псевдо-элемент :after будет вставлять иконку в HTML-код для этого элемента. Обратите внимание, что нам нужно повернуть её обратно в противоположном направлении от родительского элемента, чтобы видеть её в "нормальном" положении:

 [data-icon]:after {
 content: attr(data-icon);
 font-family: 'RaphaelIcons';
 color: #fff;
 text-shadow: 1px 1px 1px rgba(151,24,64,0.2);
 position: absolute;
 width: 200px;
 height: 200px;
 line-height: 200px;
 text-align: center;
 font-size: 90px;
 top: 50%;
 left: 50%;
 margin: -100px 0 0 -100px;
 transform: rotate(-45deg) translateY(25%);
}

Заголовок будет размещен в центре экрана с отрицательным верхним отступом:

 .st-panel h2 {
 color: #e23a6e;
 text-shadow: 1px 1px 1px rgba(151,24,64,0.2);
 position: absolute;
 font-size: 54px;
 font-weight: 900;
 width: 80%;
 left: 10%;
 text-align: center;
 line-height: 50px;
 margin: -70px 0 0 0;
 padding: 0;
 top: 50%;
 -webkit-backface-visibility: hidden;
}

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

 #st-control-1:checked ~ .st-scroll #st-panel-1 h2,
#st-control-2:checked ~ .st-scroll #st-panel-2 h2,
#st-control-3:checked ~ .st-scroll #st-panel-3 h2,
#st-control-4:checked ~ .st-scroll #st-panel-4 h2,
#st-control-5:checked ~ .st-scroll #st-panel-5 h2{
 animation: moveDown 0.6s ease-in-out 0.2s backwards;
}
 
@keyframes moveDown{
 0% {
 transform: translateY(-40px);
 opacity: 0;
 }
 100% {
 transform: translateY(0px);
 opacity: 1;
 }
}

Параграфы будут иметь следующие стили:

 .st-panel p {
 position: absolute;
 text-align: center;
 font-size: 16px;
 line-height: 22px;
 color: #8b8b8b;
 z-index: 2;
 padding: 0;
 width: 50%;
 left: 25%;
 top: 50%;
 margin: 10px 0 0 0;
 -webkit-backface-visibility: hidden;
}

В то время как заголовок будет двигаться вниз, параграф будет двигаться вверх:

 #st-control-1:checked ~ .st-scroll #st-panel-1 p,
#st-control-2:checked ~ .st-scroll #st-panel-2 p,
#st-control-3:checked ~ .st-scroll #st-panel-3 p,
#st-control-4:checked ~ .st-scroll #st-panel-4 p,
#st-control-5:checked ~ .st-scroll #st-panel-5 p{
 animation: moveUp 0.6s ease-in-out 0.2s backwards;
}
 
@keyframes moveUp{
 0% {
 transform: translateY(40px);
 opacity: 0;
 }
 100% {
 transform: translateY(0px);
 opacity: 1;
 }
}

Для того, чтобы сделать наш макет немного симпатичнее, мы добавим класс color, который «инвертирует» цвета для секций и их элементов содержания:

 /* Colored sections */
 
.st-color,
.st-deco{
 background: #fa96b5;
}
.st-color [data-icon]:after {
 color: #fa96b5;
}
.st-color .st-deco {
 background: #fff;
}
.st-color h2 {
 color: #fff;
 text-shadow: 1px 1px 1px rgba(0,0,0,0.1);
}
.st-color p {
 color: rgba(255,255,255,0.8);
}

И последнее, но не менее важное, мы добавим некоторые media queries для контроля положения и размера шрифта элементов для небольших экранов:

 @media screen and (max-width: 520px) {
 .st-panel h2 {
 font-size: 42px;
 }
 
 .st-panel p {
 width: 90%;
 left: 5%;
 margin-top: 0;
 }
 
 .st-container > a {
 font-size: 13px;
 }
}
 
@media screen and (max-width: 360px) {
 .st-container > a {
 font-size: 10px;
 }
 
 .st-deco{
 width: 120px;
 height: 120px;
 margin-left: -60px;
 }
 
 [data-icon]:after {
 font-size: 60px;
 transform: rotate(-45deg) translateY(15%);
 }
}

Для старых браузеров, которые не поддерживают некоторые селекторы мы хотим вернуться к классическому "target jump". Мы можем сделать это изменив некоторые стили (simple.css). В частности, мы установим свойство overflow для body равное "auto" и спрячем радио-кнопки, делая ссылки кликабельными (в аттрибуте href они имеют ID соответствующей панели):

 body {
 overflow: auto;
}
.st-container > input{
 display: none;
}

И это все! Я надеюсь, вам понравился этот урок!

Демонстрация

Скачать исходные файлы

Перевод статьи с http://tympanus.net/codrops


Если у Вас возникли вопросы, то для скорейшего получения ответа рекомендуем воспользоваться нашим форумом

Комментарии  

#1 алексей 03.08.2012 09:43
а при переносе меню наверх как треугольник развернуть?

всё хорошо, но треугольник всегда остриём вниз показывает...

просьба по возможности написать ответ на почту.

Спасибо!
#2 Егор 15.12.2012 17:09
Скажите пожалуйста, а как изменить изображения в треугольнике?
Заранее огромное спасибо!

You have no rights to post comments