2

some parts of this question have already been covered here.

I am trying to create a navigation bar that goes on top of all elements like this:

<div class="navbar">
  ...links...
</div>
<div class="hero-with-image">
  <h1>Hello</h1>
</div>

And then invert navigation links if my hero is dark or has an image on the background. Squarespace has a good example on their home page when you scroll slides.

I am using Ruby On Rails for my back end and one of the solutions I found is to create a helper method for my navigation bar where I define my controller.controller_name && controller.action_name and then add an extra class .has-dark-background to my html tag. But what if I have multiple pages with dark background and multiple pages with light background, is there any way to invert text color based on hero object using jQuery?

Here is a good solution for jquery that I found:

var rgb = [255, 0, 0];

// randomly change to showcase updates
setInterval(setContrast, 1000);

function setContrast() {
  // randomly update
  rgb[0] = Math.round(Math.random() * 255);
  rgb[1] = Math.round(Math.random() * 255);
  rgb[2] = Math.round(Math.random() * 255);

  // http://www.w3.org/TR/AERT#color-contrast
  var o = Math.round(((parseInt(rgb[0]) * 299) +
                     (parseInt(rgb[1]) * 587) +
                     (parseInt(rgb[2]) * 114)) / 1000);
  var fore = (o > 125) ? 'black' : 'white';
  var back = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
  $('#bg').css('color', fore); 
  $('#bg').css('background-color', back);
}

The code above works fine but it can only inver text color based on the current object background.

In other words I do not want to create multiple navigation bars, I just want to invert colours based on the content (hero) background color.

Is there any other solution based on Jquery or Ruby on Rails?

Excuse me for my broken English. Thank you for your help and time.

Anton S.
  • 969
  • 1
  • 11
  • 29
  • you can do it with just CSS – Dalin Huang Oct 06 '17 at 17:58
  • @DanielH can you please explain a little bit more? – Anton S. Oct 06 '17 at 17:59
  • i don't think you can do it with css alone. the question you linked is using JS to determine brightness of a color before setting text to black or white. squarespace is using essentially the same formula, but it's hard to tell exactly how they're determining what the background color is to start with. – worc Oct 06 '17 at 18:09
  • @worc then, I will just create a Rails helper method and list all of the controllers and actions... Thank you for your thoughts anyways – Anton S. Oct 06 '17 at 18:15

2 Answers2

2

Here is the answer that I came up with. I created a helper method for my navigation bar:

# helpers/application_helper.rb
def color_attr
  if %w(pages).include?(params[:controller])
    return 'has-dark-background'
  end
end

Where %w(pages) is a controller name. Then, I just used my helper inside my header tag:

# haml syntax
%header(class="#{color_attr} other-classes" role="banner")

Class has-dark-background manually changes text color to white with additional styles whereas default colors dark. Unfortunately, this method will not change text color dynamically as I wanted.

Update

Not sure if this is the best way of doing it but here is another way:

# about.html.erb
- content_for :navbar_class, 'new_class_1 new_class_2 ...'

# _navbar.html.erb
...
  %header(id="navbarPrimary" class="navbar #{content_for :navbar_class}" role="navigation")
... 
Anton S.
  • 969
  • 1
  • 11
  • 29
1

Is this close to what you want?

div {
  width: 200px;
  height: 200px;
}

.text {
  mix-blend-mode: difference;
  color: white;
}

.wrapper {
  background: url(http://lorempixel.com/400/400/);
}
<div class="wrapper">
  <div class="text">This is my text, hellow World! This is my text, hellow World! This is my text, hellow World! This is my text, hellow World!</div>
</div>
Dalin Huang
  • 11,212
  • 5
  • 32
  • 49
  • @AnthonyBrooks I think to get exactly reverse color you need two image, one as original the other one is reversed, with text set to transparent to show the reversed image, by that you can achieve what you want, I could try if I can make one for that. – Dalin Huang Oct 06 '17 at 18:21
  • Not really, because the `wrapper` and `text` is the same "object". I am trying to make separate navigation bar that will be rendered on every page and invert its colours based on the current page content. For example, home page has a hero image, then navbar links will be white whereas about page does not have a dark hero, navbar links won't be inverted and stay black – Anton S. Oct 06 '17 at 18:23
  • that's a pretty tall order. hero images aren't necessarily all one color. squarespace's hero images are actually just [PNG images with everything except the foreground objects removed](https://static1.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/9158/assets/blocks/content/home-summer-2017/hero/wellness-overlay-1-1500w.png). that gives them plenty of whitespace to not overlap those objects with the text. the hero images don't have colors to compare against. the background color is a separate decision from the hero image. – worc Oct 06 '17 at 18:31
  • Chiming in here, Squarespace has image color detection built into the pipeline which gives you access to an images average color, each corner and middle. To achieve a similar result, you would need to process an image through a library like [Color Thief](https://github.com/lokesh/color-thief) then with that information determine whether the color was light/dark – [TinyColor](https://github.com/bgrins/TinyColor) is great for this. – jfox Oct 07 '17 at 05:10