Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gooey css effects with contrast parent

Tags:

I'm trying to create gooey effect with CSS only (without svg). Everything goes right but my parent container has a contrast filter and I can't use colors on my child elements (the contrast filter changes the colors).

Does someone know of a basic way to make this effect with only CSS or reverse the contrast filter to get my right colors on the child elements?

My code:

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blob {
  background:black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  -webkit-transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  box-shadow: 0 0 30px 10px black;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

When I'm coloring the child elements:

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blob {
  background: rgb(255, 113, 93);
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  -webkit-transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
  box-shadow: 0 0 30px 10px rgb(255, 113, 93);
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}

.original-color {
  height: 100px;
  background: rgb(255, 113, 93);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="original-color"></div>

My fiddle

like image 758
Zeev Katz Avatar asked Nov 03 '16 12:11

Zeev Katz


2 Answers

I have taken your effect. On the container, I have set a pseudo element that covers it, with whatever color you want.

And with a mix-blend-mode, I can set this color where the container is black, keeping the remaining white:

(By the way, a very nice effect !)

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blobs:after {
  content: "";
  position: absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background-color: coral;  
  mix-blend-mode: lighten;
}

.blob {
  background:black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
  box-shadow: 0 0 30px 10px black;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

Added another way to get your request. This is harder to set up, but will work on Edge, where filter is available but blend modes do not.

This snippet involves using 2 of your previous setting, and a different primary color for each. (You could already achieve primary colors with your original setting).

To get a particular color, you set different alphas to the 2 settings, and somehow you can achieve any color that you want (even though the process is not easy)

body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
  opacity: 0.99;
}


.blob {
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 2.5s;
}

.blobs:hover .blob:first-child,  
.blobs:hover ~ .blobs .blob:first-child {
  transform:translateX(-70px);
}
.blobs:hover .blob:last-child, 
.blobs:hover ~ .blobs .blob:last-child {
  transform:translateX(70px);
}
.blobs:nth-child(1)  {
  opacity: 0.57;
}
.blobs:nth-child(1) .blob {
  background: red;
  box-shadow: 0 0 30px 10px red;
}
.blobs:nth-child(2)  {
  pointer-events: none;
  opacity: 0.08;
}
.blobs:nth-child(2) .blob {
  background: yellow;
  box-shadow: 0 0 30px 10px yellow;
}
.test {
    width: 100px;
  height: 100px;
  position: absolute;
  left: 0px;
  background-color: rgb(255, 113, 93);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<div class="test"></div>

Another try, this time with a more complex filter.

The color is achieved with a hue-rotate

body {
  background: #fff;
}
.blobs {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #fff;
  width: 400px;
  height: 200px;
  margin: auto;
  -webkit-filter: contrast(20) hue-rotate(-25deg);
  filter: contrast(20) hue-rotate(-25deg);
}
.blob {
  background: red;
  width: 100px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-top: -50px;
  margin-left: -50px;
  border-radius: 100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
  box-shadow: 0 0 30px 10px red;
}
.blobs:hover .blob:first-child {
  transform: translateX(-70px);
}
.blobs:hover .blob:last-child {
  transform: translateX(70px);
}
<div class="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>

Another try, this time a single div ....

.test {
  border: 1px solid black;
  width: 600px;
  height: 400px;
  background-color: white;
  background-image: radial-gradient(circle, red 100px, transparent 140px), radial-gradient(circle, red 100px, transparent 140px);
  background-position: -150px 0px, 150px 0px;
  background-repeat: no-repeat;
  -webkit-filter: contrast(20) hue-rotate(35deg);
  filter: contrast(20) hue-rotate(35deg);
  transition: background-position 2s;
  animation: crazy 13s infinite steps(12);
}
.test:hover {
  background-position: 0px 0px, 0px 0px;
}
@keyframes crazy {
  from {
    filter: contrast(20) hue-rotate(0deg);
  }
  to {
    filter: contrast(20) hue-rotate(360deg);
  }
}
<div class="test"></div>

Trying to get a solution that works cross-browser . Added javascript to check blend-mode availiabily.

Just click the button to run the function.

function check () {
  if('CSS' in window && 'supports' in window.CSS) {
    var support = window.CSS.supports('mix-blend-mode','lighten');
    if ( ! support) {
      var element = document.getElementById('blobs');
      element.classList.add('compat');
    }
}
}
body{
  background: #fff;
}

.blobs {
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background: #fff;
  width:400px;
  height:200px;
  margin:auto;
  filter:contrast(20);
  -webkit-filter:contrast(20);
}

.blobs:after {
  content: "";
  position: absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background-color: coral;  
  mix-blend-mode: lighten;
}

.blob {
  background:black;
  box-shadow: 0 0 30px 10px black;
  width:100px;
  height:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
  border-radius:100%;
  transition: cubic-bezier(0.82, 0.1, 0.24, 0.99) 1.5s;
}

.blobs:hover .blob:first-child {
  transform:translateX(-70px);
}

.blobs:hover .blob:last-child {
  transform:translateX(70px);
}

/* compatibility */

.blobs.compat {
  -webkit-filter:contrast(20)  hue-rotate(-25deg);
  filter:contrast(20)   hue-rotate(-25deg);
}
.blobs.compat:after {
  content: none;
}

.compat .blob {
  background: red;
  box-shadow: 0 0 30px 10px red;
}
<div class="blobs" id="blobs">
  <div class="blob"></div>
  <div class="blob"></div>
</div>
<button onclick="check()">Check</button>
like image 175
vals Avatar answered Oct 20 '22 19:10

vals


For this answer, I only had to make a change to the filter property

contrast(15) contrast(.5) sepia(1) brightness(1.85) hue-rotate(319deg) saturate(3.45)
  • First, we set the contrast to 15 (20 made the edges a little too hard, if you ask me)
  • Then we set it back to .5 (Yes, you can stack these things)

So now we have a lightgray background and darkgray blobs

  • Apply sepia (which gives it a color)
  • Add 1.85 brightness (now the background is white again, and we have colored blobs)
  • hue-rotate to get to the right hue
  • saturate to give it its saturation

The last three properties in the list are essential for getting the right color. Your goal is rgb(255, 113, 93). With this line applied, the colors are rgb(255, 115, 94)

You can see it work in this Fiddle

As a sidenote. You can also stack transforms, which means that if you want to center the blobs, you won't have to use negative margins, but use the translate(-50%, -50%) trick. Then when you hover over them, you can simply stack the transforms like this translate(-50%, -50%) translateX(-70px)

like image 45
Gust van de Wal Avatar answered Oct 20 '22 19:10

Gust van de Wal