Создание офф-скрин меню с помощью CSS переходов

24.06.2016

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

просмотр демо учебник меню анимированное CSS3 меню приложений в стиле меню навигации по экрану

Давайте сначала рассмотрим разницу двух типов меню:

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

Прежде чем мы продолжим, есть некоторые важные вещи, которые необходимо отметить:

  • Эта инструкция использует CSS transitions, чтобы работать плавно и красиво. На старых браузерах контент будет просто перепрыгивать в соответствующую позицию.
  • Автор использует classie.js для простого добавления и удаления классов.
  • Автор использует JavaScript-функции querySelector и querySelectorAll, которые поддерживаются в IE8 и выше.

Наконец, давайте взглянем на 8 разновидностей меню, которые мы будем создавать:

Slide left menu — меню, которое выдвигается с левой стороны контента.
Slide right menu — меню, которое выдвигается с правой стороны контента.
Slide top menu — меню, которое выдвигается сверху контента.
Slide in bottom menu — меню, которое выдвигается снизу контента.
Push left menu — меню, которое выдвигается с левой стороны и сдвигает контент вправо.
Push right menu — меню, которое выдвигается с правой стороны и сдвигает контент влево.
Push top menu — меню, которое выдвигается сверху и сдвигает контент вниз.
Push bottom menu — меню, которое выдвигается снизу и сдвигает контент вверх.

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

The HTML

<body>

  <nav class="menu slide-menu-left">
    <ul>
      <li><button class="close-menu">← Close</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /slide menu left -->

  <nav class="menu slide-menu-right">
    <ul>
      <li><button class="close-menu">Close →</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /slide menu right -->

  <nav class="menu slide-menu-top">
    <ul>
      <li><button class="close-menu">↑ Close</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /slide menu top -->

  <nav class="menu slide-menu-bottom">
    <ul>
      <li><button class="close-menu">Close ↓</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /slide menu bottom -->

  <nav class="menu push-menu-left">
    <ul>
      <li><button class="close-menu">← Close</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /push menu left -->

  <nav class="menu push-menu-right">
    <ul>
      <li><button class="close-menu">Close →</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /push menu right -->

  <nav class="menu push-menu-top">
    <ul>
      <li><button class="close-menu">↑ Close</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /push menu top -->

  <nav class="menu push-menu-bottom">
    <ul>
      <li><button class="close-menu">Close ↓</button></li>
      <li><a href="#">Broccoli</a></li>
      ...
    </ul>
  </nav><!-- /push menu bottom -->

  <div id="wrapper">
    <div id="main">
      <div class="container">
        <div class="buttons">
          <button class="nav-toggler toggle-slide-left">Slide Menu Left</button>
          ...
        </div><!-- /buttons -->
        <section class="content">
          <h1>Vegetables</h1>
          <p>Turnip greens yarrow...</p>
        </section><!-- /.content -->
      </div>
    </div><!-- #main -->

  </div><!-- /#wrapper -->

</body>

The Common CSS

/* ------------------------------------------------------------ *\
|* ------------------------------------------------------------ *|
|* Template
|* ------------------------------------------------------------ *|
\* ------------------------------------------------------------ */
body {
    overflow-x: hidden
}
#wrapper {
    position: relative;
    z-index: 10;
    top: 0;
    left: 0;
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -ms-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;
}
section {
    margin-bottom: 30px
}
section h1 {
    font-family: "Oswald", sans-serif;
    margin-bottom: 10px;
}
section p {
    margin-bottom: 30px
}
section p:last-child {
    margin-bottom: 0
}
section:last-child {
    margin-bottom: 0
}
section.toggle {
    text-align: center
}
.mask {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 15;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
}
/* ------------------------------------------------------------ *\
|* ------------------------------------------------------------ *|
|* Menus
|* ------------------------------------------------------------ *|
\* ------------------------------------------------------------ */
/* general style for all menus */
nav.menu {
    position: fixed;
    z-index: 20;
    background-color: #67b5d1;
    overflow: hidden;
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -ms-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;
}
nav.menu ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
}
nav.menu a {
    font-weight: 300;
    color: #fff;
}
button.close-menu {
    background-color: #3184a1;
    color: #fff;
}
button.close-menu:focus {
    outline: none
}

Понимание Структуры

Наш body overflow-x имеет свойство hidden, потому что мы не хотим иметь полосы прокрутки на экране, когда оболочка выталкивается влево или вправо. Когда меню появляется вертикально, это не имеет значения. Что еще более важно, хоть мы и позиционируем наше внеэкранное меню навигации вне оболочки, но, когда преобразование применяется к элементу, он приобретает временно относительное позиционирование. Поскольку наши навигационные меню должны быть прикреплены к наружной части окна браузера, мы не хотим чтобы оно было внутри элемента с относительным позиционированием. Внутри каждого меню содержится список пунктов меню, и кнопка закрытия меню.

Уже давно ведется долгая дискуссия о различиях производительности абсолютного позиционирования/влево/вверх против transforms/translating. Paul Irish глубоко копает в этом и вы можете прочитать об этом здесь. Я использую позиционирование в данном случае, потому что мы имеем запасное non-transitioning решение для старых браузеров без использования условных стилей. Кроме того, после тестирования обоих, разница была совершенно невидимой для человеческого глаза. Давайте взглянем на версию нашего меню.

 

1) Slide Menu Left

Slide left menu - меню, которое выдвигается с левой стороны контента и его CSS

Slide left menu — меню, которое выдвигается с левой стороны контента и его CSS:

nav.slide-menu-left {
    top: 0;
    width: 300px;
    height: 100%;
}
nav.slide-menu-left li {
    display: block;
    text-align: center;
    border-bottom: solid 1px #3184a1;
    border-top: solid 1px #b5dbe9;
}
nav.slide-menu-left li:first-child {
    border-top: none
}
nav.slide-menu-left li:last-child {
    border-bottom: none
}
nav.slide-menu-left a {
    display: block;
    padding: 10px;
    font-size: 18px;
}
nav.slide-menu-left button.close-menu {
    margin: 10px 0;
    padding: 10px 30px;
    background-color: #3184a1;
    color: #fff;
}
nav.slide-menu-left {
    left: -300px
}
body.sml-open nav.slide-menu-left {
    left: 0
}

 

2) Slide Menu Right

Slide right menu - меню, которое выдвигается с правой стороны контента и его CSS

Slide right menu — меню, которое выдвигается с правой стороны контента и его CSS:

nav.slide-menu-right {
    top: 0;
    width: 300px;
    height: 100%;
}
nav.slide-menu-right li {
    display: block;
    text-align: center;
    border-bottom: solid 1px #3184a1;
    border-top: solid 1px #b5dbe9;
}
nav.slide-menu-right li:first-child {
    border-top: none
}
nav.slide-menu-right li:last-child {
    border-bottom: none
}
nav.slide-menu-right a {
    display: block;
    padding: 10px;
    font-size: 18px;
}
nav.slide-menu-right button.close-menu {
    margin: 10px 0;
    padding: 10px 30px;
    background-color: #3184a1;
    color: #fff;
}
nav.slide-menu-right {
    right: -300px
}
body.smr-open nav.slide-menu-right {
    right: 0
}

 

3) Slide Menu Top

Slide top menu - меню, которое выдвигается сверху контента и его CSS

Slide top menu — меню, которое выдвигается сверху контента и его CSS:

nav.slide-menu-top {
    left: 0;
    width: 100%;
    height: 100px;
}
nav.slide-menu-top ul {
    text-align: center;
    padding: 25px 0 0 0;
}
nav.slide-menu-top li {
    display: inline-block;
    margin: 0;
    vertical-align: middle;
}
nav.slide-menu-top a {
    display: block;
    line-height: 50px;
    padding: 0 10px;
    font-size: 18px;
}
nav.slide-menu-top button.close-menu {
    display: block;
    line-height: 50px;
    margin: 0;
    padding: 0 10px;
}
nav.slide-menu-top {
    top: -100px
}
body.smt-open nav.slide-menu-top {
    top: 0
}

 

4) Slide Menu Bottom

Slide in bottom menu - меню, которое выдвигается снизу контента и его CSS

Slide in bottom menu — меню, которое выдвигается снизу контента и его CSS:

nav.slide-menu-bottom {
    left: 0;
    width: 100%;
    height: 100px;
}
nav.slide-menu-bottom ul {
    text-align: center;
    padding: 25px 0 0 0;
}
nav.slide-menu-bottom li{
    display: inline-block;
    margin: 0;
    vertical-align: middle;
}
nav.slide-menu-bottom a{
    display: block;
    line-height: 50px;
    padding: 0 10px;
    font-size: 18px;
}
nav.slide-menu-bottom button.close-menu{
    display: block;
    line-height: 50px;
    margin: 0;
    padding: 0 10px;
}
nav.slide-menu-bottom {
    bottom: -100px
}
body.smb-open nav.slide-menu-bottom {
    bottom: 0
}

 

5) Push Menu Left

Push left menu - меню, которое выдвигается с левой стороны и сдвигает контент вправо и его CSS

Push left menu — меню, которое выдвигается с левой стороны и сдвигает контент вправо и его CSS:

nav.push-menu-left {
    top: 0;
    width: 300px;
    height: 100%;
}
nav.push-menu-left li {
    display: block;
    text-align: center;
    border-bottom: solid 1px #3184a1;
    border-top: solid 1px #b5dbe9;
}
nav.push-menu-left li:first-child {
    border-top: none
}
nav.push-menu-left li:last-child {
    border-bottom: none
}
nav.push-menu-left a {
    display: block;
    padding: 10px;
    font-size: 18px;
}
nav.push-menu-left button.close-menu {
    margin: 10px 0;
    padding: 10px 30px;
    background-color: #3184a1;
    color: #fff;
}
nav.push-menu-left {
    left: -300px
}
body.pml-open nav.push-menu-left {
    left: 0
}
body.pml-open #wrapper {
    left: 300px
}

 

6) Push Menu Right

Push right menu - меню, которое выдвигается с правой стороны и сдвигает контент влево и его CSS

Push right menu — меню, которое выдвигается с правой стороны и сдвигает контент влево и его CSS:

nav.push-menu-right {
    top: 0;
    width: 300px;
    height: 100%;
}
nav.push-menu-right li {
    display: block;
    text-align: center;
    border-bottom: solid 1px #3184a1;
    border-top: solid 1px #b5dbe9;
}
nav.push-menu-right li:first-child {
    border-top: none
}
nav.push-menu-right li:last-child {
    border-bottom: none
}
nav.push-menu-right a {
    display: block;
    padding: 10px;
    font-size: 18px;
}
nav.push-menu-right button.close-menu {
    margin: 10px 0;
    padding: 10px 30px;
    background-color: #3184a1;
    color: #fff;
}
nav.push-menu-right {
    right: -300px
}
body.pmr-open nav.push-menu-right {
    right: 0
}
body.pmr-open #wrapper {
    left: -300px
}

 

7) Push Menu Top

Push top menu - меню, которое выдвигается сверху и сдвигает контент вниз и его CSS

Push top menu — меню, которое выдвигается сверху и сдвигает контент вниз и его CSS:

nav.push-menu-top {
    left: 0;
    width: 100%;
    height: 100px;
}
nav.push-menu-top ul {
    text-align: center;
    padding: 25px 0 0 0;
}
nav.push-menu-top li {
    display: inline-block;
    margin: 0;
    vertical-align: middle;
}
nav.push-menu-top a {
    display: block;
    line-height: 50px;
    padding: 0 10px;
    font-size: 18px;
}
nav.push-menu-top button.close-menu {
    display: block;
    line-height: 50px;
    margin: 0;
    padding: 0 10px;
}
nav.push-menu-top {
    top: -100px
}
body.pmt-open nav.push-menu-top {
    top: 0
}
body.pmt-open #wrapper {
    top: 100px
}

 

8) Push Menu Bottom

Push bottom menu - меню, которое выдвигается снизу и сдвигает контент вверх и его CSS

Push bottom menu — меню, которое выдвигается снизу и сдвигает контент вверх и его CSS:

nav.push-menu-bottom {
    left: 0;
    width: 100%;
    height: 100px;
}
nav.push-menu-bottom ul {
    text-align: center;
    padding: 25px 0 0 0;
}
nav.push-menu-bottom li {
    display: inline-block;
    margin: 0;
    vertical-align: middle;
}
nav.push-menu-bottom a {
    display: block;
    line-height: 50px;
    padding: 0 10px;
    font-size: 18px;
}
nav.push-menu-bottom button.close-menu {
    display: block;
    line-height: 50px;
    margin: 0;
    padding: 0 10px;
}
nav.push-menu-bottom {
    bottom: -100px
}
body.pmb-open nav.push-menu-bottom {
    bottom: 0
}
body.pmb-open #wrapper {
    top: -100px
}

 

The JavaScript

Теперь давайте взглянем на код JavaScript, чтобы переключать наши классы при нажатии на различные кнопки меню. Мы также будем отображать наши маски для остального контента, и реализовать функционал “закрыть меню”, когда пользователь нажимает маску или кнопку «закрыть меню». Помните, я использую classie.js для добавления и удаления классов. Данный код JavaScript охватывает все восемь меню. Вы, вероятно, захотите облегчить свой JavaScript и убрать все лишнее (конечно, если вы не используете на своем сайте 8 различных меню…). Вот код JavaScript:

(function( window ){

  'use strict';

  var body = document.body,
    mask = document.createElement("div"),
    toggleSlideLeft = document.querySelector( ".toggle-slide-left" ),
    toggleSlideRight = document.querySelector( ".toggle-slide-right" ),
    toggleSlideTop = document.querySelector( ".toggle-slide-top" ),
    toggleSlideBottom = document.querySelector( ".toggle-slide-bottom" ),
    togglePushLeft = document.querySelector( ".toggle-push-left" ),
    togglePushRight = document.querySelector( ".toggle-push-right" ),
    togglePushTop = document.querySelector( ".toggle-push-top" ),
    togglePushBottom = document.querySelector( ".toggle-push-bottom" ),
    slideMenuLeft = document.querySelector( ".slide-menu-left" ),
    slideMenuRight = document.querySelector( ".slide-menu-right" ),
    slideMenuTop = document.querySelector( ".slide-menu-top" ),
    slideMenuBottom = document.querySelector( ".slide-menu-bottom" ),
    pushMenuLeft = document.querySelector( ".push-menu-left" ),
    pushMenuRight = document.querySelector( ".push-menu-right" ),
    pushMenuTop = document.querySelector( ".push-menu-top" ),
    pushMenuBottom = document.querySelector( ".push-menu-bottom" ),
    activeNav
  ;
  mask.className = "mask";

  /* slide menu left */
  toggleSlideLeft.addEventListener( "click", function(){
    classie.add( body, "sml-open" );
    document.body.appendChild(mask);
    activeNav = "sml-open";
  } );

  /* slide menu right */
  toggleSlideRight.addEventListener( "click", function(){
    classie.add( body, "smr-open" );
    document.body.appendChild(mask);
    activeNav = "smr-open";
  } );

  /* slide menu top */
  toggleSlideTop.addEventListener( "click", function(){
    classie.add( body, "smt-open" );
    document.body.appendChild(mask);
    activeNav = "smt-open";
  } );

  /* slide menu bottom */
  toggleSlideBottom.addEventListener( "click", function(){
    classie.add( body, "smb-open" );
    document.body.appendChild(mask);
    activeNav = "smb-open";
  } );

  /* push menu left */
  togglePushLeft.addEventListener( "click", function(){
    classie.add( body, "pml-open" );
    document.body.appendChild(mask);
    activeNav = "pml-open";
  } );

  /* push menu right */
  togglePushRight.addEventListener( "click", function(){
    classie.add( body, "pmr-open" );
    document.body.appendChild(mask);
    activeNav = "pmr-open";
  } );

  /* push menu top */
  togglePushTop.addEventListener( "click", function(){
    classie.add( body, "pmt-open" );
    document.body.appendChild(mask);
    activeNav = "pmt-open";
  } );

  /* push menu bottom */
  togglePushBottom.addEventListener( "click", function(){
    classie.add( body, "pmb-open" );
    document.body.appendChild(mask);
    activeNav = "pmb-open";
  } );

  /* hide active menu if mask is clicked */
  mask.addEventListener( "click", function(){
    classie.remove( body, activeNav );
    activeNav = "";
    document.body.removeChild(mask);
  } );

  /* hide active menu if close menu button is clicked */
  [].slice.call(document.querySelectorAll(".close-menu")).forEach(function(el,i){
    el.addEventListener( "click", function(){
      classie.remove( body, activeNav );
      activeNav = "";
      document.body.removeChild(mask);
    } );
  });

})( window );

Свободный перевод статьи Slide and Push Menus with CSS.

Полезная инфа:

Оставить комментарий