Search code examples
cssanimationhovertransition

Button masked transition


I want a button hover transition using an (I think) mask in the background.

A button that in normal state has a white background and black letters would have a black background sliding in from the side on hover making the letters white on the go. Like so:

Wanted button transition

I got it working using a before and after pseudo:

.button--slide {
  background-color: #fff;
  color: #000;
  border-radius: 10px;
  border: none;
  padding: 10px 20px;
  position: relative;
  transition: all 0.5s ease;
  cursor: pointer;
  overflow: hidden;
}

.button--slide span {
  position: relative;
  z-index: 999;
}

.button--slide:before {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  left: calc(-100% - 35px);
  top: 0;
  background-color: #000;
  transition: left 0.5s ease;
}

.button--slide:after {
  content: "";
  position: absolute;
  top: 0;
  left: -70px;
  width: 0px;
  height: 0px;
  border-left: 35px solid transparent;
  border-right: 35px solid transparent;
  border-top: 35px solid #000;
  transition: left 0.5s ease;
}

.button--slide:hover {
  color: #fff;
}

.button--slide:hover:before {
  left: 0;
}

.button--slide:hover:after {
  left: calc(100% - 35px);
}

See fiddle https://jsfiddle.net/5arj1emx/

It's not quite how I want it: I would like the background to mask the letters like in the example so that the letters turn white as the black background slides over it.

Is this possible?


Solution

  • do a background animation for both the pseudo element and the span and make the one of the span to color the text. I used a big transition time to better see the result;

    body {
      background-color: #efefef
    }
    
    .button--slide {
      background-color: #fff;
      color: #000;
      border-radius: 10px;
      padding:0;
      border: none;
      position: relative;
      cursor: pointer;
      overflow: hidden;
    }
    
    .button--slide span {
      display:block;
      padding: 10px 20px;
      position: relative;
      transition: all 5s ease;
      color:transparent;
      font-weight:bold;
      background:linear-gradient(-45deg,#000 50%,#fff 0) right/220% 100% no-repeat;
      -webkit-background-clip:text;
      background-clip:text;
    }
    
    .button--slide:before {
      content: "";
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
      bottom:0;
      background:linear-gradient(-45deg,transparent 50%,#000 0) right/220% 100% no-repeat;
      transition:  5s ease;
    }
    
    .button--slide:hover span,
    .button--slide:hover:before {
      background-position:left;
    }
    <button class="button--slide">
    <span>SEE OUR GLOBES</span>
    </button>