En este HowTo aprenderás a crear un menú lateral responsive desde cero, utilizando jQuery 3> y Sass.
Antes de empezar a crear el menú vamos hacer una recopilación de las tecnologías y técnicas web que vamos a necesitar:
- Haremos uso de HTML5 para crear el documento y las listas del menú.
- Para crear eventos, efectos y cambios de estilos, haremos uso de jQuery 3.3>
- Para la maquetación del menú usaremos CSS + Sass. Esto nos facilitará el manejo y uso de los media queries para hacer el menú responsive.
- Aunque no es necesario utilizaré el framework Fontawesome para incluir los iconos que pueda necesitar el documento.
Todos los ficheros para crear el menú se pueden descargar desde Github.
Previa del menú en ordenador
Previa del menú en móviles y tablets
Cabecera de nuestro documento HTML5
Empezaremos creando la cabecera del documento con sus meta etiquetas, links y scripts a los recursos que vamos a necesitar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<!DOCTYPE html> <html lang="es"> <head> <!-- meta --> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta name="robots" content="noindex" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> <!-- meta info --> <meta name="title" content="default page" /> <!-- styles--> <link rel="stylesheet" id="main-style" href="assets/css/style.css" /> <!-- fontawesome --> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> <!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- Side menu scripts--> <script src="assets/js/jquery.navSide.js"></script> </head> <body> |
Contenido del menú y resto del documento
A continuación vamos a incluir el contenido de nuestro menú responsive (sideNav) y también la correspondientes elementos que componen el documento.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
<nav id="sideNav" class="sideNav"> <div class="container"> <!-- Responsive Icon & Desktop logo--> <a href="#" id="iconClose"><i class="fas fa-window-close fa-2x"></i></i></a> <a href="#" id="headerLogo"><img src="assets/img/Your-Logo-Here.png" title="Your Logo"></a> <div id="search" id="search"> <input type="text" name="search" class="searching" placeholder="Search ... " /> </div> <!-- Main Menu --> <ul class="menu"> <li><a href="topmenu.html">top menu</a></li> <li><a href="sidebar-menu.html">side menu</a></li> <li><a href="#" class="dropdown">Dropdown 1</a> <ul class="nav-dropdown"> <li><a href="#">Submenu 1.1</a></li> <li><a href="#">Submenu 1.2</a></li> <li><a href="#">Submenu 1.3</a></li> <li><a href="#">Submenu 1.4</a></li> <li><a href="#">Submenu 1.5</a></li> <li><a href="#">Submenu 1.6</a></li> </ul> </li> <li><a href="#" class="dropdown">Dropdown 2</a> <ul class="nav-dropdown"> <li><a href="#">Submenu 2.1</a></li> <li><a href="#">Submenu 2.2</a></li> <li><a href="#">Submenu 2.3</a></li> </ul> </li> </ul> <!-- Social menu--> <ul id="social" class="social"> <li class="sozialize"> Let's Sozialize! </li> <li class="social"> <a class="nav-link" href="http://www.linkedin.com/in/jlrojo" target="_blank" title="Linkedin"><i class="fab fa-linkedin"></i></a> </li> <li class="social"> <a class="nav-link" href="https://www.twitter.com/centinela" target="_blank" title="Twitter"><i class="fab fa-twitter"></i></a> </li> <li class="social"> <a class="nav-link" href="https://github.com/jl3377" target="_blank" title="Github"><i class="fab fa-github"></i></a> </li> <li class="social"> <a class="nav-link" href="https://www.facebook.com/joseluis.rojo.7399" target="_blank" title="Facebook"><i class="fab fa-facebook-f"></i></a> </li> </ul> </div> </nav> <div id="main"> <!-- only responsive Top Menu--> <div id="responsiveTopMenu"> <ul> <li id="iconOpen"><a href="#" id="iconOpen"><i class="fas fa-bars fa-2x"></i></a></li> <li id="logo"><a href="#" class="logo"><img src="assets/img/Your-Logo-Here.png" title="Your Logo" /></a></li> </ul> </div><!-- end responsiveTopMenu --> <header id="header"> <div class="container"> <div class="row"> <div class="col-12"> <h1 class="title">Ut aliquip aute et incididunt irure exercitation ex ut irure officia cupidatat do.</h1> <h2>Proident enim dolore ea officia.</h2> </div> </div> </div> </header> <div id="content"> <div class="container"> <div class="row"> <div class="col-12"> <p>Velit proident consectetur eiusmod incididunt esse amet pariatur esse deserunt incididunt tempor irure incididunt ea. Laboris consectetur labore do pariatur velit. Lorem cillum esse culpa nisi occaecat. Excepteur elit cupidatat sunt non cillum. Sunt voluptate ut ad velit Lorem id ad consequat sint tempor. Sunt do labore quis non voluptate sint. Labore non esse tempor consectetur do voluptate et irure cillum incididunt veniam.</p> </div> </div> </div> </div> <footer id="footer"> <div class="container"> <div class="row"> <div class="col-12"> <p>Aliqua magna aliqua do cupidatat fugiat sit officia consectetur. Aliquip excepteur anim esse labore. Esse qui incididunt dolor veniam exercitation velit. Cillum eiusmod aliqua excepteur dolore. Est fugiat eiusmod reprehenderit consectetur eu esse fugiat commodo. Fugiat et voluptate ex ullamco dolor adipisicing enim incididunt exercitation nulla nulla dolor in. Nulla nulla mollit id aliquip ipsum Lorem cillum eu et.</p> </div> </div> </div> </footer> </div> </body> </html> |
Estilos del menú usando Sass
Para poder crear los estilos es importante tener una nociones básicas de cómo trabajar con Sass, para luego saber como compilarlos correctamente. La estructura Sass está disponibles desde GitHub.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
/*------------------------------------------------*\ # Responsive Side Navigation Menu \*------------------------------------------------*/ .sideNav { position: fixed; width:100%; background: hsl(240, 1%, 16%); z-index: 1; height: 75px; // Side Nav menu in responsive mode @include media-query(md){ overflow-x: hidden; height: 100%; width: 0; position: fixed; z-index: 1; top: 0; left: 0; background: hsl(0, 0%, 0%); padding: 60px 0 0 0; transition: 0.5s; } // Close Icon Into Side Menu #iconClose { display: none; // Responsive mode @include media-query(md) { display: initial; position: absolute; top: 15px; right: 15px; color: hsl(0, 0%, 71%); } } // Header logo image #headerLogo { color: #fff; width: 100px; text-align: center; float:left; padding: 15px 10px 0 10px; margin-right: 25px; img { max-height: 50px; } @include media-query(md){ float: left; position: absolute; top: 0; } } // search box #search { display: none; // hide on desktop @include media-query(md) { display: block; margin: 30px 0 0 10px; .searching { padding: 5px 10px; } } } // menu list items ul { float: left; display: inherit; padding: 0; list-style: none; height: auto; border-top: solid hsl(180, 1%, 29%) 1px; @include media-query(md) { margin-top: 25px; padding-top: 15px; } li { float: left; text-align: center; padding: 23px 15px 23px 15px; text-decoration: none; font-size: 1.2rem; position: relative; list-style: none; @include media-query(md) { padding: 8px 8px 8px 15px; text-decoration:none; font-size: 1rem; color: hsl(0, 0%, 0%); display: block; transition: 0.3s; float: left; text-align: left; width: 100%; } a { color: hsl(0, 0%, 71%); &:hover { text-decoration: none; } // submenu with items &.dropdown { // showing arrow down &:after{ content: ""; margin:0 0.5em; display:inline-block; border: 7px solid transparent; border-top:8px solid hsl(0, 0%, 50%); border-bottom:0 none; } } } &:hover { color: hsl(0, 0%, 0%); background: hsl(0, 0%, 32%); @include media-query(md){ background: transparent; } // show submenu list on over > ul { display: block; @include media-query(md) { // hide dropdown only responsive display:none; } } } } // end </li> // second level menu ul { display:none; position:absolute; top:100%; left:0; padding:0; @include media-query(md){ border: 0; margin: 0; } // dropdown navigation menu static at responsive mode &.nav-dropdown { @include media-query(md){ position: static; } } li { float: none; display: inline-block; width: 100%; background: hsl(240, 1%, 16%); text-align: left; cursor: pointer; @include media-query(md) { background: transparent; padding: 15px 0 0; } a { color: hsl(0, 0%, 71%); line-height: 120%; @include media-query(md) { color: hsl(219, 64%, 71%); } } } // thirtd level ul { top: 0; left:100%; } } .hide { display:block!important; } } // end first </ul> #social { float: right; @include media-query(md) { position: static; padding-top: 15px; width: 100%; margin-top: 0; } li { &.social { @include media-query(md){ display: inline; width: auto; text-align: center; padding: 10px 10px 0 15px; } } &.sozialize { color: hsl(0, 6%, 80%); &:hover { background:transparent; } } } } // social } #main { transition: margin-left 0.5s; // responsive Top Menu #responsiveTopMenu { display: none; // Icon to Open Menu #iconOpen { display: none; // Show only in responsive mode @include media-query(md) { display: initial; color: hsl(0, 0%, 71%); } } #sharebuttons { display:none; } @include media-query(md){ display: initial; position: fixed; background: hsl(0, 0%, 0%); width: 100%; z-index: 111111; height: 80px; ul { list-style: none; height: auto; overflow: hidden; margin: 0; padding: 0; height: 70px; li { float: left ; } #iconOpen { position: absolute; right: 15px; top: 13px; } #logo { padding: 15px 0 0 25px; img { height: 50px; } } #sharebuttons { display:initial; } } } } // responsiveTopMenu } |
Los breakpoints que tengo declarados son idénticos o muy parecidos a los que usa el framework Bootstrap. Por lo que si queremos que funcione correctamente haremos uso del siguiente mixin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// breakpoints media queries $breakpoints: ( 'xs': 576px, 'sm': 768px, 'md': 992px, 'lg': 1200px ); $orientations: ( 'portrait': portrait, 'landscape': landscape ); // mixim media queries @mixin media-query($breakpoint) { // check if the key exist into the map @if(map-has-key($breakpoints, $breakpoint)) { $value: map-get($breakpoints, $breakpoint); @media (max-width: $value){ @content; } } @warn "Cant find `#{$breakpoint}` in $breakpoints"; } |
Por último vamos a incluir los scripts creados con jQuery
Haciendo uso de jQuery incluimos eventos al abrir y cerrar menús, eventos para desplegar submenús y efectos para redimensionar el menú y mover iconos de redes sociales cuando el usuario hacer scroll en la página. Es todo muy personalizable según el gusto de cada uno.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
$(document).ready(function(){ // reload on resize page $(window).resize(function() { location.reload(); }); // operations to open menu $("#iconOpen").click(function() { $("#sideNav").css('width', "+=275"); $("body").css('background-color', "rgba(0,0,0,0.4)"); $("#responsiveTopMenu").css('display', 'none'); }); // operations to close menu $("#iconClose").click(function() { $("#sideNav").css('width', "0"); $("#main").css('margin-left', "0"); $("body").css('background-color', "rgb(255,255,255, .4)"); $("#iconOpen").css('display', 'initial'); $("#responsiveTopMenu").css('display', 'initial'); // hide submenu on click }); // open close nav-dropdown $('#sideNav ul li a:not(:only-child)').click(function(e) { $(this).siblings('.nav-dropdown').toggle(); // Close one dropdown when selecting another $('.nav-dropdown').not($(this).siblings()).hide(); e.stopPropagation(); }); // Clicking away from dropdown will remove the dropdown class $('html').click(function() { $('.nav-dropdown').hide(); }); // shrink navbar on scroll $( window ).scroll(function() { // user scrolling > 100px if ($(window).scrollTop() > 100) { $("#responsiveTopMenu").css( { "height": "50px" }); $("#responsiveTopMenu ul #iconOpen").css ({ "top": "6px" }); $("#responsiveTopMenu ul li#logo").css ({ "padding-top": "10px", "margin-right": "25px" }); $("#responsiveTopMenu ul li#logo img").css ({ "padding": "0px", "margin": "-10px 0", "height": "40px", "transition": "all 1.5s" }); // move social icons on scroll down menu to top menu $("#social li.social").appendTo('#responsiveTopMenu ul'); $("#responsiveTopMenu ul li.social").css ({ "padding": "15px 0px 0px 15px" }); } // restore default size if ($(window).scrollTop() < 100) { $("#responsiveTopMenu").css( { "height": "80px", "transition": "all 1.5s" }); $("#responsiveTopMenu ul #iconOpen").css ({ "top": "13px", "right": "15px", "transition": "all 1.5s" }); $("#responsiveTopMenu ul li#logo").css ({ "padding-top": "15px" }); $("#responsiveTopMenu ul li#logo img").css ({ "padding": "0px", "margin": "0", "height": "50px", "transition": "all 1.5s" }); // move social icons to side bar $("li.social").appendTo('#social'); } }); }); |
… previsualización del menú desde jsFiddle