Header

Verze:

17. 02. 2022

Zodpovědná osoba:

Dominik Šlechta

Split header into top and bottom part (header__top, header__bottom) as needed (mostly on e-shops).

We name the components using the grandparent__child, parent__child style. Using "__" multiple times is wrong according to BEM notation.

Hiding certain parts on the phone can be easily done via 2 classes - header__mobile-part, header__desktop-part.

Basic header layout

{* Header - Simple *}

<header class="header js--header">
    <div class="header__content --content --flex">

    </div>
</header>
{* Header - Advanced *}

<header class="header js--header">
    <div class="header__top">
        <div class="header__content --content --flex">

        </div>
    </div>


    <div class="header__bottom">
        <div class="header__content --content --flex">

        </div>
    </div>
</header>

Example in practice

<header class="header js--header">
    <div class="header__content --content --flex --flex-centre-y">
        <a href="/{$lang}" class="header__figure">
            <img class="header__logo" src="/img/logo.svg" alt="Logo">
        </a>
        <div class="header__text --flex-column">
            <a href="tel:+420 555 555 555" class="header__link icon icon--phone">
                +420 555 555 555
                <span class="header__span">
                    (Mon-Fri: 9-17)
                </span>
            </a>
        </div>


        <div class="header__menu js--header-menu">
            <ul class="header__menu-nav menu">
                <li class="menu__item">
                    <a class="menu__link" href="#">Menu Item</a>
                </li>
            
                <li class="menu__item menu__item--dropdown">
                    <a  href="#"
                        class="menu__link">
                        Item name with dropdown
                    </a>
                    <div class="menu__dropdown" id="dropdown_1">
                        <a href="#" class="menu__link menu__dropdown-item">
                                Subitem
                        </a>
                    </div>
                </li>
            </ul>

            <a class="header__button button button--brand" href="/cs/m-2-kontakt#contact-form">
                Order
            </a>

            <div class="header__text --flex-column">
                <a href="tel:+420 555 555 555" class="header__link icon icon--phone">
                    +420 555 555 555
                    <span class="header__span">
                        (Mon-Fri: 9-17)
                    </span>
                </a>
            </div>

        </div>

        <a href="#" class="header__toggler js--header-toggler js--skip-anim">
            <span class="header__toggler-bar"></span>
            <span class="header__toggler-bar"></span>
            <span class="header__toggler-bar"></span>
        </a>
    </div>

</header>

Header

.header {
  padding: 10px 0;
  z-index: 1000;
  position: relative;

  @include media($large) {
    display: flex;
    flex-flow: column wrap;
    padding: 15px 0;
  }
}

.header__content {
  position: static;
}

.header__figure {
  max-width: 200px;

  margin: 0 30px 0 0;
  @include media($xlarge) {
    margin: 0 60px 0 0;
  }
}


.header__logo {
  @include media($xlarge) {
    width: 100%;
  }

}

.header__text{
  display: none;

  @include media($large){
    display: inline-flex;
  }


  .header__menu &{
    display: inline-flex;
    margin: 10px 0 15px 0;

    @include media($large){
      display: none;
    }
  }
}



.header__span {
  font-size: 1.2rem;
  color: #717171;
}

.header__menu {
  margin-left: auto;
  display: none;
  font-family: $font__title;
  font-size: 2rem;
  box-shadow: 0 17px 17px rgb(0 0 0 / 9%);

  @include media($large) {
    display: flex;
    align-items: center;
    box-shadow: none;
    border-bottom: none;
  }
}

.header__menu--active {
  position: absolute;
  left: 0;
  align-items: center;
  right: 0;
  top: 100%;
  background: white;
  display: flex;
  flex-direction: column;
}

.header__button {
  @include media($large) {
    background: $color__primary;
    padding: 15px 30px;
    margin-left: 15px;
    color: white;
  }
}

.header__toggler {
  display: flex;
  flex-direction: column;
  margin-left: auto;
  width: 30px;

  @include media($large) {
    display: none;
  }
}

.header__toggler-bar {
  width: 100%;
  height: 4px;
  background: $color__primary;
  transition: $ease;

  &:not(:last-of-type) {
    margin-bottom: 3px;
  }
  
  .header__toggler--active & {
    position: relative;
    overflow: visible;
  
    &:first-of-type, &:last-of-type {
      margin: auto;
      position: relative;
      top: 0;
      bottom: 0;
    }
  
    &:first-of-type {
      transform: rotate(45deg);
      top: 4px;
    }
  
    &:last-of-type {
      transform: rotate(-45deg);
      bottom: 2px;
    }
  
    &:nth-of-type(2) {
      display: none;
    }
  }
}



Menu

.menu{
  display: flex;
  align-items: center;
  flex-direction: column;


  @include media($large){
    flex-direction: row;
  }

}


.menu__item{
  padding: 0 10px;
  position: relative;

  @include media($xlarge){
    padding: 0 30px;
  }

  &:hover > .menu__dropdown {
    display: block;
  }
}

.menu__item--dropdown {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.menu__link{
  font-size: 1.5rem;
  color: $color__text-dark;
  display: flex;
  padding: 5px;


  &:before {
    color: $color__primary;
  }

  &:hover, &:focus{
    color: $color__primary;
  }


  @include media($large){
    font-size: 2rem;
  }

  .menu__item--dropdown > & {
    position: relative;
    display: flex;
    align-items: center;

    &::after {
      @include pseudo(block, relative);
      line-height: inherit;
      width: 1.2rem;
      height: 1.2rem;
      border: 2px solid transparent;
      border-bottom-color: $color__primary;
      border-right-color: $color__primary;
      transform: rotate(45deg);
      margin-left: 8px;
      margin-bottom: 5px;
    }
  }
}

.menu__dropdown {
  position: relative;
  display: none;
  padding: 1rem;
  background-color: white;

  @include media($large) {
    position: absolute;
    top: 100%;
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
  }
}

Necessary JavaScript

const headerButton = document.querySelector(".js--header-toggler");
const headerMenu = document.querySelector(".js--header-menu");
headerButton.addEventListener("click", function (){
    headerMenu.classList.toggle("header__menu--active");
    headerButton.classList.toggle("header__toggler--active");
});