Navbar with Brand Logo

Hello everyone and thanks for the help in advance. I’m trying to develop a responsive navbar with and inline logo. After searching for examples, there seems to be an endless variety of ways to tackle the problem. However, many of the examples use older methodology omitting semantic elements while using floats and the lot. Would someone please point me to an example using modern best practices? Any help would be appreciated.

I tried putting together a rough draft using flexbox at: http://christyforcongress.com/test/menuflex. I guess this is a basic start, but I need to figure out if this is the wrong direction and also how to make this more responsive, especially regarding mobile devices. My question regarding mobile is how to toggle between the full menu or the hamburger button. I’m thinking the best method is a media query as opposed to javascript, however, I have seen both used. Any feedback as to how to proceed?

You need first to decide how you want it to look at full screen and then how you want it to look on the smallest screens.

Then you need to decide how you want it to look at intermediate sizes if you want a progressive change throughout all widths.

Once you have drawn on paper some wire-frames of how you want it to look then you can construct the html and css with those displays in mind.

The structure of the html should be semantic but there is often a trade off when design considerations make that awkward. Luckily flexbox and CSS grid give you the facility to re-order elements as long as they are direct siblings so you do need to keep an eye on the html and the design at the same time to make sure the things you require can be accomplished.

If the design you require means that the html can’t be semantic then you should try and think again and come up with designs that are feasible and usable.

There is nothing special about building a navbar than there is with building any of the other page components except that the navbar is going to be one of the most used parts of the page (via users and other technologies such as screen readers and search engines) so semantics play a great part here.

A media query will change the design at the width you require but cannot provide a toggle function at all.

You will need js to provide the toggle function assuming you want to hide and show the mobile menu using the hamburger icon. The media query can show a hamburger and hide the navbar but you will need js to turn it back on again. (You can use the checkbox hack to create a toggle in pure css or use :target to do similar but both are not as reliable as JS).

I would put your navigation inside a ul list as they are a list of links. Having anchors next to each other (with no elements or content between) would historically cause screen readers to read them all out in one go like a sentence rather than pause. It’s not an issue these days but using an un-ordered list still makes a better structure and provides more styling opportunities should they be needed. (However I have used both methods where needs must :slight_smile: )

That would also help when you want to move the logo to one position and all the links to another position as you will have a wrapper around all the links and can place them in one go.

Decide how wide you want your page to be and use a page-wrapper for all your content if you are going to have a max-width. You seldom want content to spread all the way across large monitors (although you may want the background to do this).

Hope that’s a start :slight_smile:

1 Like

Thank you so much for the very helpful and informative response. I know what I am trying to accomplish. Examples are at www.rivian.com or https://www.parkeeastapartmentsorlando.com/, effectively a transparent type of responsive menu that could be ported to different pages on the site, some of which might have a hero image, some not. Part of the reason for my post was confirmed when you said to avoid non-semantic designs as there are many examples that don’t. Point also taken on the use of unordered lists. I will revise my design and repost. Thank you again for the valuable insight. I appreciate it.

2 Likes

Still fumbling around with what should be basic stuff that I just can’t grasp. Sample is posted at: http://christyforcongress.com/test/menuflex. I’m trying to use a media query to simply turn off and on the hamburger icon, without success. Secondary issue is spacing with the menu items on the horizontal layout. Any help is appreciated.

Hi,

You caught me as I was just going offline but here’s a very quick example of hiding and showing the hamburger using mostly your code and tidying the navbar.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/Styles/MenuFlex.css">
<style>
body {
	margin:  0 auto;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
html {
	box-sizing: border-box;
}
*, *:before, *:after {
	box-sizing: inherit;
}
#main {
	max-width:1280px;
	margin:auto;
	background:#ccc;
	padding:10px;
}
.logo {
	padding-right:  30px;
	padding-top:  10px;
}
#navbarcontainer {
	display: flex;
	width:  100%;
	justify-content:space-between;
	align-items:center;
}
#navbarcontainer ul {
	list-style-type:  none;
	margin:0;
	padding:0;
	display:flex;
	flex-wrap:wrap;
	justify-content:space-around;
	align-items:baseline;
	flex:1 0 0%;
}
#navbarcontainer a {
	padding:10px;
	display:block;
	color:  gray;
	text-decoration:  none;
	font-size:  1em;
}
#navbarcontainer a:hover {
	background:#000;
	color:#fff;
}
.icon {
	padding:0;
	margin:0 1rem;
	background:transparent;
	border:none;
	display:none;
	font-size:2rem;
}
@media only screen and (max-width: 768px) {
	.icon {
		display:block;
	}
	#navbarcontainer ul {
	display:none;
	}
}
</style>
</head>
<body>
<!--
        https://www.freecodecamp.org/news/how-to-create-a-fully-responsive-navbar-with-flexbox-a4435d175dd3/
    -->
<div id="main">
  <nav>
    <div id="navbarcontainer"> <img class="logo" src="http://christyforcongress.com/images/Logo/Keep_SW_Florida_Great_Crop_200.png">
      <ul>
        <li> <a href="#home" class="active">Home</a> </li>
        <li> <a href="https://secure.winred.com/christy-for-congress/donate​" target="_blank">Donate</a> </li>
        <li> <a href="#pacpledge">My Pledge</a> </li>
        <li> <a href="#divmedia">Media</a> </li>
        <li> <a href="#content">Meet Christy</a> </li>
        <li> <a href="#gallery">Gallery</a> </li>
        <li> <a href="#issues">Issues</a> </li>
        <li> <a href="#" id="lnkcontactusdialog" class="lnkjoinus">Join Us</a> </li>
        <li> <a href="https://www.facebook.com/christy.mclaughlin.102" target="_blank" id="facebook"><i class="fa fa-facebook-square" style="font-size:24px; padding-right:  1px;"></i>Facebook</a> </li>
        <li> <a href="https://twitter.com/ChristyMarieEm" target="_blank" id="twitter"><i class="fa fa-twitter-square" style="font-size:24px; padding-right:  1px;"></i>Twitter</a> </li>
      </ul>
      <button class="icon" onclick="myFunction()">&#9776;</button>
    </div>
  </nav>
</div>
</body>
</html>

I moved the hamburger out of the ul because you will want to easily hide the ul when the hamburger is showing and then you will want to show it when the hamburger is clicked. Don’t be tempted to use inline click handlers as you want the js to be in the js file and not in the html.

As I said this was a quick fix to point you in the right direction but I will be back tomorrow to give further advice and explanation (and to check I didn’t mess anything up). :slight_smile:

Ok I’m back.:slight_smile:

Here’s some updated code that moves the navigation off screen when the hamburger appears and then slides it back into view when clicked (I’ve added some js for that). It’s mostly your original html but there are some subtle differences so check carefully.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/Styles/MenuFlex.css">
<style>
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
}
html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
#main {
  max-width: 1280px;
  margin: auto;
  background: #eee;
  padding: 10px;
  min-height: 100vh;
}
.logo {
  padding-right: 30px;
  padding-top: 10px;
}
#navbarcontainer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
#navbarcontainer ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  align-items: baseline;
  flex: 1 0 0%;
}
#navbarcontainer a {
  padding: 10px;
  display: block;
  color: gray;
  text-decoration: none;
  font-size: 1rem;
}
#navbarcontainer a:hover {
  background: #000;
  color: #fff;
}
.icon {
  padding: 5px;
  margin: 0 1rem;
  background: transparent;
  border: none;
  display: none;
  font-size: 2rem;
  cursor: pointer;
}
.icon .fa-times-circle,
.icon span {
  position: fixed;
  left: -100vw;
}
.icon:hover {
  background: #fff;
}
.icon:focus {
  outline: 1px dotted #ccc;
}
@media only screen and (max-width: 768px) {
  body.menu-open {
    overflow: hidden;
  }
  .icon {
    display: block;
  }
  /* lets hide the navbar off screen but turn it into a sliding side menu for small screens*/
  #navbarcontainer ul {
    display: block;
    position: fixed;
    z-index: 99;
    top: 0;
    left: 0;
    padding-top: 4rem;
    width: 100%;
    height: 100vh;
    overflow: auto;
    max-width: 480px;
    background: #f9f9f9;
    border-right: 1px solid #000;
    transform: translateX(-100%);
    opacity: 0;
    /* transition:transform .5s ease-in-out,opacity .3s linear; allows menu to slide out slowly*/
  }
  .menu-open #navbarcontainer ul {
    transform: translateX(0);
    opacity: 1;
    box-shadow: 0 0 100vw rgba(0, 0, 0, 0.5);
    transition: transform 0.5s ease-in-out, opacity 0.3s linear;
  }
  #navbarcontainer li,
  #navbarcontainer a {
    background: #fff;
  }
  #navbarcontainer li:first-child a {
    border-top: 1px solid #000;
  }
  #navbarcontainer a {
    border-bottom: 1px solid #000;
  }
  .menu-open .icon .fa-times-circle {
    position: fixed;
    z-index: 1000;
    left: 0.8rem;
    top: 0.8rem;
  }
  /*.menu-open .icon .fa-bars{position:fixed;left:-100vw}*/
}

</style>
</head>
<body>
<div id="main">
  <nav>
    <div id="navbarcontainer"> <img class="logo" src="http://christyforcongress.com/images/Logo/Keep_SW_Florida_Great_Crop_200.png" alt="Keep SW Florida Great">
      <ul>
        <li> <a href="#home" class="active">Home</a> </li>
        <li> <a href="https://secure.winred.com/christy-for-congress/donate​" target="_blank">Donate</a> </li>
        <li> <a href="#pacpledge">My Pledge</a> </li>
        <li> <a href="#divmedia">Media</a> </li>
        <li> <a href="#content">Meet Christy</a> </li>
        <li> <a href="#gallery">Gallery</a> </li>
        <li> <a href="#issues">Issues</a> </li>
        <li> <a href="#" id="lnkcontactusdialog" class="lnkjoinus">Join Us</a> </li>
        <li> <a href="https://www.facebook.com/christy.mclaughlin.102" target="_blank" id="facebook"><i class="fa fa-facebook-square" style="font-size:24px; padding-right:  1px;"></i>Facebook</a> </li>
        <li> <a href="https://twitter.com/ChristyMarieEm" target="_blank" id="twitter"><i class="fa fa-twitter-square" style="font-size:24px; padding-right:  1px;"></i>Twitter</a> </li>
      </ul>
      <button class="icon"><i class="fa fa-bars"></i><i class="fa fa-times-circle"></i><span>Open and Close menu</span></button>
    </div>
  </nav>
  <div class="content">
    <h1>Main Page Title</h1>
    <p>Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working </p>
    <p>Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working Some dummy content with a <a href="#">link</a>link to check all is working </p>
  </div>
</div>
<script>

(function(d ) {
   'use strict'; 
  const icon = d.querySelector( '.icon' );
  const theBody = d.querySelector('body');
   
   icon.addEventListener( 'click', function() { 
   	theBody.classList.toggle('menu-open');
    });

}( document ));

</script>
</body>
</html>

I’ve deliberately left it simple so that you can style it as required but the basic function is in place for you to work with.

Hope it helps anyway. (I’ll throw it into a codepen later).

I’ve removed any specifics to your site and put up a codepen demo. I’ve tidied up the html and css into more manageable chunks but still tried to keep it based on what you had already.

Feel free to fork that pen and play around with it.

The basics are that the navbar is hidden using a media query while at the same time showing the hamburger. When you click the hamburger he JS simply toggles a class on the body element. You can then use this class on the body element to change anything on the page while the menu is open. This allows us to slide the menu into view and indeed change anything else that you may want to change while the menu is open.

The rest is basic css but you do need to organise things properly to make it easier to manipulate later. for examples I removed the logo and the social icons and the button from the navbar in order that we could move them separately if required, That gives us more opportunity to change the styling for small screens whether needed or not.

There is a live version here outside codepen to see full effect.

Hope it helps but shout if you need more explanation.

1 Like

Thanks so much for all of the hard work and input. I’m reading through the code right now, trying to understand it. However, on my Samsung Note 10+, the mobile hamburger menu doesn’t display, so I’m trying understand/debug.

Are you talking about my live version or a version that you have updated?

If its your version I assume you have linked to the font-awesome file that provides the hamburger icons?

You’ll have to post a screenshot as I don’t have that phone to test. I can confirm that the hamburger works fine on my really old iphone 5 and my newer iphone7 so I can’t see there would be a problem at all on newer phones.

However never say never :slight_smile:

When I say I am not very good at front end, I mean it. You are of course correct in that I failed to include the external file (extremely embarrassed smile). Let me muddle through the rest of the code before saying anything else. it looks great. Thank you for the help.

2 Likes

Thank yo so much for all of the hard work and insight. A few questions if I may:

  1. The #navcontainer and #navbarcontainer ul both have a display: flex, i.e. a flexbox within a flexbox. I’m not sure why this was done.
  2. ON the mobile version, the ul uses z-index: 99;. Again, I am confused why.
  3. On .menu-open you use z-index: 1000.
  1. The ul (navbar) contains a load of list items and if that ul was not a flex container all the list items would flow vertically down the page. We need to make the ul display:flex so that we can use the horizontal alignment on the list items and space them out properly using appropriate flex values.

Only direct children of a flexbox are flex items. Flex items may hold many other elements so you can make a flex item also be a flex box itself.

I actually meant to make it z-index:999 just to be safe because the side menu must always appear on top of whatever else is in the page and we don’t know what z-indexes he rest of the page will hold. Therefore I use an arbitrarily high value in the hope that it stays above all else.

No I don’t change the side menu again but I do raise the z-index of the close(X) icon because I have moved it out of the flow and onto the top of the sliding menu. As the sliding menu has a z-index of 999 (was 99) then its obvious that I must make the close icon have a z-index of at least 999 to match. Therefore I made it z-index:1000 to be on the safe side. If you reduce the z-index of that close icon lower than the nav then it will disappear behind and on small screens you cannot close the sliding menu.

Note that the trick I used was to have the hamburger icon and the close icon both in the button at the same time and then I just hide and reveal the close icon when the menu is open. Even though the close icon is now somewhere else it still acts as a click on the hamburger and will trigger js to remove the class from the body that is holding the menu open.

The easiest way to see what is happening is to open your chrome developer tools while looking at the page and then you can turn on and off (or change) values in the css by just toggling the check boxes in the css panel of the devtools. In his way you can easily see what happens live if you remove display:flex or raise or lower z-indexes. The developer tools should be your constant companion and I look at mine more than I do at the page in question.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.