0

Normal state:

Text

Desired output in hover state:

Text

I have a button that needs to clip the background on both the padding-box and the text in the hover state. I can achieve similiar behaviour by using border-image along with using background-clip: text, however there's no border-radius:

button {
  background-color: #FFFFFF;
  border: 2px solid black;
  color: black;
  padding: 15px 32px;
  text-align: center;
  border-radius: 5px;
}

button:hover {
  border-image: url("https://i.imgur.com/drcgLxf.png");
  border-image-slice: 30;
  background: url("https://i.imgur.com/drcgLxf.png");
  background-size: cover;
  background-repeat: no-repeat;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
<button>text here</button>

I found a way to use background-clip on both the text and the background itself by using a transparent border. I can't find a way to merge both of these together in a single hover state though, as there can only be specified a single background-clip on a single selector.

/* --- BACKGROUND CLIP TEXT ---*/
button.text {
  border: 2px solid black;
  border-radius: 5px;
  background: white;
  padding: 10px;
}

button.text:hover {
  background: url("https://i.imgur.com/drcgLxf.png");
  background-size: cover;
  background-repeat: no-repeat;
  z-index: 1;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* --- END ---*/


/* --- BACKGROUND CLIP PADDING-BOX ---*/
button.padding {
  border: 2px solid black;
  border-radius: 5px;
  background: white;
  background-clip: padding-box;
  padding: 10px;
  position: relative;
}

button.padding:hover {
  border: 2px solid transparent;
}

button.padding::after {
  position: absolute;
  top: -2px;
  bottom: -2px;
  left: -2px;
  right: -2px;
  background: url('https://i.imgur.com/drcgLxf.png');
  background-repeat: no-repeat;
  background-size: cover;
  content: '';
  z-index: -1;
  border-radius: 2px;
}
/* --- END --- */
<button class="text">clipped text</button>
<button class="padding">clipped padding-box</button>

Any JavaScript, jQuery or CSS-solution?

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Sigurd Mazanti
  • 2,098
  • 1
  • 8
  • 24

1 Answers1

1

Use mask to combine both of them (related: Border Gradient with Border Radius)

button {
  padding: 10px;
  position: relative;
  border: none;
  background: var(--i,linear-gradient(#000 0 0)) center/cover repeat;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}

button::after {
  content: '';
  position: absolute;
  inset: 0;
  padding: 2px; /* the border thickness */
  border-radius: 5px;
  background: inherit;
  background-clip: padding-box;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

button:hover {
  --i: url('https://i.imgur.com/drcgLxf.png');
}
<button class="text">clipped text</button>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415