Using CSS I'd like to animate a radial-gradient circle to expand the full length and width of the page (to fully white) and then reverse this animation (return to original state). This should look like a gradual "blast" of white from the center and fade to fully white once reaching full width/height, however my white background starts transitioning too early. How do I achieve this?
scss
.container {
display: flex;
justify-content: center;
flex-direction: column;
text-align: center;
background: black;
height: 100vh;
}
.flash-container {
animation: grow 5s 2s linear forwards;
width: 20px;
height: 20px;
z-index: 4;
#flash {
background: radial-gradient(circle, white, transparent 10%);
width: 100%;
height: 100%;
position: absolute;
border-radius: 100%;
}
}
#keyframes grow {
to {
transform: scale(1000);
background: white;
}
}
html
<div class="container">
<div class="flash-container">
<div class="flash"></div>
</div>
</div>
Jsfiddle: https://jsfiddle.net/zv3bmw8j/2/
I updated your CSS to use the box-shadow method as I quoted above. This would need more tweaks to do as it was being built on a hover method. Just change the percentage value from 0% - 100% and you should be solid. I also made a change to the HTML format and removed the inner flash div.
https://jsfiddle.net/q9n6adLp/
.flash-container {
animation: grow 5s 2s linear forwards;
width: 20px;
height: 20px;
z-index: 4;
margin: 0 auto;
box-shadow: 0 0 30vw 40vw rgba(241,244,0,1);
.flash {
background: radial-gradient(circle, white, transparent 10%);
width: 100%;
height: 100%;
position: absolute;
border-radius: 100%;
}
}
Related
Trying to smoothly animate a div's background image #bg2 over a short pixel distance (while a clip path animates over it). I'm not able to get the image to move smoothly, it jitters and judders. The clip path animation is fine.
I've tried different easing (linear / ease-in-out etc) suggested in another SO thread, and also extending the distance it needs to move, but it still seems to jump pixel by pixel (sort of), rather than move smoothly. (Although, extending the move distance isn't an option in the actual use case).
How can smooth movement of the cat background image #bg2 be accomplished? Thanks.
** Edit: It's totally smooth for me in Firefox, for me it's jittery in Chrome 91.0.4472.114 on Mojave 10.14.6, and less jittery in Safari. For other it seems to be smooth on Chrome also. Hmmm...
var clickTag = "#";
#main-container {
position: absolute;
width: 970px;
height: 250px;
left:-200px;
box-sizing: border-box;
background: #333;
overflow:hidden; perspective: 800px;
border:1px solid #ccc;
}
div, img {
position: absolute;
background-repeat:no-repeat;
width: 970px;
height: 250px;
z-index: 4;
background-size: 970px 250px;
}
#bg2{
width: 970px;
height: 250px;
z-index:2;
background-image:url('https://i.stack.imgur.com/6EcDu.jpg');
-webkit-clip-path: circle(9% at 682px 110px);
clip-path: circle(9% at 682px 110px);
transform: translateY(20px);
background-position: -5px -10px;
}
#bg2{animation: grow 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;-webkit-animation: groww 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;}
#-webkit-keyframes groww {
0% {opacity:1;transform: translateY(20px);clip-path: circle(9% at 682px 110px);-webkit-clip-path: circle(9% at 682px 110px);background-position: -5px -10px;}
100% {opacity:1;transform: translateY(-4px);clip-path: circle(15% at 682px 128px);-webkit-clip-path: circle(15% at 682px 128px);background-position: 0px 0px;}
}
#keyframes grow {
0% {opacity:1;transform: translateY(20px);clip-path: circle(9% at 682px 110px);background-position: -5px -10px;}
100% {opacity:1;transform: translateY(-4px);clip-path: circle(15% at 682px 128px);background-position: 0px 0px;}
}
<a href="javascript:window.open(window.clickTag)">
<div id="main-container" class="animate">
<div id="bg2"></div>
</div>
</a>
I'm a bit curious about why having a large banner while not displaying it all.
Anyways, I provide another way of animating, basically just changing the height. Hopefully that could give some ideas.
I removed the width to make it slightly more responsive.
The animation somewhat jittery in this solution, but I guess that it depends on your bezier curve. So perhaps that's the issue all along?
var clickTag = "#";
#main-container {
position: relative;
height: 250px;
box-sizing: border-box;
border: 1px solid #ccc;
background-color: #333;
}
#bg2 {
position: absolute;
left: 75%;
top: 50%;
transform: translate(-50%, -50%);
height: 40%;
aspect-ratio: 1;
border-radius: 50%;
background-image: url('https://i.stack.imgur.com/6EcDu.jpg');
background-position: right 25% center;
animation: grow 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;
}
#keyframes grow {
to { height: 80%; }
}
<a href="javascript:window.open(window.clickTag)">
<div id="main-container">
<div id="bg2"></div>
</div>
</a>
Why flex keyframes doesn't work in Safari? In other browsers, all works fine.
<div class="a">
<div class="b"></div>
</div>
.a {
height: 200px;
display: flex;
}
.b {
flex:0 1 50%;
border: 20px solid red;
animation: anim-b 1s infinite;
}
#keyframes anim-b {
0% { flex:0 1 0%; }
100% { flex:0 1 100%; }
}
Animations can be picky (buggy) when one mix longhand and shorthand properties.
In this case Safari also has a bug when animating flex-basis, which I just noticed is still not fixed in ver. 11.
https://github.com/DrummerHead/safari-flex-basis-animation-bug
In this case, for the default row direction, you need to use width instead.
Stack snippet
.a {
height: 200px;
display: flex;
}
.b {
flex:0 1 auto;
width: 50%;
border: 20px solid red;
animation: anim-b 1s infinite;
}
#keyframes anim-b {
0% { width: 0%; }
100% { width: 100%; }
}
<div class="a">
<div class="b"></div>
</div>
I'm trying to implement a full-screen infinite scrolling background effect, which must extend on the entire height and width of the viewport.
Here's the demo.
The solution I've tried was to take a wrapper element that has 100vh and 100vw of the viewport, then place 2 divs inside it, 100% of its height, that have the same background-image and background-size: cover property. The size of the image I've used is: 1,920px × 808px.
Then I've applied the following animation on the wrapper element:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-100%);
}
}
But the problem is that on some viewport sizes, the images are not repeating correctly (because of background-size: cover property):
.
Here's the full code I've tried:
<div class="animated-scene">
<div class="animated-scene__frame animated-scene__frame-1"></div>
<div class="animated-scene__frame animated-scene__frame-2"></div>
</div>
And the css:
.animated-scene {
width: 100vw;
height: 100vh;
position: fixed;
min-height: 400px;
animation: infiniteScrollBg 50s linear infinite;
}
.animated-scene__frame {
width: 100%;
height: 100%;
background-size: cover;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg');
}
Do you have any idea on how could I implement this effect?
Thanks for your help.
For scrolling background, I used background-position instead of using additional element and animate it using transform css properties.
Why you might asked?
Pattern will be seamlessly stitched by the browsers
cleaner HTML code. We just need one element to do this.
The only const doing this method is you need to know the dimension of image you are using.
Example :
/*
specify the scroll x (or y) with the width (or height) of the images
In this case, the image dimension is :
width: 1920px;
height: 808px;
*/
#keyframes bgScroll {
0% {
background-position : 0px 0px
}
100% {
background-position : 0px -808px
}
}
.scrollingBG {
display:block;
width:100vw;
height:100vh;
background-image:url("https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg.jpg");
animation: bgScroll 20s linear infinite;
}
<div class='scrollingBG'></div>
I have used an image element just to use the auto height of it.
Then I use a backgroiund on a pseudo that gives the ability to repeat itself as many times as needed
I have set 2 different containers with different aspect ratios to more easily check the result on different screens
.container {
border: solid 1px black;
overflow: hidden;
position: absolute;
}
#ctn1 {
width: 300px;
height: 150px;
}
#ctn2 {
width: 200px;
height: 350px;
left: 320px;
}
.inner {
width: 100%;
position: relative;
animation: scroll 5s infinite linear;
}
.inner:after {
content: "";
height: 500%;
width: 100%;
position: absolute;
background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
background-size: 100% 20%;
}
.img {
width: 100%;
}
#keyframes scroll {
from {transform: translateY(-100%);}
to {transform: translateY(-200%);}
}
<div class="container" id="ctn1">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
<div class="container" id="ctn2">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
A better solution with media query used to change the way the image is used.
Notice that background-size: cover is needed when both the aspect ratio of the image and the window is unknown. Since you know the aspect ratio of your image, you can control the display with a media query based on it.
Now, when it's needed, the image will adapt not to the width of the container, but to the height of it
#media screen and (max-aspect-ratio: 4/3) {
.inner {
height: 100%;
width: auto !important;
}
.img {
height: 100%;
width: auto !important;
}
}
.container {
border: solid 1px black;
display: inline-block;
overflow: hidden;
}
#ctn1 {
width: 300px;
height: 150px;
}
#ctn2 {
width: 200px;
height: 350px;
}
.inner {
width: 100%;
position: relative;
animation: scroll 5s infinite linear;
display: inline-block;
}
.inner:after {
content: "";
height: 500%;
width: 100%;
left: 0px;
position: absolute;
background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
background-size: 100% 20%;
}
.img {
width: 100%;
}
#keyframes scroll {
from {transform: translateY(-100%);}
to {transform: translateY(-200%);}
}
<div class="container" id="ctn1">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
<div class="container" id="ctn2">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
The issue is with aspect ratio. You're setting the aspect ratio to the view window, and not the image size. So your image ends up getting cut off at the view window aspect.
I worked around in your codepen by changing .animated-scene__frame to this:
.animated-scene__frame {
width: 100%;
height:200vh; //easy way - increase height in animated div to prevent image cutoff. Ideally should be done through javascript using like a 3x multiple of the height of the image. Then just rely on background-repeat during the animation :)
background-size:contain;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
}
I would recommend to just extend the picture 3 times, with:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-66.66%);
}
}
Use some image editor and create a large image with the same pattern, take a look of this site that I made site, there you will find some infinite background pattern
You must use background-position property.
Here's fixed example http://codepen.io/azamat7g/pen/BRwRVV
Full code:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-100%);
}
}
.animated-scene {
width: 100vw;
height: 100vh;
position: fixed;
min-height: 400px;
animation: infiniteScrollBg 50s linear infinite;
}
.animated-scene__frame {
width: 100%;
height: 100%;
background-size: cover;
background-position: bottom left;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
}
.bottom{
background-position: top left;
}
<div class="animated-scene">
<div class="animated-scene__frame animated-scene__frame-1"></div>
<div class="animated-scene__frame animated-scene__frame-2 bottom"></div>
</div>
How can I create a button so that on hover the background colour fills the element from center to left and right of the element.
Example :
I know how to use CSS3 transitions and can get it to animate to the desired shape but can't get it to transition from center outwards.
The shape does not change size I just want to fill it using a transition.
Another way to achieve a similar effect would be to use linear-gradient as the background-image, position the image at the center of the element and then transition background-size from 0% 100% to 100% 100% on hover. Incrementing background-size in X axis from 0% to 100% would mean that the background color will slowly fill up the element and keeping its position fixed at the center would mean that the color would grow from center to the left and right edges at the same time.
Gradients have lower support than transforms and that is one drawback compared to the answer that has been provided by web-tiki's but this approach does not require any extra pseudo-elements which mean that they can be used for other purposes.
div {
position: relative;
display: inline-block;
padding: 15px 70px;
border: 5px solid #B17461;
color: #B17461;
font-size: 30px;
font-family: arial;
background-image: linear-gradient(#B17461, #B17461);
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: 0% 100%;
transition: background-size .5s, color .5s;
}
div:hover {
background-size: 100% 100%;
color: #fff;
}
<div>NEXT</div>
The very same approach can be used for producing a variety of different fill approaches depending on the position of the gradient image.
div {
position: relative;
display: inline-block;
padding: 15px 70px;
border: 5px solid #B17461;
color: #B17461;
font-size: 30px;
font-family: arial;
background-image: linear-gradient(#B17461, #B17461);
background-repeat: no-repeat;
transition: background-size .5s, color .5s;
}
.center-right-left, .center-top-bottom, .center-corner {
background-position: 50% 50%;
}
.to-left {
background-position: 100% 50%;
}
.to-right {
background-position: 0% 50%;
}
.to-top {
background-position: 50% 100%;
}
.to-bottom {
background-position: 50% 0%;
}
.center-right-left, .to-left, .to-right {
background-size: 0% 100%;
}
.center-top-bottom, .to-top, .to-bottom {
background-size: 100% 0%;
}
.center-corner {
background-size: 0% 0%;
}
div:hover {
background-size: 100% 100%;
color: #fff;
}
<h4>From center towards left and right</h4>
<div class='center-right-left'>NEXT</div>
<h4>From center towards top and bottom</h4>
<div class='center-top-bottom'>NEXT</div>
<h4>From center towards corners</h4>
<div class='center-corner'>NEXT</div>
<h4>From right to left</h4>
<div class='to-left'>NEXT</div>
<h4>From left to right</h4>
<div class='to-right'>NEXT</div>
<h4>From bottom to top</h4>
<div class='to-top'>NEXT</div>
<h4>From top to bottom</h4>
<div class='to-bottom'>NEXT</div>
To fill an element with a solid color from center on hover, you can use a pseudo element and CSS3 transitions.
In the following example, the background is made with a pseudo element and scaled from 0 to 1 horizontaly on hover:
div {
position: relative;
display: inline-block;
padding: 15px 70px;
border: 5px solid #B17461;
color: #B17461;
font-size: 30px;
font-family: arial;
-webkit-transition: color .5s;
transition: color .5s;
}
div:before {
content: '';
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: #B17461;
z-index: -1;
-webkit-transform:scaleX(0);
-ms-transform:scaleX(0);
transform:scaleX(0);
-webkit-transition: -webkit-transform .5s;
transition: transform .5s;
}
div:hover {
color: #fff;
}
div:hover:before {
-webkit-transform: scaleX(1);
-ms-transform: scaleX(1);
transform: scaleX(1);
}
<div>NEXT</div>
you can do a button with this structure
<button>
<text layer>
<image layer>
</button>
on.hover -> button > image
transform-origin: center
insert desired effect here
*edit -- seems like you want the text the have color changes while transition is happening..
you can do a 2 image button inside a div
on hover hide the whtie background image and display the div that contains the brown image
<div container>
<img borwn butn>
</div>
Set the width of container to 0 pix and fix it to the center
and then animate just the width will give you the desired results.
I'm working on a ghost floating here.
The issue I'm having is the transform-origin property. Right now the shadow (the ellipse on the bottom) seems to be expanding from the left to the right and then shrinking in that direction again. The behavior I wanted was for the shadow to expand and shrink from the middle - hence the transform-origin: 50% 50%;.
Here's the relevant code, although it helps to look at the Codepen:
.container {
position: absolute;
top: 50%;
left: 50%;
margin-left: -64.5px;
margin-top: -85.5px;
}
.shadow {
margin-left: 22px;
animation: shrink 3s ease-out infinite;
transform-origin: center center;
ellipse {
transform-origin: center center;
}
}
#keyframes shrink {
0% {
width: 20%;
}
50% {
width: 27%;
}
100% {
width: 20%;
}
}
If anyone has any ideas, thank you so much! Really struggling with this for some reason.
Okay I got a solution for you.
What I did was use margin and width for the animation to keep it centered. I also gave the p tag that is containing the svg shadow a set width of the ghost to keep the shadow centered.
Here is the css I edited,
.shadowFrame {
width: 130px;
}
.shadow {
animation: shrink 3s ease-out infinite;
transform-origin: center center;
ellipse {
transform-origin: center center;
}
}
#keyframes shrink {
0% {
width: 90%;
margin: 0 5%;
}
50% {
width: 60%;
margin: 0 20%;
}
100% {
width: 90%;
margin: 0 5%;
}
}
Here is the live link.