Edvard
Edvard

Reputation: 475

Change text color to match dynamic background color

I'm trying to change the color of my links on hover to match the background which is always changing. Here's a JSFiddle of what I have so far: https://jsfiddle.net/Lcz7gk72/

Basically, I want the "[email protected]" to match the body background color on hover.

Would appreciate any help. Unless it's really needed, I'd rather not use jQuery and keep this to just Javascript.

body {
    font: 20px monospace;
    color: #fff;
    -webkit-font-smoothing: antialiased;
    animation: pulse 60s infinite normal;
    -webkit-animation: pulse 60s infinite normal;
    -moz-animation: pulse 60s infinite normal;
    -o-animation: pulse 60s infinite normal;
}
a {
    color: #fff;
    border-bottom: 1px dotted #fff;
    text-decoration: none;
}
a:hover {
    border-bottom: 1px solid #fff;
    position: relative;
}
a:after {
    display: block;
    position: absolute;
    left: 0;
    bottom: 0px;
    width: 0;
    height: 20px;
    background-color: #fff;
    content: "";
    transition: width 0.4s;
}
a:hover {
    color: #fff;
}
a:hover:after {
    width: 100%;
}

@keyframes pulse {
    0% { background-color: #f00; }
    25% { background-color: #0f0; }
    50% { background-color: #00f; }
    75% { background-color: #00a; }
    100% { background-color: #0a0; }
}
@-webkit-keyframes pulse {
    0% { background-color: #f00; }
    25% { background-color: #0f0; }
    50% { background-color: #00f; }
    75% { background-color: #00a; }
    100% { background-color: #0a0; }
}
@-moz-keyframes pulse {
    0% { background-color: #f00; }
    25% { background-color: #0f0; }
    50% { background-color: #00f; }
    75% { background-color: #00a; }
    100% { background-color: #0a0; }
}
@-o-keyframes pulse {
    0% { background-color: #f00; }
    25% { background-color: #0f0; }
    50% { background-color: #00f; }
    75% { background-color: #00a; }
    100% { background-color: #0a0; }
}
<a href="mailto:[email protected]">[email protected]</a>

Upvotes: 3

Views: 1157

Answers (1)

David Thomas
David Thomas

Reputation: 253318

I'd suggest creating a new animation to animate the color property of the text shown on hover of the <a> element, and adding – or changing – a::after (or, indeed, the a:after) rules.

The changes are included, and explained, in the CSS below:

body {
  font: 20px monospace;
  color: #fff;
  -webkit-font-smoothing: antialiased;
  animation: pulse 60s infinite normal;
  -webkit-animation: pulse 60s infinite normal;
  -moz-animation: pulse 60s infinite normal;
  -o-animation: pulse 60s infinite normal;
}
a {
  color: #fff;
  border-bottom: 1px dotted #fff;
  text-decoration: none;

  /* I added this rule to the
  base 'a' rule, to avoid the
  otherwise ghastly jump
  when un-hovering the <a>: */
  position: relative;
}
a:hover {
  border-bottom: 1px solid #fff;
}
a:after {
  display: block;
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 20px;
  background-color: #fff;

  /*
    slowed down significantly, to clearly
    show the transition of the text as it
    progresses across the element: */

  transition: width 3s;

  /* 
  Obtaining the text to show from the
  custom data-attribute: */

  content: attr(data-text);

  /*
  To hide the pseudo-element's
  text in the non-hovered state: */

  overflow: hidden;

  /* 
  /linking to the animation: */

  -webkit-animation: textPulse 60s infinite normal;
  -moz-animation: textPulse 60s infinite normal;
  -o-animation: textPulse 60s infinite normal;
  animation: textPulse 60s infinite normal;
  border-bottom: 1px solid transparent;
}
a:hover:after {
  width: 100%;
}
@keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-webkit-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-moz-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-o-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-webkit-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-moz-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-o-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
<a href="mailto:[email protected]" data-text="[email protected]">[email protected]</a>

External JS Fiddle demo for experimentation and development.

Unfortunately the above solution does require you to ensure that the data-text attribute exists, and is filled with the appropriate text; with that in mind – and despite your preference to not rely upon JavaScript – I'd like to post another snippet that employs a JavaScript function to appropriately fill set, and fill, the data-text attribute on the relevant elements:

// using the Immediately-Invoked Function Expression ('IIFE')
// syntax to invoke the wrapped anonymous function without
// having to call it elsewhere:
(function() {
  // getting all the elements, using document.querySelectorAll(),
  // with the (atrociously long, but explanatory) class-name of
  // 'showBodyBackgroundColoredTextOnHover' (by all means, please,
  // choose a shorter class-name):
  var elems = document.querySelectorAll('.showBodyBackgroundColoredTextOnHover');

  // Using Function.prototype.call() to apply an Array
  // method, Array.prototype.forEach(), on the
  // Array-like NodeList returnd by querySelectorAll():
  Array.prototype.forEach.call(elems, function(el) {
    // the first argument of forEach() is the array-element
    // of the Array over which we're currently iterating:

    // using the HTMLElement.dataset to create the
    // 'data-text' attribute/property value:
    el.dataset.text = el.textContent;
  });
})();

(function() {
  var elems = document.querySelectorAll('.showBodyBackgroundColoredTextOnHover');
  Array.prototype.forEach.call(elems, function(el) {
    el.dataset.text = el.textContent.trim();
  });
})();
body {
  font: 20px monospace;
  color: #fff;
  -webkit-font-smoothing: antialiased;
  animation: pulse 60s infinite normal;
  -webkit-animation: pulse 60s infinite normal;
  -moz-animation: pulse 60s infinite normal;
  -o-animation: pulse 60s infinite normal;
}
a {
  color: #fff;
  border-bottom: 1px dotted #fff;
  text-decoration: none;
  /* I added this rule to the
  base 'a' rule, to avoid the
  otherwise ghastly jump
  when un-hovering the <a>: */
  position: relative;
}
a:hover {
  border-bottom: 1px solid #fff;
}
a:after {
  display: block;
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 20px;
  background-color: #fff;
  /*
    slowed down significantly, to clearly
    show the transition of the text as it
    progresses across the element: */
  transition: width 3s;
  /* 
  Obtaining the text to show from the
  custom data-attribute: */
  content: attr(data-text);
  /*
  To hide the pseudo-element's
  text in the non-hovered state: */
  overflow: hidden;
  /* 
  /linking to the animation: */
  -webkit-animation: textPulse 60s infinite normal;
  -moz-animation: textPulse 60s infinite normal;
  -o-animation: textPulse 60s infinite normal;
  animation: textPulse 60s infinite normal;
  border-bottom: 1px solid transparent;
}
a:hover:after {
  width: 100%;
}
@keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-webkit-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-moz-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@-o-keyframes pulse {
  0% {
    background-color: #f00;
  }
  25% {
    background-color: #0f0;
  }
  50% {
    background-color: #00f;
  }
  75% {
    background-color: #00a;
  }
  100% {
    background-color: #0a0;
  }
}
@keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-webkit-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-moz-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
@-o-keyframes textPulse {
  0% {
    color: #f00;
  }
  25% {
    color: #0f0;
  }
  50% {
    color: #00f;
  }
  75% {
    color: #00a;
  }
  100% {
    color: #0a0;
  }
}
<a href="mailto:[email protected]" class="showBodyBackgroundColoredTextOnHover">[email protected]</a>

External JS Fiddle demo for experimentation and development.

Upvotes: 3

Related Questions