<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Accordion 2.0</title>
	<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
	<nav class="navigation">
		<header class="navigation__logo">
			<img src="https://s27.postimg.org/p5shqemzn/logo.png" alt="Navigation's logo" width="216" height="39">
		</header>
		<article>
			<ul class="accordion">
				<li class="accordion__item">
					<a href="#" class="accordion__link accordion__link_active">Основы языка и как на нём говорить правильно</a>
					<ul class="sub-accordion">
						<li class="sub-accordion__item">Лексическая структура</li>
						<li class="sub-accordion__item">Типы данных, значения и переменные</li>
						<li class="sub-accordion__item">Выражения и операторы инструкции</li>
					</ul>
				</li>
				<li class="accordion__item">
					<a href="#" class="accordion__link">Функции</a>
					<ul class="sub-accordion">
						<li class="sub-accordion__item">Лексическая структура</li>
						<li class="sub-accordion__item">Типы данных, значения и переменные</li>
						<li class="sub-accordion__item">Выражения и операторы инструкции</li>
					</ul>
				</li>
				<li class="accordion__item">
					<a href="#" class="accordion__link">Обработка ошибок и отладка</a>
					<ul class="sub-accordion">
						<li class="sub-accordion__item">Лексическая структура</li>
						<li class="sub-accordion__item">Типы данных, значения и переменные</li>
						<li class="sub-accordion__item">Выражения и операторы инструкции</li>
					</ul>
				</li>
				<li class="accordion__item">
					<a href="#" class="accordion__link">Объекты и массивы</a>
					<ul class="sub-accordion">
						<li class="sub-accordion__item">Лексическая структура</li>
						<li class="sub-accordion__item">Типы данных, значения и переменные</li>
						<li class="sub-accordion__item">Выражения и операторы инструкции</li>
					</ul>
				</li>
				<li class="accordion__item">
					<a href="#" class="accordion__link">События</a>
					<ul class="sub-accordion">
						<li class="sub-accordion__item">Лексическая структура</li>
						<li class="sub-accordion__item">Типы данных, значения и переменные</li>
						<li class="sub-accordion__item">Выражения и операторы инструкции</li>
					</ul>
				</li>
			</ul>
		</article>
	</nav>
</body>
</html>
* {
    box-sizing: border-box;
}
html,
body {
	font-family: 'Fira Sans', sans-serif;
	font-weight: 500;
	font-size: 100%;
	margin: 0;
	padding:20px;
}
/* 
*	Растягивает картинку на всю ширину блока в котором находится
*/
img {
	width: 100%;
}
/* 
*	Стили для всего меню 
*/
.navigation {
	font-weight: 300;
	font-size: 0.9375rem;
	max-width: 460px;
	min-width: 216px;
	margin: 0 auto;
	color: #696666;
}
/* 
*	Стили для логотипа 
*/
.navigation__logo {
	width: 216px;
	margin: 0 auto;
	padding-bottom: 18px;
}
/* 
*	Стили для основного меню
*	Очищение отступов и сброс стилей по умолчанию 
*/
.accordion,
.sub-accordion {
	margin: 0;
	padding: 0;
	list-style: none;
}
.accordion__item {
	background: #e7e7e7;
	border-radius: 20px;
	margin-bottom: 5px;
}
/* 
*	Стили для заголовка меню 
*/
.accordion__item:nth-child(odd) > :first-child:not(.accordion__link_active) {
    color: #ffffff;
    background: #696666;
}
.accordion__link {
	font-weight: 500;
	font-size: 1rem;
	position: relative;
	color: #696666;
	text-decoration: none;
	border-radius: 20px;
	display: block;
	padding: 12px 50px 12px 20px;
}
.accordion__link:not(.accordion__link_active):after {
	position: absolute;
	content: "";
	border-top: 12px #ff8663 solid;
	border-left: 7px solid transparent;
	border-right: 7px solid transparent;
	right: 22px;
	top: 50%;
	transform: translatey(-6px);
}
.accordion__link:not(.accordion__link_active):hover {
    opacity: .8;
    color: #fff;
    background: #B8B8B8;
}
.accordion__link:not(.accordion__link_active):hover:after {
	border-top: 12px #ffffff solid;
}
/* 
*	Стили для подменю 
*/
.sub-accordion {
	padding: 5px 20px;
    display: none;
    height: 0;
    overflow: hidden;
}
.sub-accordion__item {
	padding: 5px 0;
}
/* 
*	Стили для октивного подменю 
*/
.accordion__link_active {
    color: #ffffff;
    background-color: #ff8663;   
}
.accordion__link_active:after {
	position: absolute;
	content: "";
	border-bottom: 12px #fff solid;
	border-left: 7px solid transparent;
	border-right: 7px solid transparent;
	right: 22px;
	top: 50%;
	transform: translatey(-6px);
}
.accordion__link_active + ul{
    display: block;
    height: 100%;
}
function slide(link) {
  
  var down = function (callback, time) {
    var subMenu = link.nextElementSibling;
    var height = subMenu.clientHeight; 
    var part = height / 100;
    
    var paddingTop = parseInt(window.getComputedStyle(subMenu, null).getPropertyValue('padding-top'));
    var paddingBottom = parseInt(window.getComputedStyle(subMenu, null).getPropertyValue('padding-bottom'));
    var paddingTopPart = parseInt(paddingTop) / 50;
    var paddingBottomPart = parseInt(paddingBottom) / 30;
    
    (function innerFunc(i, t, b) {

      subMenu.style.height = i + 'px';
      
      i += part;
      
      if(t < paddingTop) {
      
        t += paddingTopPart;
        subMenu.style.paddingTop = t + 'px';
          
      } else if(b < paddingBottom) {

        b += paddingBottomPart;
        subMenu.style.paddingBottom = b + 'px';
      }
      
      if(i < height) { 
      
        setTimeout(function() {
            
            innerFunc(i, t, b);
            
        }, time / 100);
          
      } else { 
          
        subMenu.removeAttribute('style');
        callback();
      }
        
    })(0, 0, 0);
  },
  
  up = function (callback, time) {
      
    var subMenu = link.nextElementSibling;
    var height = subMenu.clientHeight; 
    var part = subMenu.clientHeight / 100;
    var paddingTop = parseInt(window.getComputedStyle(subMenu).paddingTop);
    var paddingBottom = parseInt(window.getComputedStyle(subMenu).paddingBottom);
    var paddingTopPart = parseInt(paddingTop) / 30;
    var paddingBottomPart = parseInt(paddingBottom) / 50;

    (function innerFunc(i, t, b) {

      subMenu.style.height = i + 'px';
      
      i -= part;
      i = i.toFixed(2);

      if(b > 0) {
          
        b -= paddingBottomPart;
        b = b.toFixed(1);                
        subMenu.style.paddingBottom = b + 'px';
          
      } else if(t > 0) {
          
        t -= paddingTopPart;
        t = t.toFixed(1); 
        subMenu.style.paddingTop = t + 'px';
      }
      
      if(i > 0) { 
      
        setTimeout(function() {
            
            innerFunc(i, t, b);
            
        }, time / 100);
          
      } else {
          
        subMenu.removeAttribute('style');
        callback(); 
      }
        
    })(height, paddingTop, paddingBottom);
  }
      
  return {
    down: down,
    up: up
  }
} 
    
var accordion = (function() {

    var menu = document.querySelectorAll('.accordion');
    var activeClass = 'accordion__link_active';
    var arr = [];
    var timer = 100;
    
    for(let i = 0; i < menu.length; i++) {

        for(let p = 0; p < menu[i].children.length; p++) {

            var link = menu[i].children[p].firstElementChild;
            
            if(link.classList.contains(activeClass)) {
                arr[i] = link;
            }
        }
    }
       
    function accordionInner(i) {
            
      var clicked = false;
      
      menu[i].addEventListener('click', function(e) {

        if(e.target.tagName === 'A' && !clicked) {

          clicked = true;

          if(e.target.classList.contains(activeClass)) {
              
            slide(e.target).up(function() {
                
              clicked = false;
              
              e.target.classList.remove(activeClass);
              
              console.log('slide up of accordion ' + i + ' is done');
            
            }, timer);
              
          } else {

            if(arr.length > 0) {
                
              slide(arr[i-1]).up(function() {
                  
                arr[i-1].classList.remove(activeClass);
                
                arr[i-1] = e.target;
                
                console.log('slide up of accordion ' + i + ' is done');

              }, timer);
            }

            e.target.classList.add(activeClass);
            
            slide(e.target).down(function() {
              
              clicked = false;
              
              arr[i-1] = e.target;
              
              console.log('slide down of accordion ' + i + ' is done');
            
            }, timer);
          }
        }
      });
      
      i++;
      
      if(i < menu.length) { accordionInner(i); }
        
    } accordionInner(0);
})();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.