Changing Color of a Burger Menu Depending on Background

Changing colors of the bars in a burger menu depending on background-color is not straight forward. I ended up using JavaScript, and it is still not working very well.

3457 views
d

By. Jacob

Edited: 2018-06-08 11:53

Just a Burger menu

As part of an exam project, recently I had to change the color of a burger menu depending on the background color beneath it, and of cause I was the one getting to do the coding. This turned out to be a hugely challenging task, and in the end I ended up with a nasty hack rather than a real CSS based solution. I was also forced to use JavaScript, which is a big no-no for layout purposes. The menu changing colors was a requirement by another designer in our group.

I would never attempt this myself unless I had a real CSS solution. But, explaining why you should not use a certain approach that appears to work – but still not completely in all circumstances – can be very difficult. Often people will think you are just incompetent or lazy, so I try to avoid discussions it, and instead allow them to learn the hard way themselves.

The "hack" is quite simple. It works by changing the color after scrolling past the site header. I could only get away with this because the site-header had a dark background on our website, so this solution will not work for everyone.

The whole process reminded me why I used to hate front-end design, especially when I am not making all design decisions. You might have a designer less experienced at coding, and they might decide on something that is simply not possible with current technology. Personally I prefer to avoid JavaScript for layout purposes, so I will usually always try to find pure CSS solutions before resorting to JavaScript.

As far as I know, a simple CSS sulution does not exist for this. I even tried using CSS filters, but that only seemed to work on the parent element, and not if you had position:fixed; on your menu. Ideally it should work depending on the visual background, and not which element came as the parent. So, I ended up using JS.

The triggering code looks like this:

//The below code calls "scrollFunction()" to change the color of the burgerMenu when needed
//Because of design-requirements, this is only needed on some pages. I.e. Some pages has a white #site_header and others have a video or an image.
if (!document.querySelector('#site_header_follow_black')) {
  // If the header background is dark, switch to white burgerBar's in the #burgerMenu
  window.onscroll = function() {
    scrollFunction();
  };
}

The scrollFunction():

function scrollFunction() {
  if (menu_state_open == false) {
    if (document.body.scrollTop > window.screen.height-100 || document.documentElement.scrollTop < window.screen.height-100) {
      toggleBurgerColor();
    }
  }
}

This will change the color of the burger menu when scrolling past a certain point. In this case 1 x height of screen minus 100px (the height of the burger). Our header has a height of 100vh which makes it fill the height of the screen.

Note. Personally I am not a fan of such types of layouts – while they work for mobile devices, they are very bad on PCs. I hate when text, images and videos automatically scales to fit my screen. Do not do this!!!

Toggling the colors of the burger menu

The toggleBurgerColor() function is a custom function that changes the burger-color if a dark header-background exists in the HTML. The way I accomplished this was to simply have a unique ID on <header> elements with a dark background color. I would then check for the existence of these IDs, and only activate the color-shift when required. I.e.:

function toggleBurgerColor() {
  let chosenColor = '#000';
  if ((document.querySelector('#site_header_black')) && (menu_state_open!==false)) {
    // Change burgerBar color to white if burgerMenu is open AND element ID "site_header_logo_white" exists
    chosenColor = '#fff';
  } else {
    chosenColor = '#000'; // Else we change color of burgerBars to black
  }
  document.querySelector('#burgerBar1').style.background = chosenColor;
  document.querySelector('#burgerBar2').style.background = chosenColor;
  document.querySelector('#burgerBar3').style.background = chosenColor;
}

Another requirement was that when the menu is open, it was go #fff and remain as #fff, even when scrolling. That is why I also check the menu_state_open variable.

Final thoughts and recommendations

If you ever find yourself facing a similar problem, do not try to hack a solution with JavaScript like I had to in this project. Do yourself a favor, save time, and just add a background to your menu.

If you must have a position:fixed; menu, the best solution is to add a semitransparent background like background:rgba(0,0,0, 0.1); or background:rgba(255,255,255, 0.1); – Doing this will avoid all the crazy special-case problems you might run into, and account for all unpredictable situations with the background-color on your website.

Normally I would also avoid using a burger menu on large screens. A Mobile-first approach is obviously bad for large screens (usually desktops), especially when you choose a design that only works decently on mobile (this is surprisingly often the case).

I actually think it is generally better to design for large screens, which typically gives the best experience, and then degrade on smaller screens. Just avoid using HTML- table like designs, since those can be very difficult to get to work properly on mobile.

Tell us what you think:

  1. An in-dept look at the use of headings (h1-h6) and sections in HTML pages.
  2. Pagination can be a confusing thing to get right both practically and programmatically. I have put a lot of thought into this subject, and here I am giving you a few of the ideas I have been working with.
  3. The best way to deal with a trailing question mark is probably just to make it a bad request, because it is a very odd thing to find in a request URL.
  4. How to optimize image-loading and automatically include width and height attributes on img elements with PHP.
  5. HTTP headers are not case-sensitive, so we are free to convert them to all-lowercase in our applications.

More in: Web development