├── README.md ├── assets ├── css │ └── styles.css ├── img │ └── perfil.png ├── js │ └── main.js └── scss │ ├── base │ └── _base.scss │ ├── components │ ├── _header.scss │ └── _mediaqueries.scss │ ├── config │ └── _variables.scss │ ├── layout │ └── _layout.scss │ ├── styles.scss │ └── theme │ └── _theme.scss ├── index.html └── preview.png /README.md: -------------------------------------------------------------------------------- 1 | # Responsive Bottom Navigation Bar 2 | ## [Watch it on youtube]() 3 | ### Responsive Bottom Navigation Bar 4 | 5 | - Lower navigation bar using HTML, CSS and JavaScript. 6 | - First design with labels in the navigation bar. 7 | - Second design with points in the navigation bar. 8 | - Smooth scrolling in each section. 9 | - Developed first with the Mobile First methodology, then for desktop. 10 | - Compatible with all mobile devices and with a beautiful and pleasant user interface. 11 | 12 | Join the channel to see more videos like this. [Bedimcode](https://www.youtube.com/c/Bedimcode) 13 | 14 |  15 | -------------------------------------------------------------------------------- /assets/css/styles.css: -------------------------------------------------------------------------------- 1 | /*=============== GOOGLE FONTS ===============*/ 2 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap"); 3 | 4 | /*=============== VARIABLES CSS ===============*/ 5 | :root { 6 | --header-height: 3rem; 7 | 8 | /*========== Colors ==========*/ 9 | --hue: 174; 10 | --sat: 63%; 11 | --first-color: hsl(var(--hue), var(--sat), 40%); 12 | --first-color-alt: hsl(var(--hue), var(--sat), 36%); 13 | --title-color: hsl(var(--hue), 12%, 15%); 14 | --text-color: hsl(var(--hue), 8%, 35%); 15 | --body-color: hsl(var(--hue), 100%, 99%); 16 | --container-color: #FFF; 17 | 18 | /*========== Font and typography ==========*/ 19 | --body-font: 'Open Sans', sans-serif; 20 | --h1-font-size: 1.5rem; 21 | --normal-font-size: .938rem; 22 | --tiny-font-size: .625rem; 23 | 24 | /*========== z index ==========*/ 25 | --z-tooltip: 10; 26 | --z-fixed: 100; 27 | } 28 | 29 | @media screen and (min-width: 968px) { 30 | :root { 31 | --h1-font-size: 2.25rem; 32 | --normal-font-size: 1rem; 33 | } 34 | } 35 | 36 | /*=============== BASE ===============*/ 37 | * { 38 | box-sizing: border-box; 39 | padding: 0; 40 | margin: 0; 41 | } 42 | 43 | html { 44 | scroll-behavior: smooth; 45 | } 46 | 47 | body { 48 | margin: var(--header-height) 0 0 0; 49 | font-family: var(--body-font); 50 | font-size: var(--normal-font-size); 51 | background-color: var(--body-color); 52 | color: var(--text-color); 53 | } 54 | 55 | ul { 56 | list-style: none; 57 | } 58 | 59 | a { 60 | text-decoration: none; 61 | } 62 | 63 | img { 64 | max-width: 100%; 65 | height: auto; 66 | } 67 | 68 | /*=============== REUSABLE CSS CLASSES ===============*/ 69 | .section { 70 | padding: 4.5rem 0 2rem; 71 | } 72 | 73 | .section__title { 74 | font-size: var(--h1-font-size); 75 | color: var(--title-color); 76 | text-align: center; 77 | margin-bottom: 1.5rem; 78 | } 79 | 80 | .section__height { 81 | height: 100vh; 82 | } 83 | 84 | /*=============== LAYOUT ===============*/ 85 | .container { 86 | max-width: 968px; 87 | margin-left: 1rem; 88 | margin-right: 1rem; 89 | } 90 | 91 | /*=============== HEADER ===============*/ 92 | .header { 93 | position: fixed; 94 | top: 0; 95 | left: 0; 96 | width: 100%; 97 | background-color: var(--container-color); 98 | z-index: var(--z-fixed); 99 | transition: .4s; 100 | } 101 | 102 | /*=============== NAV ===============*/ 103 | .nav { 104 | height: var(--header-height); 105 | display: flex; 106 | justify-content: space-between; 107 | align-items: center; 108 | } 109 | 110 | .nav__img { 111 | width: 32px; 112 | border-radius: 50%; 113 | } 114 | 115 | .nav__logo { 116 | color: var(--title-color); 117 | font-weight: 600; 118 | } 119 | 120 | @media screen and (max-width: 767px) { 121 | .nav__menu { 122 | position: fixed; 123 | bottom: 0; 124 | left: 0; 125 | background-color: var(--container-color); 126 | box-shadow: 0 -1px 12px hsla(var(--hue), var(--sat), 15%, 0.15); 127 | width: 100%; 128 | height: 4rem; 129 | padding: 0 1rem; 130 | display: grid; 131 | align-content: center; 132 | border-radius: 1.25rem 1.25rem 0 0; 133 | transition: .4s; 134 | } 135 | } 136 | 137 | .nav__list, 138 | .nav__link { 139 | display: flex; 140 | } 141 | 142 | .nav__link { 143 | flex-direction: column; 144 | align-items: center; 145 | row-gap: 4px; 146 | color: var(--title-color); 147 | font-weight: 600; 148 | } 149 | 150 | .nav__list { 151 | justify-content: space-around; 152 | } 153 | 154 | .nav__name { 155 | font-size: var(--tiny-font-size); 156 | /* display: none;*/ /* Minimalist design, hidden labels */ 157 | } 158 | 159 | .nav__icon { 160 | font-size: 1.5rem; 161 | } 162 | 163 | /*Active link*/ 164 | .active-link { 165 | position: relative; 166 | color: var(--first-color); 167 | transition: .3s; 168 | } 169 | 170 | /* Minimalist design, active link */ 171 | /* .active-link::before{ 172 | content: ''; 173 | position: absolute; 174 | bottom: -.5rem; 175 | width: 4px; 176 | height: 4px; 177 | background-color: var(--first-color); 178 | border-radius: 50%; 179 | } */ 180 | 181 | /* Change background header */ 182 | .scroll-header { 183 | box-shadow: 0 1px 12px hsla(var(--hue), var(--sat), 15%, 0.15); 184 | } 185 | 186 | /*=============== MEDIA QUERIES ===============*/ 187 | /* For small devices */ 188 | /* Remove if you choose, the minimalist design */ 189 | @media screen and (max-width: 320px) { 190 | .nav__name { 191 | display: none; 192 | } 193 | } 194 | 195 | /* For medium devices */ 196 | @media screen and (min-width: 576px) { 197 | .nav__list { 198 | justify-content: center; 199 | column-gap: 3rem; 200 | } 201 | } 202 | 203 | @media screen and (min-width: 767px) { 204 | body { 205 | margin: 0; 206 | } 207 | .section { 208 | padding: 7rem 0 2rem; 209 | } 210 | .nav { 211 | height: calc(var(--header-height) + 1.5rem); /* 4.5rem */ 212 | } 213 | .nav__img { 214 | display: none; 215 | } 216 | .nav__icon { 217 | display: none; 218 | } 219 | .nav__name { 220 | font-size: var(--normal-font-size); 221 | /* display: block; */ /* Minimalist design, visible labels */ 222 | } 223 | .nav__link:hover { 224 | color: var(--first-color); 225 | } 226 | 227 | /* First design, remove if you choose the minimalist design */ 228 | .active-link::before { 229 | content: ''; 230 | position: absolute; 231 | bottom: -.75rem; 232 | width: 4px; 233 | height: 4px; 234 | background-color: var(--first-color); 235 | border-radius: 50%; 236 | } 237 | 238 | /* Minimalist design */ 239 | /* .active-link::before{ 240 | bottom: -.75rem; 241 | } */ 242 | } 243 | 244 | /* For large devices */ 245 | @media screen and (min-width: 1024px) { 246 | .container { 247 | margin-left: auto; 248 | margin-right: auto; 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /assets/img/perfil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bedimcode/responsive-bottom-navigation/b0ab0d6352b1a163d5a50cbcce8448147a5af14a/assets/img/perfil.png -------------------------------------------------------------------------------- /assets/js/main.js: -------------------------------------------------------------------------------- 1 | /*=============== SCROLL SECTIONS ACTIVE LINK ===============*/ 2 | const sections = document.querySelectorAll('section[id]') 3 | 4 | function scrollActive(){ 5 | const scrollY = window.pageYOffset 6 | 7 | sections.forEach(current =>{ 8 | const sectionHeight = current.offsetHeight, 9 | sectionTop = current.offsetTop - 50, 10 | sectionId = current.getAttribute('id') 11 | 12 | if(scrollY > sectionTop && scrollY <= sectionTop + sectionHeight){ 13 | document.querySelector('.nav__menu a[href*=' + sectionId + ']').classList.add('active-link') 14 | }else{ 15 | document.querySelector('.nav__menu a[href*=' + sectionId + ']').classList.remove('active-link') 16 | } 17 | }) 18 | } 19 | window.addEventListener('scroll', scrollActive) 20 | 21 | 22 | /*=============== CHANGE BACKGROUND HEADER ===============*/ 23 | function scrollHeader(){ 24 | const header = document.getElementById('header') 25 | // When the scroll is greater than 80 viewport height, add the scroll-header class to the header tag 26 | if(this.scrollY >= 80) header.classList.add('scroll-header'); else header.classList.remove('scroll-header') 27 | } 28 | window.addEventListener('scroll', scrollHeader) 29 | -------------------------------------------------------------------------------- /assets/scss/base/_base.scss: -------------------------------------------------------------------------------- 1 | /*=============== BASE ===============*/ 2 | *{ 3 | box-sizing: border-box; 4 | padding: 0; 5 | margin: 0; 6 | } 7 | 8 | html{ 9 | scroll-behavior: smooth; 10 | } 11 | 12 | body{ 13 | margin: var(--header-height) 0 0 0; 14 | font-family: var(--body-font); 15 | font-size: var(--normal-font-size); 16 | background-color: var(--body-color); 17 | color: var(--text-color); 18 | } 19 | 20 | ul{ 21 | list-style: none; 22 | } 23 | a{ 24 | text-decoration: none; 25 | } 26 | img{ 27 | max-width: 100%; 28 | height: auto; 29 | } -------------------------------------------------------------------------------- /assets/scss/components/_header.scss: -------------------------------------------------------------------------------- 1 | /*=============== HEADER ===============*/ 2 | .header{ 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | background-color: var(--container-color); 8 | z-index: var(--z-fixed); 9 | transition: .4s; 10 | } 11 | 12 | /*=============== NAV ===============*/ 13 | .nav{ 14 | height: var(--header-height); 15 | display: flex; 16 | justify-content: space-between; 17 | align-items: center; 18 | 19 | &__img{ 20 | width: 32px; 21 | border-radius: 50%; 22 | } 23 | &__logo{ 24 | color: var(--title-color); 25 | font-weight: 600; 26 | } 27 | 28 | @media screen and (max-width: 767px){ 29 | &__menu{ 30 | position: fixed; 31 | bottom: 0; 32 | left: 0; 33 | background-color: var(--container-color); 34 | box-shadow: 0 -1px 12px hsla(var(--hue), var(--sat), 15%, 0.15); 35 | width: 100%; 36 | height: 4rem; 37 | padding: 0 1rem; 38 | display: grid; 39 | align-content: center; 40 | border-radius: 1.25rem 1.25rem 0 0; 41 | transition: .4s; 42 | } 43 | } 44 | 45 | &__list, 46 | &__link{ 47 | display: flex; 48 | } 49 | 50 | &__link{ 51 | flex-direction: column; 52 | align-items: center; 53 | row-gap: 4px; 54 | color: var(--title-color); 55 | font-weight: 600; 56 | } 57 | 58 | &__list{ 59 | justify-content: space-around; 60 | } 61 | &__name{ 62 | font-size: var(--tiny-font-size); 63 | // display: none; // Minimalist design, hidden labels 64 | } 65 | &__icon{ 66 | font-size: 1.5rem; 67 | } 68 | } 69 | 70 | /*Active link*/ 71 | .active-link{ 72 | position: relative; 73 | color: var(--first-color); 74 | transition: .3s; 75 | 76 | // Minimalist design, active link 77 | // &::before{ 78 | // content: ''; 79 | // position: absolute; 80 | // bottom: -.5rem; 81 | // width: 4px; 82 | // height: 4px; 83 | // background-color: var(--first-color); 84 | // border-radius: 50%; 85 | // } 86 | } 87 | 88 | /* Change background header */ 89 | .scroll-header{ 90 | box-shadow: 0 1px 12px hsla(var(--hue), var(--sat), 15%, 0.15); 91 | } -------------------------------------------------------------------------------- /assets/scss/components/_mediaqueries.scss: -------------------------------------------------------------------------------- 1 | /*=============== MEDIA QUERIES ===============*/ 2 | /* For small devices */ 3 | // Remove if you choose, the minimalist design 4 | @media screen and (max-width: 320px){ 5 | .nav__name{ 6 | display: none; 7 | } 8 | } 9 | 10 | /* For medium devices */ 11 | @media screen and (min-width: 576px){ 12 | .nav__list{ 13 | justify-content: center; 14 | column-gap: 3rem; 15 | } 16 | } 17 | 18 | @media screen and (min-width: 767px){ 19 | body{ 20 | margin: 0; 21 | } 22 | 23 | .section{ 24 | padding: 7rem 0 2rem; 25 | } 26 | 27 | .nav{ 28 | height: calc(var(--header-height) + 1.5rem); // 4.5rem 29 | 30 | &__img{ 31 | display: none; 32 | } 33 | &__icon{ 34 | display: none; 35 | } 36 | &__name{ 37 | font-size: var(--normal-font-size); 38 | // display: block; // Minimalist design, visible labels 39 | } 40 | &__link:hover{ 41 | color: var(--first-color); 42 | } 43 | } 44 | 45 | // First design, remove if you choose the minimalist design 46 | .active-link::before{ 47 | content: ''; 48 | position: absolute; 49 | bottom: -.75rem; 50 | width: 4px; 51 | height: 4px; 52 | background-color: var(--first-color); 53 | border-radius: 50%; 54 | } 55 | 56 | // Minimalist design 57 | // .active-link::before{ 58 | // bottom: -.75rem; 59 | // } 60 | 61 | } 62 | 63 | /* For large devices */ 64 | @media screen and (min-width: 1024px){ 65 | .container{ 66 | margin-left: auto; 67 | margin-right: auto; 68 | } 69 | } -------------------------------------------------------------------------------- /assets/scss/config/_variables.scss: -------------------------------------------------------------------------------- 1 | /*=============== GOOGLE FONTS ===============*/ 2 | @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap'); 3 | 4 | /*=============== VARIABLES CSS ===============*/ 5 | :root{ 6 | --header-height: 3rem; 7 | 8 | /*========== Colors ==========*/ 9 | --hue: 174; 10 | --sat: 63%; 11 | 12 | --first-color: hsl(var(--hue), var(--sat), 40%); 13 | --first-color-alt: hsl(var(--hue), var(--sat), 36%); 14 | --title-color: hsl(var(--hue), 12%, 15%); 15 | --text-color: hsl(var(--hue), 8%, 35%); 16 | --body-color: hsl(var(--hue), 100%, 99%); 17 | --container-color: #FFF; 18 | 19 | /*========== Font and typography ==========*/ 20 | --body-font: 'Open Sans', sans-serif; 21 | 22 | --h1-font-size: 1.5rem; 23 | --normal-font-size: .938rem; 24 | --tiny-font-size: .625rem; 25 | 26 | // Responsive typography 27 | @media screen and (min-width: 968px){ 28 | --h1-font-size: 2.25rem; 29 | --normal-font-size: 1rem; 30 | } 31 | 32 | /*========== z index ==========*/ 33 | --z-tooltip: 10; 34 | --z-fixed: 100; 35 | } -------------------------------------------------------------------------------- /assets/scss/layout/_layout.scss: -------------------------------------------------------------------------------- 1 | /*=============== REUSABLE CSS CLASSES ===============*/ 2 | .section{ 3 | padding: 4.5rem 0 2rem; 4 | 5 | &__title{ 6 | font-size: var(--h1-font-size); 7 | color: var(--title-color); 8 | text-align: center; 9 | margin-bottom: 1.5rem; 10 | } 11 | &__height{ 12 | height: 100vh; 13 | } 14 | } 15 | 16 | /*=============== LAYOUT ===============*/ 17 | .container{ 18 | max-width: 968px; 19 | margin-left: 1rem; 20 | margin-right: 1rem; 21 | } -------------------------------------------------------------------------------- /assets/scss/styles.scss: -------------------------------------------------------------------------------- 1 | // Import of partial files 2 | @import 'config/variables'; 3 | @import 'base/base'; 4 | @import 'layout/layout'; 5 | @import 'components/header'; 6 | @import 'components/mediaqueries'; -------------------------------------------------------------------------------- /assets/scss/theme/_theme.scss: -------------------------------------------------------------------------------- 1 | /*=============== THEME ===============*/ -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |