Gooey css effects with contrast parent - css

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

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>

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)

Related

Animating a box-shadow/text-shadow on a circular path?

I'm trying to use CSS animations to create the effect of a light source pointing down on an object, casting a shadow and moving in a circular motion around it. I've created a snippet below to show where I've gotten to so far.
It's sort-of close but at the moment (because I only have 4 keyframes) it's like the light source is moving along a square path. I'd like it to look like it was moving along a circular path.
The only solution I can think of to come close is to add a bunch of more keyframes and create a (for the sake of simplicity) a dodecagon-shaped path, but is there a simpler solution? Is there a type of timing function I could use to ease it into a smoother path? Or could I use some sort of Sass function to automatically calculate the intermediate keyframes?
I should have noted that once I get this working with box-shadows, I'd also like to apply the same method to text-shadows.
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
}
.circle {
width: 200px;
height: 200px;
border-radius: 100%;
background-color: teal;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
#keyframes orbit-shadow {
0% {
box-shadow: 50px 50px 5px darkgrey;
}
25% {
box-shadow: -50px 50px 5px darkgrey;
}
50% {
box-shadow: -50px -50px 5px darkgrey;
}
75% {
box-shadow: 50px -50px 5px darkgrey;
}
1000% {
box-shadow: 50px 50px 5px darkgrey;
}
}
<div class="container">
<div class="circle"></div>
</div>
You have to consider rotation for this. Use a pseudo element to avoid rotating the main element:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
position:relative;
z-index:0;
}
.circle {
width: 200px;
height: 200px;
margin:50px;
border-radius: 100%;
background-color: teal;
position:relative;
}
.circle::before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
border-radius:inherit;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
#keyframes orbit-shadow {
100% {
transform:rotate(360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
Or you simply rotate the element if you won't have any content:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.circle {
width: 200px;
height: 200px;
border-radius: 100%;
background-color: teal;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
#keyframes orbit-shadow {
100% {
transform:rotate(360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
Another idea:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
position:relative;
z-index:0;
}
.circle {
width: 200px;
height: 200px;
margin:50px;
border-radius: 100%;
background-color: teal;
position:relative;
}
.circle::before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
border-radius:inherit;
background:darkgrey;
filter:blur(5px);
animation: orbit-shadow 5s linear infinite;
}
#keyframes orbit-shadow {
0% {
transform:rotate(0deg) translate(50px);
}
100% {
transform:rotate(360deg) translate(50px);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
You can also do the same for text-shadow with a slightly different animation in order to not rotate the text:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.circle {
position:relative;
font-size:40px;
font-weight:bold;
}
.circle::before,
.circle::after{
content:attr(data-text);
position:relative;
z-index:1;
}
.circle::before {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
color:transparent;
text-shadow:0 0 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
/* the 50px is your offset */
#keyframes orbit-shadow {
0% {
transform:rotate(0deg) translate(50px) rotate(0deg);
}
100% {
transform:rotate(360deg) translate(50px) rotate(-360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle" data-text="some text"></div>
</div>

How to create a triangular shape with curved border?

I want to do this shape using CSS not as an image can I but I get the green shape and I can't get the all background transparent !
#arrowbox:before {
right: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(0, 128, 0, 0);
border-right-color: #008000;
border-width: 25px;
margin-top: -25px;
}
You can do it with some perspective and rotation:
.box {
margin:20px;
padding:20px calc(50% - 100px); /* this will fix the max width to 2x100px */
/* the horizontal lines (one on each side)*/
background:
linear-gradient(red,red) left,
linear-gradient(red,red) right;
background-size:calc(50% - 100px) 2px;
background-repeat:no-repeat;
/* */
text-align:center;
position:relative;
}
.box::before,
.box::after{
content:"";
position:absolute;
top:-10px; /* lower than 0 to avoid the overlap due to rotation */
/* same as the padding */
left:calc(50% - 100px);
right:calc(50% - 100px);
/* */
bottom:50%;
border:3px solid red;
border-bottom:none;
border-radius:15px 15px 0 0;
/* adjust here to control the shape */
transform:var(--s,scaley(1)) perspective(40px) rotateX(25deg);
/* */
transform-origin:bottom;
}
.box::after {
--s:scaley(-1);
}
<div class="box"> some text here</div>
<div class="box"> more and more <br> text here</div>
<div class="box"> even more <br> and more <br> text here</div>
Another idea with skew transformation:
.box {
margin:20px;
padding:20px calc(50% - 100px); /* this will fix the max width to 2x100px */
/* the horizontal lines (one on each side)*/
background:
linear-gradient(red,red) left,
linear-gradient(red,red) right;
background-size:calc(50% - 100px) 2px;
background-repeat:no-repeat;
/* */
text-align:center;
position:relative;
}
.box::before,
.box::after,
.box span::before,
.box span::after{
content:"";
position:absolute;
top:0;
left:calc(50% - 100px);
right:50%;
bottom:50%;
border:2px solid red;
border-bottom:none;
border-right:none;
border-radius:10px 0 0 0;
transform:var(--s,scaleX(1)) skew(-35deg);
transform-origin:right bottom;
}
.box::after {
--s:scalex(-1);
}
.box span::before {
--s:scaleY(-1);
}
.box span::after {
--s:scale(-1);
}
<div class="box"><span></span> some text here</div>
<div class="box"><span></span> more and more <br> text here</div>
<div class="box"><span></span> even more <br> and more <br> text here</div>
my best (for the moment...)
.corn6 {
border-top: 1px solid darkblue;
border-bottom: 1px solid darkblue;
width: 200px;
height: 28px;
line-height: 28px;
text-align: center;
position: relative;
margin-left: 30px;
}
.corn6::before,
.corn6::after {
display: block;
position: absolute;
top:0;
width: 20px;
height: 20px;
border-top: 1px solid darkblue;
border-right: 1px solid darkblue;
content:'';
}
.corn6::before {
left: 4px;
transform: translateX(-50%) rotate(225deg) translateY(-5px)
}
.corn6::after {
right: -4px;
transform: translateX(50%) rotate(45deg) translateY(5px)
}
<div class="corn6"> text </div>

button with gradient background and rounded outline

Currently I am using image of the whitish border and inside that I am using the button. But it has responsive issues. Can we create the whole thing with css or eliminate the responsive issue if it cant be done with css.
.header-btn-section img{
display: block;
margin: 0 auto;
margin-top: -23px;
width: 370px;
height: 80px;
}
.header-btn {
padding: 15px 40px 15px 40px;
background: #5760f4;
background-image: -webkit-linear-gradient(left, #5760f4 , #f3135d);
background-image: linear-gradient(to right, #5760f4 , #f3135d);
border-radius: 40px;
border: none;
text-transform: uppercase;
color: #fff;
font-size: 25px;
font-weight: bold;
}
.header-btn:hover {
background: #6e73df;
background-image: -webkit-linear-gradient(left, #f3135d, #5760f4);
background-image: linear-gradient(to right,#f3135d,#5760f4);
}
.btn-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="header-btn-section" style="position: relative">
<img class="btn-background" src="https://i.imgur.com/StNBlDd.png">
<div class="btn-container">
<button class="header-btn">Try DddxdVdDk Free !</button>
</div>
</div>
You can do this with one element considering background, border and background-clip:
.box {
width:200px;
height:70px;
border-radius:70px;
padding:5px; /* Control the space between border and background*/
background-image:linear-gradient(to right,red, blue);
background-clip:content-box; /* Don't color the padding */
border:3px solid #fff;
color:#fff;
font-size:20px;
}
.box:hover {
background-image:linear-gradient(to left,red, blue);
}
body {
background:pink;
}
<button class="box">Some text here</button>
If you want to use the padding to control the spacing, use pseudo element:
.box {
padding:20px 40px;
max-width:220px;
border-radius:70px;
position:relative;
z-index:0;
border:none;
background:none;
color:#fff;
font-size:20px;
}
.box:before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
border-radius:inherit;
padding:5px; /* Control the space between border and background*/
background-image:linear-gradient(to right,red, blue);
background-clip:content-box; /* Don't color the padding */
border:3px solid #fff;
}
.box:hover::before {
background-image:linear-gradient(to left,red, blue);
}
body {
background:pink;
}
<button class="box">Some text here</button>
<button class="box">Some long text here</button>

Border of rectangle with curved side

I have a shape that looks like this
It is a rectangle with a circle behind it. I need to do a border all around it.
I tried to do a border for the rectangle and a curved line for the curved part (based on this). It doesn't seem to be precise enough. The curved line don't align 100% with the circle part. I need precision.
Putting the same shape a bit bigger behind it does not work for what I need.
Code - jsfiddle
.template {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.rectangle {
background: red;
width: 91mm;
height: 63mm;
border-radius: 2mm;
}
.circle {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
z-index: -999;
background: red;
width: 68mm;
height: 68mm;
border-radius: 100%;
}
<div class="template">
<div class="rectangle"></div>
<div class="circle"></div>
</div>
Any ideas of how I could achieve that sweet border?
Use a pseudo element with radial-gradient:
.box {
width:200px;
height:150px;
background:red;
border-radius:10px;
position:relative;
margin-top:50px;
}
.box:before {
content:"";
position:absolute;
bottom:100%;
left:0;
right:0;
height:50px; /* Same as margin*/
background:radial-gradient(circle,red 49.5%,transparent 50%) top/150% 400%;
}
<div class="box">
</div>
Then you can add border:
.box {
width:200px;
height:150px;
background:red;
border-radius:10px;
position:relative;
margin-top:50px;
border:3px solid blue;
}
.box:before {
content:"";
position:absolute;
bottom:100%;
left:0;
right:0;
height:50px; /* Same as margin*/
background:radial-gradient(circle,red 49.5%,blue 50% calc(50% + 3px),transparent calc(50% + 4px)) top/150% 400%;
}
<div class="box">
</div>
And also use a transparent color:
.box {
width:200px;
height:150px;
background:rgba(255,0,0,0.5) padding-box;
border-radius:10px;
position:relative;
margin-top:50px;
border:3px solid blue;
border-top-color:transparent;
}
.box:before {
content:"";
position:absolute;
bottom:100%;
left:0;
right:0;
height:50px; /* Same as margin*/
background:radial-gradient(circle,rgba(255,0,0,0.5) 49.5%,blue 50% calc(50% + 3px),transparent calc(50% + 4px)) top/150% 400%;
}
.box:after {
content:"";
position:absolute;
top:-3px;
height:100%;
left:-3px;
right:-3px;
border-top:3px solid blue;
border-right:3px solid transparent;
border-left:3px solid transparent;
border-radius:inherit;
clip-path:polygon(0 0,28px 0,28px 50px,calc(100% - 28px) 50px,calc(100% - 28px) 0, 100% 0,100% 100%,0 100%);
}
body {
background:url(https://picsum.photos/id/1001/800/800) center/cover;
}
<div class="box">
</div>

Text on image not displaying

Text on my image is not appearing. Its animating but i want text on my image on mouse hover. For text I used button with image that suppose to popup on mouse hover.let me know my mistake. I am using this code from youtube tutorial.
.main
{
border: 10px solid white;
width:378px;
height:250px;
margin:50px auto;
box-shadow:0px 0px 25px black;
overflow:hidden;
}
.main:hover img
{
-webkit-transform:scale(2,2) rotate(45deg);
}
.main:hover .content
{
-webkit-transform:translate(-311px);
}
img
{
-webkit-transition: -webkit-transform: 300ms;
}
.content
{
width:378px;
height:250px;
background: rgba(124,120,120,0.5);
-webkit-transition: -webkit-transform: 300ms;
}
button
{
width:100%;
height:50px;
margin-top:200px;
background:black;
border:0;
cursor:pointer;
color:white;
font:16px tahoma;
}
button:hover {
opacity: 0.5;
}
<div class="main"><img src="img/switch.jpg" height="250" width="378"><div class="content"><button>Pepe Kalvier Switches</button></div></div>
You can use the position absolute to move your text/button above the image when hover.
CSS
.main:hover .content{
z-index: 9999;
position: absolute;
top:0;
}
DEMO HERE
you can try this one:
<div class="main"><img src="http://dev.boutiquevalmont.com/media/wysiwyg/valmont/arts/thb3.jpg" height="250" width="378"><div class="content"><button>Pepe Kalvier Switches</button></div></div>
DEMO

Resources