Search code examples
cssmix-blend-mode

reverse color of buttons on a background with text


I try to create a set of nav buttons that look like this this is how I would like the final result to look like

I was trying with mix-blend-mode but had no success. Would anyone have a suggestion on how I should achieve this? So far I did this

.nav {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #b3b3b3;
}

.skills-btn {
  font-family: Roboto, Arial, Helvetica, sans-serif;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.6rem;
  background-color: #000;
  color: white;
  text-decoration: none;
  border-radius: 60px;
  height: 45px;
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  width: auto;
  max-width: 45px;
  -webkit-transition: max-width 0.5s;
  transition: max-width 0.5s;
  z-index: 9999;
  margin: 0 2px;
}

.skills-btn:hover {
  max-width: 300px;
}

.icon {
  margin-right: 23px;
  padding: 0px 12px;
  display: flex;
  align-items: center;
}

.text {
  white-space: nowrap;
  padding-right: 15px;
}

.skills {
  position: fixed;
  bottom: 10;
  left: 20;
  font-size: 3.8rem;
  line-height: 1.8em;
  font-family: Roboto, sans-serif;
  font-weight: 600;
}
<div id="nav" class="nav">
  <a href="#" class="skills-btn">
    <span class="icon"></span>
    <span class="text">App Skills </span>
  </a>
  <a href="#" class="skills-btn">
    <span class="icon"></span>
    <span class="text">Language Skills</span>
  </a>
  <a href="#" class="skills-btn">
    <span class="icon"></span>
    <span class="text">Fields of Experties</span>
  </a>
  <span class="skills">skills</span>
</div>


Solution

  • This can be achieved using

    • an additional DIV .nav-content in order to move the gray background to the common parent wrapper element (.nav)

    • use filter: invert(100%) on that .nav-content inner element

    • Invert the default initial buttons colors! Background has to be white, color has to be black. Use mix-blend-mode: difference;

    • on buttons hover use mix-blend-mode: normal;, use the normal colors background: #000; color: #fff; and to prevent mousemove flickers bug on Chrome use also filter: invert(100%);

    body {
      font: 1.2rem/1.6rem Roboto, sans-serif;
    }
    
    .nav {
      background: #b3b3b3;
      height: 100vh;
      display: flex;
    }
    
    .nav-content {
      display: flex;
      margin: auto;
      justify-content: center;
      align-items: center;
      gap: 0.4rem;
      filter: invert(100%);
    }
    
    .skills {
      position: absolute;
      font-size: 3.8rem;
      line-height: 1.8em;
      font-weight: 600;
      color: #fff;
    }
    
    .skills-btn {
      text-decoration: none;
      border-radius: 4rem;
      height: 45px;
      display: inline-flex;
      white-space: nowrap;
      align-items: center;
      overflow: hidden;
      max-width: 45px;
      transition: max-width 0.5s;
      background: #fff;
      color: #000;
      mix-blend-mode: difference;
    }
    
    .skills-btn:hover {
      max-width: 300px;
      /* Invert on hover and prevent mousemove flickering bug Chrome */
      mix-blend-mode: normal;
      background: #000;
      color: #fff;
      filter: invert(100%);
    }
    
    .text {
      transition: opacity 0.5s;
      opacity: 0;
      padding: 0 1.5rem;
    }
    
    .skills-btn:hover .text {
      opacity: 1;
    }
    <div id="nav" class="nav">
      <div class="nav-content">
        <span class="skills">skills</span>
        <a href="#" class="skills-btn">
          <span class="text">App Skills </span>
        </a>
        <a href="#" class="skills-btn">
          <span class="text">Language Skills</span>
        </a>
        <a href="#" class="skills-btn">
          <span class="text">Fields of Experties</span>
        </a>
      </div>
    </div>