Schro
Schro

Reputation: 185

Trying to create an interactive hamburger menu

I am trying to create a hamburger menu. This is my progress so far: http://codepen.io/Dingerzat/pen/EgAdLN

<div class="bar"></div> 
    <nav>
        <ul role="navigation" class="hidden">
            <li><a href="#">WORK</a></li>
            <li><a href="#">ABOUT</a></li>
            <li><a href="#">RESUME</a></li>
            <li><a href="#">CONTACT</a></li>
        </ul>
    </nav>
</div>
( function () {

    $('.hamburger-menu').on('click', function() {

        $( '.bar' ).toggleClass( 'animate' );
        $( '.bar' ).toggleClass( "on" );
        $( "nav ul" ).toggleClass( 'hidden' );

    } );

} )();
/* SCSS */
@import "compass/css3";

$bar-width: 50px;
$bar-height: 4px;
$bar-spacing: 15px;

body {
    background: #000000;
}

.hamburger-menu {
    position: absolute;
  top: 20px;
  left: 25px;
  margin: auto;
  width: $bar-width;
    height: $bar-height + $bar-spacing*2;
    cursor: pointer;
}

.bar,
.bar:after,
.bar:before {
  width: $bar-width;
    height: $bar-height;
}

.bar {
    position: relative;
    transform: translateY($bar-spacing);
    background: rgba(155, 255, 255, 1);
    transition: all 0ms 300ms;

  &.animate {
    background: rgba(255, 255, 255, 0); 
  }
}

.bar:before {
    content: "";
    position: absolute;
    left: 0;
    bottom: $bar-spacing;
    background: rgba(155, 255, 255, 1);
    transition: bottom 300ms 300ms cubic-bezier(0.23, 1, 0.32, 1), transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
}

.bar:after {
    content: "";
    position: absolute;
    left: 0;
    top: $bar-spacing;
    background: rgba(155, 255, 255, 1);
    transition: top 300ms 300ms cubic-bezier(0.23, 1, 0.32, 1), transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
}

.bar.animate:after {
    top: 0;
    transform: rotate(45deg);
    transition: top 300ms cubic-bezier(0.23, 1, 0.32, 1), transform 300ms 300ms cubic-bezier(0.23, 1, 0.32, 1);;
}

.bar.animate:before {
    bottom: 0;
    transform: rotate(-45deg);
    transition: bottom 300ms cubic-bezier(0.23, 1, 0.32, 1), transform 300ms 300ms cubic-bezier(0.23, 1, 0.32, 1);;
}

nav ul{
  margin: 0;
  padding: 0;
  font-family: Open Sans;
  font-weight: bold;
  font-size: 0.8em;
  list-style: none;
  margin: 4em auto;
  text-align: center;

  &.hidden {
    display: none;
  }

    a {
    @include transition-duration(0.5s);
    text-decoration: none;
    color: white;
    font-size: 3em;
    line-height: 1.5;
    width: 100%;
    display: block;
      &:hover {
        background-color: rgba(0,0,0,0.5);
      }
    }
}

I have been bolting together a few bits of code I like with mixed success.

I want to create something like: https://bert.house/en/

But what I am having issues with, is that when I click on any of my navigation links it closes the menu. Also I am unsure how to get my menu to appear in the centre of the screen over everything else (like on the bert website). I also am unsure how to create the vanishing MENU word at the right side of the burger menu on the bert site.

I am pretty new to this, my html experience prior to this has been building emails rather than actual websites. So any help would be brilliant.

Upvotes: 0

Views: 220

Answers (1)

hungerstar
hungerstar

Reputation: 21675

1) "My navigation links it closes the menu"

That's because your navigation links are inside of .hamburger-menu. The click handler you attached to .hamburger-menu will receive the click event form any element nested within it unless that even is canceled.

To fix this do one of the following:

  1. Move the menu outside of .hamburger-menu.
  2. Cancel the event before it reaches .hamburger-menu. Use event.preventDefault().
  3. Check the source element of the click event and make sure it came from .hamburger-menu and not an element nested within it. Use event.target.

2) "how to get my menu to appear in the center of the screen"

You can use absolute positioning and translation. First you tell it to be 50% from the top of the containing overlay element. Then you nudge the navigation up by 50% of it's height with translation. You do this because top: 50%; places the top edge of the navigation in the middle of the overlay rather than the middle of the navigation in the middle of the overly.

.overlay {
  position: absolute;
  margin: 1.5rem;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  color: #333;
  background-color: #ffcc00;
}
ul,
li {
  margin: 0;
  padding: 0;
}
ul {
  position: absolute;
  top: 50%;
  width: 100%;
  transform: translateY(-50%);
  text-align: center;
}
ul li {
  display: inline;
  margin: 0 0.5rem;
}
<p>
  Something for you to look at.
</p>

<div class="overlay">
  <ul>
    <li><a href="#">One</a>
    </li>
    <li><a href="#">Two</a>
    </li>
    <li><a href="#">Three</a>
    </li>
  </ul>
</div>

3) "I also am unsure how to create the vanishing MENU word"

You need to transition the element's opacity, set it to zero. The text also shifts to the side a little bit so animate it along it's X axis with translateX().

For example:

.text {
    transition: all 350ms ease-in-out;
    transform: translateX( 0 );
}
.show .text {
    opacity: 0;
    transform: translateX( -10px );
}

JS Notes

jQuery is chainable so can change:

$( '.bar' ).toggleClass( 'animate' );
$( '.bar' ).toggleClass( "on" );

to

$( '.bar' ).toggleClass( 'animate' ).toggleClass( "on" );

You can also provide more than once class to toggleClass so you can change:

$( '.bar' ).toggleClass( 'animate' ).toggleClass( "on" );

to

$( '.bar' ).toggleClass( 'animate on' );

I personally like to cache elements so I don't have to query the DOM every time a certain click event happens so I would do something like this:

( function () {

    var $bar   = $( '.bar' );
    var $navUL = $( 'nav ul' );

    $( '.hamburger-menu' ).on( 'click', function () {

        $bar.toggleClass( 'animate on' );
        $navUL.toggleClass( 'hidden' );

    } );

} )();

You likely won't notice a difference in performance on your site but I think it's good practice for situations when you should/need to cache references to elements.

Upvotes: 1

Related Questions