Invert navigation text and logo color from white to black/colored when scrolling depending on color of background?

Viewed 454

I'm relatively new to js and finally managed to create a script (took me bloody 3 hours! :-D) that basically inverts the color of my dummy navigation (text/links plus logo image) when user scrolls past the initial darker dummy slider section, and onto the rest of the page which has white background. So far so good. Here is my code:

function logoSwitch () {
  $('.altLogo').each(function() {
    $(this).css('top',
      $('.startLogo').offset().top -  $(this).closest('.row').offset().top
    );
  });
};

$(document).scroll(function() {logoSwitch();});

logoSwitch();
* {
  padding: 0;
  margin: 0;
}

.row {
  min-height: 100vh;
  overflow: hidden;
  position: relative;
  width: 100%;
}

.logo {
  top: 30px;
  width: 100%;

  transform-origin: left top 0;
}

.startLogo {
  position: fixed;
}

.altLogo {
  position: absolute;
}

.white {
  color: white;
}

.black {
  color: #1d1d1d;
}

.grey {
  background: #ccc;
}

.white {
  background: white;
}

.hero-black {
    background: #000;
}

.light {
  color: white;
}

.menu-link, .menu-logo {
  width: 20%;
  float: left;
  text-align: center;
}

.logo-image {
  width: 80px;
  margin-top: -7px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="row hero-black">
<div class="logo light startLogo">
<div class="menu-logo"><img class="logo-image" src="https://newhomespain.com/wp-content/uploads/2016/11/footer-logo-white-small-compressed.png"></div> 
<div class="menu-link">Home</div> 
<div class="menu-link">Webshop</div> 
<div class="menu-link">About</div> 
<div class="menu-link">Contact</div> 
</div>
</div>

<div class="row white">
<div class="logo black altLogo">
<div class="menu-logo"><img class="logo-image" src="https://newhomespain.com/wp-content/uploads/2016/11/new-home-spain-hi-res-logo.png"></div> 
<div class="menu-link">Home</div> 
<div class="menu-link">Webshop</div> 
<div class="menu-link">About</div> 
<div class="menu-link">Contact</div> 
</div>
</div>

I now have 2 problems:

  1. I had to start somewhere, so i did - but i now see that the script is very limited to affect only two classes: "altLogo" (displaying the coloured logo and black text on white background) and "startLogo" (displaying the white logo and text on dark background). This makes it very rigid and i can't seem to think of a way to implement it globally in the header section of my webpage in a smart way. How could i amend the scipt to make it more flexible - in stead of having to insert the "altLogo" and "startLogo" basically everywhere?

  2. While trying to gain knowledge on how to code the script i ended up with until now, i came across this website, which does the trick in an very clever way it seems:

https://visibly.dk/

The logo and text color in the header changes based on the color of the underlying div/background, and can change multiple times back and forth while scrolling down, if let's say we have a dark section with a dark backgound, followed by a new light section, then a dark one and then a light one again.

Is there an "easy" way to do this? Basically to tell the script to change the navigation text into black and use colored image/logo if backgound is white, and revert back to all white text and image/logo if background is dark?

Link to my fiddle:

https://jsfiddle.net/3srv0kg8/

1 Answers

One approach would be to create two classes, a light and dark class. Each of those contains CSS property (aka variable) for your colors. Then just use the scroll position to switch the classes as needed.

For the image, you can either switch the src attribute within that same code block, or use something like filter: invert(1); to modify it's colors.

For a subtle animation, you can also just use CSS: transition: all 0.25s ease;.

Here's a quick demo, (it's been about 10 years since I last used jQuery, so that part may have some room for improvement).

$(window).scroll(function(){
const pageHeight = $(window).height();
  if($(window).scrollTop() > pageHeight){
    $('body').addClass('dark').removeClass('light')
  }else{
    $('body').addClass('light').removeClass('dark')
  }
});
body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  transition: all 0.25s ease;
}

body.light {
  --foreground: #000;
  --background: #fff;
}
body.dark {
  --foreground: #fff;
  --background: #000;
}

body.dark img.logo-image {
  filter: invert(1);
}

div.outer {
  width: 100%;
  min-height: 400vh;
}

nav.top-bar {
  top: 0;
  display: flex;
  width: 100%;
  background: var(--background);
  position: fixed;
  border-bottom: 1px solid var(--foreground);
}

img.logo-image {
  width: 6rem;
}

a.menu-link {
  margin: 0.5rem;
  padding: 0.25rem;
  color: var(--foreground);
  border: 1px solid var(--foreground);
}

div.content {
  height: 100vh;
  border-bottom: 1px dashed var(--foreground);
}

div.content p {
 padding-top: 4rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="light">
<div class="outer">
  <nav class="top-bar">
    <img class="logo-image" src="https://newhomespain.com/wp-content/uploads/2016/11/new-home-spain-hi-res-logo.png">
    <a class="menu-link">Home</a> 
    <a class="menu-link">Webshop</a> 
    <a class="menu-link">About</a> 
    <a class="menu-link">Contact</a> 
  </nav>

    <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Donec sed odio operae, eu vulputate felis rhoncus. Salutantibus vitae elit libero, a pharetra augue. Nihil hic munitissimus habendi senatus locus, nihil horum? A communi observantia non est recedendum.
    </p>
  </div>
  <div class="content">
    <p>
      Non equidem invideo, miror magis posuere velit aliquet. Quisque placerat facilisis egestas cillum dolore. Curabitur blandit tempus ardua ridiculus sed magna. Contra legem facit qui id facit quod lex prohibet. Petierunt uti sibi concilium totius Galliae in diem certam indicere.
    </p>
  </div>
  <div class="content">
    <p>
      A communi observantia non est recedendum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus. Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae.
    </p>
  </div>
</div>

</body>

Side note: Since you found an example website, which does what you need, you can look at it's source to get an understanding of how it works, then replicate that logic, in your project.

Related