3

In my website, I need to display a button where the background is white, and the text gets the color of the background below, which can be a solid color or a background image.

Since the background and the button location are dynamic, I can't use the solutions that where written here.

See Example below.

I'm looking for a css only solution.

Thanks for helping.

Blue backgroundpurple background

Serg Chernata
  • 12,280
  • 6
  • 32
  • 50
user3063182
  • 521
  • 3
  • 12
  • How is it dynamic? What method is used to choose the color? Why can't you just set the color twice, once on background and once on text, whenever the color is picked? – amflare Sep 13 '18 at 18:31
  • @amflare Responsive - in different screen sizes location can be different, which means that text color can be different if the background is an image. Besides, if the button is below a text which is dynamic - the length of the text can affect the location of the button. – user3063182 Sep 13 '18 at 18:36
  • in the question you linked there is a perfect solution : https://stackoverflow.com/a/29747686/8620333 .. why it's not suitable for you? – Temani Afif Sep 13 '18 at 19:42

2 Answers2

10

You can get this effect by adding the button's background in front of the text, using a pseudo element, and then using mix-blend-mode on the button (screen), and the pseudo element (color-burn) to create the cutout effect.

Note: this will only work if the button's background is white.

Note: mix-blend-mode is not supported by IE.

.button {
  position: relative;
  padding: 0.5em 1em;
  font-size: 1.2em;
  border: none;
  background: none;
  outline: none;
  color: black;
  mix-blend-mode: screen;
}

.button::before {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: white;
  border-radius: 0.3em;
  content: '';
  mix-blend-mode: color-burn;
}

.bg {
  padding: 2em;
}

.bg1 {
  background: purple;
}

.bg2 {
  background: linear-gradient(to bottom, gold 50%, silver 50%);
}
<div class="bg bg1">
  <button class="button">Text</button>
</div>

<div class="bg bg2">
  <button class="button">Text</button>
</div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1

As ansered by Ori Drori, mix-blend-mode is the way to go but there's no need to use pseudo elements. Just mix background-color, color and mix-blend-mode depending on the background you want.

Light backgrounds generally needs color: black and mix-blend-mode: lighten while dark backgrounds needs the opposite to work. A few examples:

.white {
  background-color: white;
  color: black;
  mix-blend-mode: lighten;
}

.black {
  background-color: black;
  color: white;
  mix-blend-mode: darken;
}

.blue {
  background-color: darkblue;
  color: white;
  mix-blend-mode: darken;
}

.yellow {
  background-color: lightyellow;
  color: black;
  mix-blend-mode: lighten;
}

.button {
  margin-top: 0.25rem;
  border: none;
  padding: 1rem 2rem;
  border-radius: 10rem;
  font-size: 6rem;
  cursor: pointer;
}

body {
  background-color: pink;
}

.bg {
  position: absolute;
  top: 0;
  left: 0;
}
svg {
  width: 35rem;
  height: 35rem;
}
svg img {
  width: 100%;
  height: 100%;
}
<div class="bg">
  <svg>
    <image href="https://yari-demos.prod.mdn.mozit.cloud/en-US/docs/Web/SVG/Element/image/mdn_logo_only_color.png" />
  </svg>
</div>
<button class="button white">
  White button
</button>
<button class="button black">
  Black button
</button>
<button class="button blue">
  Blue button
</button>
<button class="button yellow">
  Light yellow
</button>
Calsal
  • 1,375
  • 14
  • 25