Stripe Navigation : Mẫu menu cực cool với jQuery

30/03/2017

Cách đây vài tuần , trong khi mình lang thang trên Internet thì bắt gặp một mẫu menu rất cool, ngay lập tức mình đã save lại và hôm nay mình sẽ chia sẻ cho các bạn cách làm menu này . Các bạn hoàn toàn có thể áp dụng mẫu này vào ngay trong trang web/blog của các bạn.

Stripe Navigation : Mẫu menu cực cool với jQuery

Xem Demo | Download

HTML

Cấu trúc HTML sẽ gồm có 2 phần chính : nav.main-nav cho các menu trên cùng, và  div.morph-dropdown-wrapper sẽ là nơi chứa các menu con.

<header class="cd-morph-dropdown">
	<a href="#0" class="nav-trigger">Open Nav<span aria-hidden="true"></span></a>
	
	<nav class="main-nav">
		<ul>
			<li class="has-dropdown gallery" data-content="about">
				<a href="#0">About</a>
			</li>
 
			<li class="has-dropdown links" data-content="pricing">
				<a href="#0">Pricing</a>
			</li>
 
			<li class="has-dropdown button" data-content="contact">
				<a href="#0">Contact</a>
			</li>
		</ul>
	</nav>
	
	<div class="morph-dropdown-wrapper">
		<div class="dropdown-list">
			<ul>
				<li id="about" class="dropdown gallery">
					<!-- dropdown content here -->
				</li>
 
				<li id="pricing" class="dropdown links">
					<!-- dropdown content here -->
				</li>
 
				<li id="contact" class="dropdown button">
					<!-- dropdown content here -->
				</li>
			</ul>
 
			<div class="bg-layer" aria-hidden="true"></div>
		</div> <!-- dropdown-list -->
	</div> <!-- morph-dropdown-wrapper -->
</header>

CSS

Trong phần định dạng CSS , chúng ta sẽ khai báo thêm một số class không có ở phần html, những class này sẽ được tự động chèn vào khi người dùng rê chuột vào menu, và tính năng này được thực hiện bởi đoạn jQuery mà chúng ta sẽ xem ở phần sau.

/* -------------------------------- 

Primary style

-------------------------------- */
*, *::after, *::before {
  box-sizing: border-box;
}

html {
  font-size: 62.5%;
}

body {
  font-size: 1.6rem;
  font-family: "Lato", sans-serif;
  color: #1A1A1A;
  background-color: #FFFFFF;
}

a {
  color: #DB6356;
  text-decoration: none;
}

/* -------------------------------- 

 Header

-------------------------------- */
.cd-morph-dropdown {
  position: relative;
  height: 60px;
  background-color: #FFFFFF;
}
.cd-morph-dropdown::before {
  /* never visible - used in JS to check mq */
  content: 'mobile';
  display: none;
}
.cd-morph-dropdown .nav-trigger {
  /* menu icon - visible on small screens only */
  position: absolute;
  top: 0;
  right: 0;
  height: 60px;
  width: 60px;
  /* replace text with icon */
  overflow: hidden;
  text-indent: 100%;
  white-space: nowrap;
  color: transparent;
}
.cd-morph-dropdown .nav-trigger span, .cd-morph-dropdown .nav-trigger span::after, .cd-morph-dropdown .nav-trigger span::before {
  /* these are the 3 lines of the menu icon */
  position: absolute;
  background-color: #1A1A1A;
  height: 3px;
  width: 26px;
}
.cd-morph-dropdown .nav-trigger span {
  left: 50%;
  top: 50%;
  bottom: auto;
  right: auto;
  -webkit-transform: translateX(-50%) translateY(-50%);
      -ms-transform: translateX(-50%) translateY(-50%);
          transform: translateX(-50%) translateY(-50%);
  -webkit-transition: background-color .3s;
  transition: background-color .3s;
}
.cd-morph-dropdown .nav-trigger span::after, .cd-morph-dropdown .nav-trigger span::before {
  content: '';
  left: 0;
  -webkit-transition: -webkit-transform .3s;
  transition: -webkit-transform .3s;
  transition: transform .3s;
  transition: transform .3s, -webkit-transform .3s;
}
.cd-morph-dropdown .nav-trigger span::before {
  -webkit-transform: translateY(-9px);
      -ms-transform: translateY(-9px);
          transform: translateY(-9px);
}
.cd-morph-dropdown .nav-trigger span::after {
  -webkit-transform: translateY(9px);
      -ms-transform: translateY(9px);
          transform: translateY(9px);
}
.cd-morph-dropdown.nav-open .nav-trigger span {
  background-color: transparent;
}
.cd-morph-dropdown.nav-open .nav-trigger span::before {
  -webkit-transform: rotate(45deg);
      -ms-transform: rotate(45deg);
          transform: rotate(45deg);
}
.cd-morph-dropdown.nav-open .nav-trigger span::after {
  -webkit-transform: rotate(-45deg);
      -ms-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
.cd-morph-dropdown .main-nav {
  display: none;
}
.cd-morph-dropdown .morph-dropdown-wrapper {
  display: none;
  position: absolute;
  top: 60px;
  left: 0;
  width: 100%;
  padding: 1.2em 5%;
  box-shadow: inset 0 1px 0 #e6e6e6;
  background-color: #FFFFFF;
}
.cd-morph-dropdown.nav-open .morph-dropdown-wrapper {
  display: block;
}
.cd-morph-dropdown .dropdown-list > ul > li {
  margin-bottom: 3.3em;
}
.cd-morph-dropdown .label {
  display: block;
  font-size: 2.2rem;
  color: #1A1A1A;
  margin-bottom: .8em;
}
.cd-morph-dropdown .content li::after {
  clear: both;
  content: "";
  display: block;
}
.cd-morph-dropdown .gallery .content li {
  margin-bottom: 1.4em;
}
.cd-morph-dropdown .gallery .content a {
  display: block;
}
.cd-morph-dropdown .gallery .content a::before {
  /* icon on the left */
  content: '';
  display: inline-block;
  float: left;
  height: 54px;
  width: 54px;
  margin-right: .6em;
  background: red;
  border-radius: 50%;
  -webkit-transition: background .2s;
  transition: background .2s;
}
.cd-morph-dropdown .gallery .content a span, .cd-morph-dropdown .gallery .content a em {
  display: block;
  line-height: 1.2;
}
.cd-morph-dropdown .gallery .content a em {
  font-size: 1.8rem;
  padding: .4em 0 .2em;
  color: #1A1A1A;
}
.cd-morph-dropdown .gallery .content a span {
  font-size: 1.4rem;
  color: #a6a6a6;
}
.cd-morph-dropdown .gallery .content a:hover::before {
  background-color: #1A1A1A;
}
.cd-morph-dropdown .gallery li:nth-of-type(1) a::before {
  background: #f4e58a url(../img/cd-gallery-icons.svg) no-repeat 0 0;
}
.cd-morph-dropdown .gallery li:nth-of-type(2) a::before {
  background: #F4AF6D url(../img/cd-gallery-icons.svg) no-repeat -54px 0;
}
.cd-morph-dropdown .gallery li:nth-of-type(3) a::before {
  background: #DB6356 url(../img/cd-gallery-icons.svg) no-repeat -108px 0;
}
.cd-morph-dropdown .gallery li:nth-of-type(4) a::before {
  background: #8D4645 url(../img/cd-gallery-icons.svg) no-repeat -162px 0;
}
.cd-morph-dropdown .links .content > ul > li {
  margin-top: 1em;
}
.cd-morph-dropdown .links-list a,
.cd-morph-dropdown .btn {
  display: block;
  margin-left: 14px;
  font-size: 2.2rem;
  line-height: 1.6;
}
.cd-morph-dropdown .links-list a:hover,
.cd-morph-dropdown .btn:hover {
  color: #1A1A1A;
}
.cd-morph-dropdown .content h2 {
  color: #a6a6a6;
  text-transform: uppercase;
  font-weight: bold;
  font-size: 1.3rem;
  margin: 20px 0 10px 14px;
}
@media only screen and (min-width: 1000px) {
  .cd-morph-dropdown {
    position: absolute;
    height: 80px;
    left: 0;
    top: 0;
    width: 100%;
    padding: 0;
    text-align: center;
    background-color: transparent;
  }
  .cd-morph-dropdown::before {
    content: 'desktop';
  }
  .cd-morph-dropdown .nav-trigger {
    display: none;
  }
  .cd-morph-dropdown .main-nav {
    display: inline-block;
  }
  .cd-morph-dropdown .main-nav > ul > li {
    display: inline-block;
    float: left;
  }
  .cd-morph-dropdown .main-nav > ul > li > a {
    display: block;
    padding: 0 1.8em;
    height: 70px;
    line-height: 70px;
    color: #FFFFFF;
    font-size: 1.8rem;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-transition: opacity .2s;
    transition: opacity .2s;
  }
  .cd-morph-dropdown.is-dropdown-visible .main-nav > ul > li > a {
    /* main navigation hover effect - on hover, reduce opacity of elements not hovered over */
    opacity: .6;
  }
  .cd-morph-dropdown.is-dropdown-visible .main-nav > ul > li.active > a {
    opacity: 1;
  }
  .cd-morph-dropdown .morph-dropdown-wrapper {
    /* dropdown wrapper - used to create the slide up/slide down effect when dropdown is revealed/hidden */
    display: block;
    top: 58px;
    /* overwrite mobile style */
    width: auto;
    padding: 0;
    box-shadow: none;
    background-color: transparent;
    /* Force Hardware acceleration */
    -webkit-transform: translateZ(0);
            transform: translateZ(0);
    will-change: transform;
    -webkit-transform: translateY(20px);
        -ms-transform: translateY(20px);
            transform: translateY(20px);
    -webkit-transition: -webkit-transform .3s;
    transition: -webkit-transform .3s;
    transition: transform .3s;
    transition: transform .3s, -webkit-transform .3s;
  }
  .cd-morph-dropdown.is-dropdown-visible .morph-dropdown-wrapper {
    -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
            transform: translateY(0);
  }
  .cd-morph-dropdown .dropdown-list {
    position: absolute;
    top: 0;
    left: 0;
    visibility: hidden;
    -webkit-transform: translateZ(0);
            transform: translateZ(0);
    will-change: transform, width, height;
    -webkit-transition: visibility .3s;
    transition: visibility .3s;
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
  }
  .no-csstransitions .cd-morph-dropdown .dropdown-list {
    display: none;
  }
  .cd-morph-dropdown .dropdown-list::before {
    /* dropdown top triangle */
    content: '';
    position: absolute;
    bottom: 100%;
    left: 50%;
    right: auto;
    -webkit-transform: translateX(-50%);
        -ms-transform: translateX(-50%);
            transform: translateX(-50%);
    height: 0;
    width: 0;
    border: 8px solid transparent;
    border-bottom-color: #FFFFFF;
    opacity: 0;
    -webkit-transition: opacity .3s;
    transition: opacity .3s;
  }
  .cd-morph-dropdown .dropdown-list > ul {
    position: relative;
    z-index: 1;
    height: 100%;
    width: 100%;
    overflow: hidden;
  }
  .cd-morph-dropdown.is-dropdown-visible .dropdown-list {
    visibility: visible;
    -webkit-transition: width .3s, height .3s, -webkit-transform .3s;
    transition: width .3s, height .3s, -webkit-transform .3s;
    transition: transform .3s, width .3s, height .3s;
    transition: transform .3s, width .3s, height .3s, -webkit-transform .3s;
  }
  .cd-morph-dropdown.is-dropdown-visible .dropdown-list::before {
    opacity: 1;
  }
  .cd-morph-dropdown .dropdown {
    position: absolute;
    left: 0;
    top: 0;
    opacity: 0;
    visibility: hidden;
    width: 100%;
    -webkit-transition: opacity .3s, visibility .3s;
    transition: opacity .3s, visibility .3s;
  }
  .cd-morph-dropdown .dropdown.active {
    opacity: 1;
    visibility: visible;
  }
  .cd-morph-dropdown .dropdown.move-left .content {
    -webkit-transform: translateX(-100px);
        -ms-transform: translateX(-100px);
            transform: translateX(-100px);
  }
  .cd-morph-dropdown .dropdown.move-right .content {
    -webkit-transform: translateX(100px);
        -ms-transform: translateX(100px);
            transform: translateX(100px);
  }
  .cd-morph-dropdown .label {
    /* hide the label on bigger devices */
    display: none;
  }
  .cd-morph-dropdown .content {
    padding: 2.2em 1.8em;
    -webkit-transition: -webkit-transform .3s;
    transition: -webkit-transform .3s;
    transition: transform .3s;
    transition: transform .3s, -webkit-transform .3s;
    text-align: left;
  }
  .cd-morph-dropdown .content > ul::after {
    clear: both;
    content: "";
    display: block;
  }
  .cd-morph-dropdown .content > ul > li {
    width: 48%;
    float: left;
    margin-right: 4%;
    margin-top: 0;
  }
  .cd-morph-dropdown .content > ul > li:nth-of-type(2n) {
    margin-right: 0;
  }
  .cd-morph-dropdown .gallery .content {
    /* you need to set a width for the .content elements because they have a position absolute */
    width: 510px;
    padding-bottom: .8em;
  }
  .cd-morph-dropdown .gallery .content li {
    margin-bottom: 1.8em;
  }
  .cd-morph-dropdown .links .content > ul > li {
    margin-top: 0;
  }
  .cd-morph-dropdown .links .content,
  .cd-morph-dropdown .button .content {
    width: 390px;
  }
  .cd-morph-dropdown .links-list a {
    font-size: 1.6rem;
    margin-left: 0;
  }
  .cd-morph-dropdown .btn {
    display: block;
    width: 100%;
    height: 60px;
    margin: 1.5em 0 0;
    font-size: 1.8rem;
    text-align: center;
    color: #FFFFFF;
    line-height: 60px;
    background: #DB6356;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .cd-morph-dropdown .btn:hover {
    background: #1A1A1A;
    color: #FFFFFF;
  }
  .cd-morph-dropdown .content h2 {
    font-size: 1.8rem;
    text-transform: none;
    font-weight: normal;
    color: #1A1A1A;
    margin: 0 0 .6em;
  }
  .cd-morph-dropdown .bg-layer {
    /* morph dropdown background */
    position: absolute;
    top: 0;
    left: 0;
    height: 1px;
    width: 1px;
    background: #FFFFFF;
    opacity: 0;
    -webkit-transition: opacity .3s;
    transition: opacity .3s;
    -webkit-transform-origin: top left;
        -ms-transform-origin: top left;
            transform-origin: top left;
    -webkit-transform: translateZ(0);
            transform: translateZ(0);
    will-change: transform;
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
  }
  .cd-morph-dropdown.is-dropdown-visible .bg-layer {
    opacity: 1;
    -webkit-transition: opacity .3s, -webkit-transform .3s;
    transition: opacity .3s, -webkit-transform .3s;
    transition: transform .3s, opacity .3s;
    transition: transform .3s, opacity .3s, -webkit-transform .3s;
  }
}

/* -------------------------------- 

Main site content

-------------------------------- */
.cd-main-content {
  min-height: 100vh;
  background-color: #548c7e;
}
@media only screen and (min-width: 1000px) {
  .cd-main-content {
    padding-top: 80px;
  }
}

jQuery

Đây là phần  phức tạp nhất và cũng là quan trọng nhất của menu, ở mỗi đoạn script đều có ghi chú đính kèm, các bạn có thể hiễu rõ chức năng của từng câu lệnh.

jQuery(document).ready(function($){
	function morphDropdown( element ) {
		this.element = element;
		this.mainNavigation = this.element.find('.main-nav');
		this.mainNavigationItems = this.mainNavigation.find('.has-dropdown');
		this.dropdownList = this.element.find('.dropdown-list');
		this.dropdownWrappers = this.dropdownList.find('.dropdown');
		this.dropdownItems = this.dropdownList.find('.content');
		this.dropdownBg = this.dropdownList.find('.bg-layer');
		this.mq = this.checkMq();
		this.bindEvents();
	}

	morphDropdown.prototype.checkMq = function() {
		//check screen size
		var self = this;
	return window.getComputedStyle(self.element.get(0), '::before').getPropertyValue('content').replace(/"/g, "").replace(/"/g, "").split(', ');
	};

	morphDropdown.prototype.bindEvents = function() {
		var self = this;
		//hover over an item in the main navigation
		this.mainNavigationItems.mouseenter(function(event){
			//hover over one of the nav items -> show dropdown
			self.showDropdown($(this));
		}).mouseleave(function(){
			setTimeout(function(){
				//if not hovering over a nav item or a dropdown -> hide dropdown
				if( self.mainNavigation.find('.has-dropdown:hover').length == 0 && self.element.find('.dropdown-list:hover').length == 0 ) self.hideDropdown();
			}, 50);
		});
		
		//hover over the dropdown
		this.dropdownList.mouseleave(function(){
			setTimeout(function(){
				//if not hovering over a dropdown or a nav item -> hide dropdown
				(self.mainNavigation.find('.has-dropdown:hover').length == 0 && self.element.find('.dropdown-list:hover').length == 0 ) && self.hideDropdown();
			}, 50);
		});

		//click on an item in the main navigation -> open a dropdown on a touch device
		this.mainNavigationItems.on('touchstart', function(event){
			var selectedDropdown = self.dropdownList.find('#'+$(this).data('content'));
			if( !self.element.hasClass('is-dropdown-visible') || !selectedDropdown.hasClass('active') ) {
				event.preventDefault();
				self.showDropdown($(this));
			}
		});

		//on small screens, open navigation clicking on the menu icon
		this.element.on('click', '.nav-trigger', function(event){
			event.preventDefault();
			self.element.toggleClass('nav-open');
		});
	};

	morphDropdown.prototype.showDropdown = function(item) {
		this.mq = this.checkMq();
		if( this.mq == 'desktop') {
			var self = this;
			var selectedDropdown = this.dropdownList.find('#'+item.data('content')),
				selectedDropdownHeight = selectedDropdown.innerHeight(),
				selectedDropdownWidth = selectedDropdown.children('.content').innerWidth(),
				selectedDropdownLeft = item.offset().left + item.innerWidth()/2 - selectedDropdownWidth/2;

			//update dropdown position and size
			this.updateDropdown(selectedDropdown, parseInt(selectedDropdownHeight), selectedDropdownWidth, parseInt(selectedDropdownLeft));
			//add active class to the proper dropdown item
			this.element.find('.active').removeClass('active');
			selectedDropdown.addClass('active').removeClass('move-left move-right').prevAll().addClass('move-left').end().nextAll().addClass('move-right');
			item.addClass('active');
			//show the dropdown wrapper if not visible yet
			if( !this.element.hasClass('is-dropdown-visible') ) {
				setTimeout(function(){
					self.element.addClass('is-dropdown-visible');
				}, 10);
			}
		}
	};

	morphDropdown.prototype.updateDropdown = function(dropdownItem, height, width, left) {
		this.dropdownList.css({
		    '-moz-transform': 'translateX(' + left + 'px)',
		    '-webkit-transform': 'translateX(' + left + 'px)',
			'-ms-transform': 'translateX(' + left + 'px)',
			'-o-transform': 'translateX(' + left + 'px)',
			'transform': 'translateX(' + left + 'px)',
			'width': width+'px',
			'height': height+'px'
		});

		this.dropdownBg.css({
			'-moz-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
		    '-webkit-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
			'-ms-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
			'-o-transform': 'scaleX(' + width + ') scaleY(' + height + ')',
			'transform': 'scaleX(' + width + ') scaleY(' + height + ')'
		});
	};

	morphDropdown.prototype.hideDropdown = function() {
		this.mq = this.checkMq();
		if( this.mq == 'desktop') {
			this.element.removeClass('is-dropdown-visible').find('.active').removeClass('active').end().find('.move-left').removeClass('move-left').end().find('.move-right').removeClass('move-right');
		}
	};

	morphDropdown.prototype.resetDropdown = function() {
		this.mq = this.checkMq();
		if( this.mq == 'mobile') {
			this.dropdownList.removeAttr('style');
		}
	};

	var morphDropdowns = [];
	if( $('.cd-morph-dropdown').length > 0 ) {
		$('.cd-morph-dropdown').each(function(){
			//create a morphDropdown object for each .cd-morph-dropdown
			morphDropdowns.push(new morphDropdown($(this)));
		});

		var resizing = false;

		//on resize, reset dropdown style property
		updateDropdownPosition();
		$(window).on('resize', function(){
			if( !resizing ) {
				resizing =  true;
				(!window.requestAnimationFrame) ? setTimeout(updateDropdownPosition, 300) : window.requestAnimationFrame(updateDropdownPosition);
			}
		});

		function updateDropdownPosition() {
			morphDropdowns.forEach(function(element){
				element.resetDropdown();
			});

			resizing = false;
		};
	}
});

Chúc các bạn thành công !

Chuyên Mục:

Bài viết được đăng bởi webmaster

Nếu các bạn thấy bài viết hữu ích thì giúp mình Like cái nhé !