Header
21 Sep 2022
<header class="header fixed">
<div class="cont">
<div class="navbar">
<a href="./index.html" class="logo">
<img src="./images/logo.svg" alt="" />
</a>
<nav class="navbar-nav nav-slide-right">
<ul class="menu">
<li class="menu-item">
<a class="menu-link" href="./index.html">Home</a>
</li>
<li class="menu-item">
<a class="menu-link" href="./about-us.html">About Us</a>
</li>
<li class="menu-item dropdown">
<a class="menu-link dropdown-toggle" href="./job-search.html"
>Job Board</a
>
<ul class="dropdown-menu">
<li><a class="menu-link" href="/">engineering</a></li>
<li><a class="menu-link" href="/">software & it</a></li>
</ul>
</li>
<li class="menu-item">
<a class="menu-link" href="./insights.html">Insights Hub</a>
</li>
<li class="menu-item dropdown">
<a class="menu-link dropdown-toggle" href="./meet-the-team.html"
>Meet the team</a
>
<ul class="dropdown-menu">
<li><a class="menu-link" href="/">engineering</a></li>
<li><a class="menu-link" href="/">software & it</a></li>
<li><a class="menu-link" href="/">engineering</a></li>
<li><a class="menu-link" href="/">software & it</a></li>
<li><a class="menu-link" href="/">engineering</a></li>
<li><a class="menu-link" href="/">software & it</a></li>
<li><a class="menu-link" href="/">engineering</a></li>
<li><a class="menu-link" href="/">software & it</a></li>
</ul>
</li>
<li class="menu-item">
<a class="menu-link" href="./client-hub.html">Client Hub</a>
</li>
<li class="menu-item">
<a class="menu-link" href="./contact-us.html">Contact Us</a>
</li>
<li class="menu-item">
<a class="menu-link" href="./usecases.html">Use Cases</a>
</li>
</ul>
</nav>
<div class="burger menu-toggle">
<span></span>
</div>
</div>
</div>
</header>
<div class="header-close-wrapper"></div>
/*----------------------- Common desktop header -----------------------*/
.header {
position: absolute;
transition: background ease-in-out 0.25s, height ease-in-out 0.25s;
width: 100%;
top: 0;
left: 0;
right: 0;
z-index: 999;
height: ac(120px, 75px);
padding: ac(25px, 15px) 0;
display: flex;
align-items: center;
&.absolute {
position: absolute;
}
&.fixed {
position: fixed;
}
&.scrolled {
background: rgba(var(--black-rgb), 0.8);
backdrop-filter: blur(10px);
height: ac(100px, 60px);
.logo {
width: ac(130px, 60px);
}
}
.logo {
height: 100%;
width: ac(100px, 70px);
flex-shrink: 0;
&::before {
display: none;
}
&:hover {
transform: scale(1.06);
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
.burger {
display: none;
}
.navbar-nav {
display: flex;
flex-grow: 1;
}
.menu {
width: 100%;
display: flex;
justify-content: flex-end;
}
.menu-item {
margin-right: 20px;
position: relative;
&.dropdown {
& > .menu-link {
display: inline-flex;
justify-content: space-between;
align-items: center;
&::after {
content: "\e999";
font-family: "icomoon";
font-size: ac(10px, 8px);
padding-left: 10px;
}
}
}
}
&:not(.header-mobile) {
.menu-item {
@media (min-width: $mobile-menu-end-point) {
padding: 5px 0;
}
&:hover {
@media (min-width: $mobile-menu-end-point) {
.dropdown-menu {
display: block;
}
}
}
}
}
.menu-link {
position: relative;
font-size: ac(16px, 14px);
@include transition-all;
&::before {
content: "";
position: absolute;
bottom: 0;
right: 0;
width: 0;
height: 2px;
background: var(--white);
@include transition-all;
}
&:hover {
color: var(--primary);
&::before {
width: 100%;
left: 0;
background: var(--primary);
}
}
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
min-width: 100%;
padding: 10px 10px 10px 15px;
border-radius: 10px;
background: var(--bg-second);
box-sizing: content-box;
display: none;
li {
.menu-link {
padding: 5px 0;
text-transform: capitalize;
}
}
}
}
/* end of Common desktop header */
/*----------------------- Common desktop header Mobile HEADER -----------------------*/
@media (max-width: $mobile-menu-start-point) {
.header:not(.header-mobile) {
.burger,
.menu-toggle {
display: flex;
}
.navbar-nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100vh;
min-width: 320px;
padding-top: 100px;
background: var(--bg-second);
padding-right: 5px;
padding-bottom: 40px;
transition: transform 0.3s ease-out;
&.nav-slide-left {
right: auto;
left: 0;
transform: translateX(-100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-right {
right: 0;
left: auto;
transform: translateX(100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-down {
right: auto;
left: 0;
transform: translateY(-100%);
&.active {
transform: translateY(0);
}
}
&.nav-slide-up {
right: auto;
left: 0;
transform: translateY(100%);
&.active {
transform: translateY(0);
}
}
.menu {
width: 100%;
max-height: 100%;
overflow-y: auto;
flex-direction: column;
justify-content: flex-start;
padding-left: 40px;
align-items: flex-start;
align-self: center;
&::-webkit-scrollbar {
width: 3px;
height: 2px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
border-radius: 3px;
cursor: pointer;
}
}
.menu-link {
padding: 10px 0;
font-size: ac(30px, 22px);
}
}
.dropdown-menu {
position: relative;
top: 0;
}
}
}
/* end of Common desktop header Mobile HEADER */
/*----------------------- ONLY Mobile HEADER -----------------------*/
.header.header-mobile {
.burger {
display: flex;
}
.navbar-nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100vh;
min-width: 320px;
padding-top: 100px;
background: var(--bg-second);
padding-right: 5px;
padding-bottom: 40px;
transition: transform 0.3s ease-out;
&.nav-slide-left {
right: auto;
left: 0;
transform: translateX(-100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-right {
right: 0;
left: auto;
transform: translateX(100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-down {
right: auto;
left: 0;
transform: translateY(-100%);
&.active {
transform: translateY(0);
}
}
&.nav-slide-up {
right: auto;
left: 0;
transform: translateY(100%);
&.active {
transform: translateY(0);
}
}
.menu {
width: 100%;
max-height: 100%;
overflow-y: auto;
flex-direction: column;
justify-content: flex-start;
padding-left: 40px;
align-items: flex-start;
align-self: center;
&::-webkit-scrollbar {
width: 3px;
height: 2px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
border-radius: 3px;
cursor: pointer;
}
}
.menu-link {
padding: 10px 0;
font-size: ac(25px, 18px);
}
}
.dropdown-menu {
position: relative;
top: 0;
}
}
/* end of ONLY Mobile HEADER */
/*----------------------- HEADER COMPONENTS -----------------------*/
.burger,
.menu-toggle {
position: relative;
flex-direction: column;
justify-content: center;
cursor: pointer;
width: ac(48px, 36px, 375, 1025);
height: 16px;
display: flex;
span {
width: 100%;
height: 2px;
background: var(--white);
transition: all 0.1s;
position: relative;
&::before,
&::after {
position: absolute;
content: "";
left: 0;
width: 100%;
height: 2px;
background: var(--white);
transition: all 0.1s;
}
&::before {
top: -10px;
}
&::after {
bottom: -10px;
}
}
@include transition-all;
@include min-media(1025) {
&:hover {
transform: scale(1.1);
}
}
&.active {
height: 40px;
span {
background: transparent;
&::before {
top: 0;
transform: rotate(-45deg);
}
&::after {
top: 0;
transform: rotate(45deg);
}
}
&:hover {
height: 40px;
}
}
}
.header-close-wrapper {
position: fixed;
width: 100%;
height: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 77;
background: rgba(0, 0, 0, 0.7);
pointer-events: none;
visibility: hidden;
opacity: 0;
@include transition-all;
&.active {
visibility: visible;
pointer-events: auto;
opacity: 1;
cursor: pointer;
}
}
/* end of HEADER COMPONENTS*/
/*----------------------- Common desktop header -----------------------*/
.header {
position: absolute;
transition: background ease-in-out 0.25s, height ease-in-out 0.25s;
width: 100%;
top: 0;
left: 0;
right: 0;
z-index: 999;
height: ac(120px, 75px);
padding: ac(25px, 15px) 0;
display: flex;
align-items: center;
&.absolute {
position: absolute;
}
&.fixed {
position: fixed;
}
&.scrolled {
background: rgba(var(--black-rgb), 0.8);
backdrop-filter: blur(10px);
height: ac(100px, 60px);
.logo {
width: ac(130px, 60px);
}
}
.logo {
height: 100%;
width: ac(100px, 70px);
flex-shrink: 0;
&::before {
display: none;
}
&:hover {
transform: scale(1.06);
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
.burger {
display: none;
}
.navbar-nav {
display: flex;
flex-grow: 1;
}
.menu {
width: 100%;
display: flex;
justify-content: flex-end;
justify-content: flex-end;
justify-content: flex-end;
}
.menu-item {
margin-right: 20px;
position: relative;
&.dropdown {
& > .menu-link {
display: inline-flex;
justify-content: space-between;
align-items: center;
&::after {
content: "\e999";
font-family: "icomoon";
font-size: ac(10px, 8px);
padding-left: 10px;
}
}
}
}
&:not(.header-mobile) {
.menu-item {
@media (--mobile-menu-end-point) {
padding: 5px 0;
}
&:hover {
@media (--mobile-menu-end-point) {
.dropdown-menu {
display: block;
}
}
}
}
}
.menu-link {
position: relative;
font-size: ac(16px, 14px);
@mixin transition-all;
&::before {
content: "";
position: absolute;
bottom: 0;
right: 0;
width: 0;
height: 2px;
background: var(--white);
@mixin transition-all;
}
&:hover {
color: var(--primary);
&::before {
width: 100%;
left: 0;
background: var(--primary);
}
}
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
min-width: 100%;
padding: 10px 10px 10px 15px;
border-radius: 10px;
background: var(--bg-second);
box-sizing: content-box;
display: none;
li {
.menu-link {
padding: 5px 0;
text-transform: capitalize;
}
}
}
}
/* end of Common desktop header */
/*----------------------- Common desktop header Mobile HEADER -----------------------*/
@media (--mobile-menu-start-point) {
.header:not(.header-mobile) {
.burger,
.menu-toggle {
display: flex;
}
.navbar-nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100vh;
min-width: 320px;
padding-top: 100px;
background: var(--bg-second);
padding-right: 5px;
padding-bottom: 40px;
transition: transform 0.3s ease-out;
&.nav-slide-left {
right: auto;
left: 0;
transform: translateX(-100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-right {
right: 0;
left: auto;
transform: translateX(100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-down {
right: auto;
left: 0;
transform: translateY(-100%);
&.active {
transform: translateY(0);
}
}
&.nav-slide-up {
right: auto;
left: 0;
transform: translateY(100%);
&.active {
transform: translateY(0);
}
}
.menu {
width: 100%;
max-height: 100%;
overflow-y: auto;
flex-direction: column;
justify-content: flex-start;
padding-left: 40px;
align-items: flex-start;
align-self: center;
&::-webkit-scrollbar {
width: 3px;
height: 2px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
border-radius: 3px;
cursor: pointer;
}
}
.menu-link {
padding: 10px 0;
font-size: ac(30px, 22px);
}
}
.dropdown-menu {
position: relative;
position: relative;
top: 0;
}
}
}
/* end of Common desktop header Mobile HEADER */
/*----------------------- ONLY Mobile HEADER -----------------------*/
.header.header-mobile {
.burger {
display: flex;
}
.navbar-nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100vh;
min-width: 320px;
padding-top: 100px;
background: var(--bg-second);
padding-right: 5px;
padding-bottom: 40px;
transition: transform 0.3s ease-out;
&.nav-slide-left {
right: auto;
left: 0;
transform: translateX(-100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-right {
right: 0;
left: auto;
transform: translateX(100%);
&.active {
transform: translateX(0);
}
}
&.nav-slide-down {
right: auto;
left: 0;
transform: translateY(-100%);
&.active {
transform: translateY(0);
}
}
&.nav-slide-up {
right: auto;
left: 0;
transform: translateY(100%);
&.active {
transform: translateY(0);
}
}
.menu {
width: 100%;
max-height: 100%;
overflow-y: auto;
flex-direction: column;
justify-content: flex-start;
padding-left: 40px;
align-items: flex-start;
align-self: center;
&::-webkit-scrollbar {
width: 3px;
height: 2px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.5);
border-radius: 3px;
cursor: pointer;
}
}
.menu-link {
padding: 10px 0;
font-size: ac(25px, 18px);
}
}
.dropdown-menu {
position: relative;
top: 0;
}
}
/* end of ONLY Mobile HEADER */
/*----------------------- HEADER COMPONENTS -----------------------*/
.burger,
.menu-toggle {
position: relative;
flex-direction: column;
justify-content: center;
cursor: pointer;
width: ac(48px, 36px, 375, 1025);
height: 16px;
display: flex;
span {
width: 100%;
height: 2px;
background: var(--white);
transition: all 0.1s;
position: relative;
&::before,
&::after {
position: absolute;
content: "";
left: 0;
width: 100%;
height: 2px;
background: var(--white);
transition: all 0.1s;
}
&::before {
top: -10px;
}
&::after {
bottom: -10px;
}
}
@mixin transition-all;
@mixin min-media 1025 {
&:hover {
transform: scale(1.1);
}
}
&.active {
height: 40px;
span {
background: transparent;
&::before {
top: 0;
transform: rotate(-45deg);
}
&::after {
top: 0;
transform: rotate(45deg);
}
}
&:hover {
height: 40px;
}
}
}
.header-close-wrapper {
position: fixed;
width: 100%;
height: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 77;
background: rgba(0, 0, 0, 0.7);
pointer-events: none;
visibility: hidden;
opacity: 0;
@mixin transition-all;
&.active {
visibility: visible;
pointer-events: auto;
opacity: 1;
cursor: pointer;
}
}
/* end of HEADER COMPONENTS*/
const header = document.getElementsByClassName(`header`)[0];
// Header scroll
const scrollContainer = () => {
return document.documentElement || document.body;
};
document.addEventListener("scroll", () => {
if (scrollContainer().scrollTop > 200) {
header.classList.add("scrolled");
} else if (scrollContainer().scrollTop == 0) {
header.classList.remove("scrolled");
}
});
// menu handlers
///check mobile menu show/hide condition
const mobileMenuStartPoint = +getComputedStyle(
document.documentElement
).getPropertyValue("--mobile-menu-start-point");
let isMobileMenuEnable =
$(window).outerWidth() <= mobileMenuStartPoint ||
$(".header-mobile").length;
$(".dropdown-toggle").click(function (e) {
if (isMobileMenuEnable) {
//close all opened sub menu
$(".menu-item.dropdown.active .dropdown-menu").slideUp({
complete: function () {
$(this).closest(".dropdown").removeClass("active");
},
});
//open current submenu
$(this).closest(".menu-item.dropdown").toggleClass("active");
if ($(this).closest(".menu-item.dropdown").hasClass("active")) {
e.preventDefault();
$(this).next(".dropdown-menu").slideDown();
}
}
});
// toggle menu handler
function menuToggle() {
$(".menu-toggle").toggleClass("active");
$(".navbar-nav").toggleClass("active");
$(".header-close-wrapper").toggleClass("active");
// LockScroll when burger open and enable when closed and enable scroll on menu
scrollLock.getScrollState()
? scrollLock.disablePageScroll(
document.querySelector(".navbar-nav .menu")
)
: scrollLock.enablePageScroll();
}
//menu update function
function updateMenu() {
isMobileMenuEnable =
$(window).outerWidth() <= mobileMenuStartPoint ||
$(".mobile-header").length;
if (!isMobileMenuEnable) {
$(".dropdown-menu").css("display", "");
$(".header-close-wrapper").removeClass("active");
$(".menu-item.active").removeClass("active");
$(".navbar-nav").removeClass("active");
$(".menu-toggle").removeClass("active");
// LockScroll when burger open and enable when closed
scrollLock.enablePageScroll();
}
}
$(window).on("resize orientationchange", updateMenu);
// end of toggle menu handler
$(".menu-toggle").click(menuToggle); //menu toggles
$(".header-close-wrapper").click(menuToggle); //menu toggles
У модулі присутні 2-поведінки для header:
1- десктопна версія яка адаптується на певному брейкпоінті котрий задається у файлі variables.pcss три змінні --mobile-menu-start-point, @custom-media --mobile-menu-end-point, @custom-media --mobile-menu-end-point;
2- версія для мобілок, для ініціалізації потрібно до .header на етапі верстки додати клас .header-mobile;
Також для header передбачено дві поведінки позиціонування це absolute (default) i fixed. Для fixed потрібно до header на етапі верстки додати клас .fixed
Меню:
- Десктопне меню адаптується на певному брейкпоінті заданому у variables.pcss (--mobile-menu-start-point... 3шт), котрі можна міняти згідно поставленої задачі.
- Мобільне меню має 4 варіанти появи на екрані, які визначають класи котрі потрібно додати на етапі верстки до nav.navbar-nav один з перелічених класів : nav-slide-left, nav-slide-right, nav-slide-down, nav-slide-up.
У variables.pcss додати якщо не мітиться в збірці:
:root{
/* --mobile-menu-start-point and @custom-media --mobile-menu-start-point must be the same*/
--mobile-menu-start-point: 1200;}
/* --mobile-menu-start-point and @custom-media --mobile-menu-start-point must be the same*/
@custom-media --mobile-menu-start-point (max-width: 1200px);
/*--mobile-menu-end-point must be greater than 1 of the --mobile-menu-start-point and @custom-media --mobile-menu-start-point*/
@custom-media --mobile-menu-end-point (min-width: 1201px);
}
JS працює адаптивно відповідно до попередньо заданих брейкпоінтів у variables.pcss
Також потрібно піключити js скрітр scroll-lock-min.js