├── .vscode └── settings.json ├── assets ├── arrow.svg └── menu.svg ├── css └── estilos.css ├── index.html └── js └── app.js /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /assets/arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /css/estilos.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;700&display=swap'); 2 | 3 | 4 | *{ 5 | margin: 0; 6 | padding: 0; 7 | box-sizing: border-box; 8 | } 9 | 10 | body{ 11 | font-family: 'Poppins', sans-serif; 12 | } 13 | 14 | .menu{ 15 | background-color: #1A202C; 16 | color: #fff; 17 | height: 70px; 18 | } 19 | 20 | .menu__container{ 21 | display: flex; 22 | justify-content: space-between; 23 | align-items: center; 24 | width: 90%; 25 | max-width: 1200px; 26 | height: 100%; 27 | margin: 0 auto; 28 | } 29 | 30 | .menu__links{ 31 | height: 100%; 32 | transition: transform .5s; 33 | display: flex; 34 | } 35 | 36 | .menu__item{ 37 | list-style: none; 38 | position: relative; 39 | height: 100%; 40 | --clip: polygon(0 0, 100% 0, 100% 0, 0 0); 41 | --transform: rotate(-90deg); 42 | } 43 | 44 | .menu__item:hover{ 45 | --clip: polygon(0 0, 100% 0, 100% 100%, 0% 100%); 46 | --transform: rotate(0); 47 | } 48 | 49 | .menu__link{ 50 | color: #fff; 51 | text-decoration: none; 52 | padding: 0 30px; 53 | display: flex; 54 | height: 100%; 55 | align-items: center; 56 | } 57 | 58 | .menu__link:hover{ 59 | background-color: #5e7094; 60 | } 61 | 62 | 63 | .menu__arrow{ 64 | transform: var(--transform); 65 | transition: transform .3s; 66 | display: block; 67 | margin-left: 3px; 68 | } 69 | 70 | .menu__nesting{ 71 | list-style: none; 72 | transition:clip-path .3s; 73 | clip-path: var(--clip); 74 | position: absolute; 75 | right: 0; 76 | bottom: 0; 77 | width: max-content; 78 | transform: translateY(100%); 79 | background-color: #000; 80 | } 81 | 82 | .menu__link--inside{ 83 | padding: 30px 100px 30px 20px; 84 | } 85 | 86 | .menu__link--inside:hover{ 87 | background-color: #798499; 88 | } 89 | 90 | .menu__hamburguer{ 91 | height: 100%; 92 | display: flex; 93 | align-items: center; 94 | padding: 0 15px; 95 | cursor: pointer; 96 | display: none; 97 | } 98 | 99 | .menu__img{ 100 | display: block; 101 | width: 36px; 102 | } 103 | 104 | @media (max-width:800px){ 105 | .menu__hamburguer{ 106 | display: flex; 107 | } 108 | 109 | .menu__item{ 110 | --clip:0; 111 | overflow:hidden ; 112 | } 113 | 114 | .menu__item--active{ 115 | --transform: rotate(0); 116 | --background: #5e7094; 117 | } 118 | 119 | .menu__item--show{ 120 | background-color: var(--background); 121 | } 122 | 123 | 124 | .menu__links{ 125 | position: fixed; 126 | max-width: 400px; 127 | width: 100%; 128 | top: 70px; 129 | bottom: 0; 130 | right: 0; 131 | background-color: #000; 132 | overflow-y: auto; 133 | display: grid; 134 | grid-auto-rows: max-content; 135 | transform: translateX(100%); 136 | } 137 | 138 | .menu__links--show{ 139 | transform: unset; 140 | width: 100%; 141 | } 142 | 143 | .menu__link{ 144 | padding: 25px 0; 145 | padding-left: 30px; 146 | height: auto; 147 | } 148 | 149 | .menu__arrow{ 150 | margin-left: auto; 151 | margin-right: 20px; 152 | } 153 | 154 | .menu__nesting{ 155 | display: grid; 156 | position: unset; 157 | width: 100%; 158 | transform: translateY(0); 159 | height: 0; 160 | transition: height .3s; 161 | } 162 | 163 | .menu__link--inside{ 164 | width: 90%; 165 | margin-left: auto; 166 | border-left: 1px solid #798499; 167 | } 168 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Menu desplegable 8 | 9 | 10 | 11 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | const listElements = document.querySelectorAll('.menu__item--show'); 3 | const list = document.querySelector('.menu__links'); 4 | const menu = document.querySelector('.menu__hamburguer'); 5 | 6 | const addClick = ()=>{ 7 | listElements.forEach(element =>{ 8 | element.addEventListener('click', ()=>{ 9 | 10 | 11 | let subMenu = element.children[1]; 12 | let height = 0; 13 | element.classList.toggle('menu__item--active'); 14 | 15 | 16 | if(subMenu.clientHeight === 0){ 17 | height = subMenu.scrollHeight; 18 | } 19 | 20 | subMenu.style.height = `${height}px`; 21 | 22 | }); 23 | }); 24 | } 25 | 26 | const deleteStyleHeight = ()=>{ 27 | listElements.forEach(element=>{ 28 | 29 | if(element.children[1].getAttribute('style')){ 30 | element.children[1].removeAttribute('style'); 31 | element.classList.remove('menu__item--active'); 32 | } 33 | 34 | }); 35 | } 36 | 37 | 38 | window.addEventListener('resize', ()=>{ 39 | if(window.innerWidth > 800){ 40 | deleteStyleHeight(); 41 | if(list.classList.contains('menu__links--show')) 42 | list.classList.remove('menu__links--show'); 43 | 44 | }else{ 45 | addClick(); 46 | } 47 | }); 48 | 49 | if(window.innerWidth <= 800){ 50 | addClick(); 51 | } 52 | 53 | menu.addEventListener('click', ()=> list.classList.toggle('menu__links--show')); 54 | 55 | 56 | 57 | })(); 58 | 59 | --------------------------------------------------------------------------------