Following code produces sliding gradient animation without any line of javascript code:
html {
height: 100%
}
body {
height: 100%;
margin: 0
}
#keyframes loading {
from {
background-position: -5000% 0, 0 0
}
to {
background-position: 5000% 0, 0 0
}
}
.skeleton {
height: 100%;
animation-name: loading;
animation-duration: 1.5s;
animation-iteration-count: infinite;
background-color: #fff;
background-repeat: no-repeat;
background-image: linear-gradient(90deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, .8) 50%, hsla(0, 0%, 100%, 0)), linear-gradient(#e5e5e5 100%, transparent 0);
background-size: 99% 100%;
}
<div class="skeleton"></div>
I experimented with some properties and still do not understand how it works. Especially, when background-size: 99% 100%; is changed to background-size: 100% 100%; animation slides in opposite direction!
Could you explain it?
I don't know what's your browser and its version. But on my computer, if background-size: 100% 100% then the animation will be stop. (Actually, the background-position will be ignored)
The idea of this trick is moving background-image (linear-gradient) by background-position. (Check the comment in code below for detail)
About your second question, you should refer this answer CSS background-position ignored when using background-size. A quick summary, you can't use percent for background-position if background-size reaches to 100%. This happens because the image in background has no space to move.
If you insist to use background-size with 100%. I afraid you have to use absolute values.
BTW, I've upgraded the code. Now it looks better.
html {
height: 100%
}
body {
height: 100%;
margin: 0
}
#keyframes loading {/* original code */
from {/* This is the position of image of the first frame */
background-position: -5000% 0, 0 0
}
to {/* This is the pos of img of the last frame */
background-position: 5000% 0, 0 0
}
}
#keyframes betterLoading {
0% {/* This is the position of image of the first frame */
background-position: -5000% 0, 0 0
}
50% {
/* This is the pos of img of a frame in the middle happening animation */
/* If duration is 1s then the pos below will be at 0.5s */
background-position: 5000% 0, 0 0
}
100% {/* This is the pos of img of the last frame */
background-position: -5000% 0, 0 0
}
}
.skeleton {
height: 100%;
animation-name: betterLoading;
animation-duration: 1.5s;
animation-iteration-count: infinite;
background-color: #fff;
background-repeat: no-repeat;
background-image: linear-gradient(90deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, .8) 50%, hsla(0, 0%, 100%, 0)), linear-gradient(green 100%, transparent 0);
background-size: 99% 100%, cover;
}
<div class="skeleton"></div>
Related
In my code, on hover the direction of linear-gradient animation is like counterclockwise, how can do it stright linear from top right to bottom left?
.boxstyle
{
background-color:rgba(0,69,255,1);
background-size: 0% 100%;
transition: background-color .5s;
width: 150px;
height: 150px;
}
.boxstyle:hover
{
background-image:linear-gradient(to left bottom, rgba(189,41,242,0) 0%, rgba(189,41,242,0) 40%, rgba(189,41,242, 0.9) 100%);
background-repeat:no-repeat;
background-size: 200% 100%;
transition:background-size 1s, background-color 1s;
}
<div class="boxstyle">hover it</div>
If you really want the pink to start at the top right and move to the bottom left you could use before and after pseudo elements, the before with just the color, the after also with the linear-gradient.
The after pseudo element moves diagonally across to the bottom left on hover of the main element.
.boxstyle {
width: 150px;
height: 150px;
position: relative;
overflow: hidden;
}
.boxstyle::before,
.boxstyle::after {
content: '';
position: absolute;
z-index: -1;
}
.boxstyle::before {
background-color: rgba(0, 69, 255, 1);
width: 100%;
height: 100%;
}
.boxstyle::after {
background-image: linear-gradient(to left bottom, rgba(189, 41, 242, 0) 0%, rgba(189, 41, 242, 0) 40%, rgba(189, 41, 242, 0.9) 100%);
bottom: 100%;
left: 100%;
transition: all 1s linear;
width: 200%;
height: 200%;
}
.boxstyle:hover::after {
bottom: -10%;
left: -10%;
}
<div class="boxstyle">hover it</div>
Old comment: This fits your verbal description of the effect desired, but I suspect it isn't exactly what you intended - did you want it more 'blendy' and subtle, becoming the final picture only at the very end?
UPDATE: Since seeing your images this snippet uses an after that has twice the dimensions of the main element so spreading out the colors more. It 'settles' on a hover a bit beyond the bottom left.
You can try like below. Invert the positions to get the opposite direction. More details: Using percentage values with background-position on a linear-gradient
.boxstyle {
background: linear-gradient(to top right, #0000 40%, rgb(189 41 242/0.9) 100%);
background-size: 200% 200%;
background-position: 0% 100%;
background-color: rgba(0, 69, 255, 1);
transition: .5s;
width: 150px;
height: 150px;
}
.boxstyle:hover {
background-position: 100% 0;
}
<div class="boxstyle">hover it</div>
If you prefer the pink color area to travel through the box (from top right corner to bottom left corner), it can be implemented by setting the linear-gradient so that has the pink area in the middle.
Example:
.boxstyle {
background: linear-gradient(to top right, #0000 10%, rgb(189 41 242/0.9) 40%, rgb(189 41 242/0.9) 60%, #0000 90%);
background-size: 500% 500%;
background-position: 0% 100%;
background-color: rgba(0, 69, 255, 1);
transition: .5s ease-in-out;
width: 150px;
height: 150px;
color: #fff;
}
.boxstyle:hover {
background-position: 100% 0;
}
<div class="boxstyle">hover it</div>
I applied a drop-shadow filter on my clip-path, while the shadow works well on white background, it does not work at all on a darker one (example below) -
It just looks like some weird lines instead of a blurred shadow, The shadow is a bit darker then the background, making the shadow completly black makes it work at the start of the shadow but to the end it has these lines once again.
The code:
body {
margin: 0;
overflow-x: hidden;
height: 2000px;
}
body .headerText {
position: absolute;
top: 50vh;
left: 40vw;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
font-size: 8vh;
z-index: 10;
color: white;
mix-blend-mode: exclusion;
}
body .headerWrap {
position: fixed;
filter: drop-shadow(-30px -30px 60px #363636) drop-shadow(-30px -30px 90px #414141);
-webkit-filter: drop-shadow(-30px -30px 60px #363636) drop-shadow(-30px -30px 90px #414141);
}
body .headerWrap header {
position: fixed;
width: 100vw;
height: 100vh;
background-color: #2e2e2e;
-webkit-clip-path: polygon(0% 0%, 40% 0%, 28% 100%, 0% 100%);
clip-path: polygon(0% 0%, 40% 0%, 28% 100%, 0% 100%);
-webkit-animation: rotate 1s 1;
animation: rotate 1s 1;
-webkit-animation-play-state: paused;
animation-play-state: paused;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-delay: calc(var(--scroll) * -3s);
animation-delay: calc(var(--scroll) * -3s);
}
#-webkit-keyframes rotate {
to {
-webkit-clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
}
}
#keyframes rotate {
to {
-webkit-clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
}
}
body .landing {
width: 100vw;
height: 100vh;
background-color: white;
}
body .content {
width: 100vw;
height: 200vh;
background-color: #424242;
}
<html lang="en">
<head>
</head>
<body>
<div class="headerText"><h1>Hello bruddas</h1></div>
<div class="headerWrap">
<header></header>
</div>
<script>
window.addEventListener('scroll', () => {
document.body.style.setProperty('--scroll',window.pageYOffset / (document.body.offsetHeight - window.innerHeight));
}, false);
</script>
<div class="landing"></div>
<div class="content"></div>
</body>
Answer
The shadow works fine on both colors.
You can barely (or not...) see it, but it's there.
The lines are in fact the shadow.
The problem here, is the low amount of colors rendered by the screen due to the low contrast between the darkest and lightest colors (for the dark one).
Screens have a limited amount of colors. It also depends on the screen type and settings, sometimes you can easily see it (and it's ugly), sometimes you can barely notice that behavior (you just see a smooth gradient).
Example
Here is an example:
Notice I used the same shadow for both sides.
You should be able to see the lines on darker tones (the top of the left side, and all the right side). Maybe you cannot see the lines at all, again, it depends on the output device and settings.
I was wondering if it was possible to split a screen into 2 parts diagonally as shown on the picture. Once I'd hover over Picture A, the diagonal line would shift a bit to the right, revealing more of picture A while hiding a bit of picture B (I'm thinking transition?), and when I'd hover over picture B the opposite would happen.
Thanks in advance,
Martin
The diagonal image transition effect is unique request. I tried my best, Can you please check revealing effect.
section {
border: 1px solid black;
display: flex;
width: 400px;
box-sizing: border-box;
}
.diagonalHover {
position: absolute;
width: 66%;
height: 200px;
transition: all 0.3s ease-out;
}
.diagonalHover.first,
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2016/07/20/22/33/vajdahunyadvar-1531470_960_720.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2020/02/05/22/17/vendetta-4822543__340.jpg);
}
.diagonalHover.first:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.second:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.first:hover + .second {
}
.diagonalHover.first {
left: 0;
top: 0;
-webkit-clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
}
.diagonalHover.second {
right: 0;
top: 0;
-webkit-clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
}
<section>
<div class="diagonalHover first">
</div>
<div class="diagonalHover second">
</div>
</section>
I have a circular div that is vertically and horizontally centered in div. I am trying to achieve a css animation, that it seems like it's fading in from top to bottom.
I thought of making height 0 initially and moving to 50px, however as it is centered, it starts to getting created from the center. Instead, I want to it to get positioned to the initial position and it gets created from top to bottom. Just like there is a square only masking the circle and nothing else, and it moves to down.
#circle {
width: 80px;
height: 80px;
border-radius: 50px;
}
How can I add this a square mask to achieve the below effect?
Please note that background has a gradient, so I can't put a square and assign it a color directly, thus I thought I need to mask them.
How to achieve this effect?
What I have tried:
#keyframes example {
from {height: 0}
to {height: 80px}
}
As the circle is centered, it starts to expand from the middle. This is not what I want. That's why I thought of the mask
Edited answer:
I am able to achieve this with a combination of a image background and background-position animation.
This will not work if you set the background as a CSS color like #fff. it needs to be an image or a gradient. You also need to set background-repeat to no-repeat
The animation simply starts with the background out of the div display area then pulls the the background downward into the display area.
Kindly check the examples in full-screen.
Working snippet (jpeg image as object background):
body {
background: linear-gradient(135deg, rgba(244, 226, 156, 0) 0%, rgba(59, 41, 58, 1) 100%), linear-gradient(to right, rgba(244, 226, 156, 1) 0%, rgba(130, 96, 87, 1) 100%);
margin: 0 auto;
height: 120vh;
overflow: hidden;
}
.sun {
height: 400px;
width: 400px;
border-radius: 100vw;
margin: 5em auto;
animation-name: sunrise;
animation-duration: 10s;
animation-delay: .5s;
animation-timing-function: linear;
animation-iteration-count: 1;
background: url(https://image.ibb.co/eVdQ3Q/white.jpg);
background-repeat: no-repeat;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes sunrise {
from {
opacity: 1;
background-position: 0 -700px;
}
to {
opacity: 1;
background-position: 0 0px;
}
}
<div class="sun"></div>
Working snippet (gradient as object background):
body {
background: linear-gradient(135deg, rgba(244, 226, 156, 0) 0%, rgba(59, 41, 58, 1) 100%), linear-gradient(to right, rgba(244, 226, 156, 1) 0%, rgba(130, 96, 87, 1) 100%);
margin: 0 auto;
height: 120vh;
overflow: hidden;
}
.sun {
height: 400px;
width: 400px;
border-radius: 100vw;
margin: 5em auto;
animation-name: sunrise;
animation-duration: 10s;
animation-timing-function: linear;
animation-iteration-count: 1;
background: linear-gradient(white,white);
background-repeat: no-repeat;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes sunrise {
from {
opacity: 1;
background-position: 0 -700px;
}
to {
opacity: 1;
background-position: 0 0px;
}
}
<div class="sun"></div>
I would like to animate the background of my div. The background position should move from left-top, to right-bottom. For some reason, nothing happens. And I have no idea why
.test {
width: 50%;
height: 250px;
background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%), linear-gradient(to bottom, green 0%, blue 100%);
background-size: 100% 100%;
animation: moving-gradient 1s infinite;
}
#keyframes moving-gradient {
0% {
background-position: left top;
}
100% {
background-position: right bottom;
}
}
JSFiddle:
http://jsfiddle.net/uLedmk5k/
You have to use fixed values for your background animation to work :
#keyframes moving-gradient {
0% {
background-position: 0,0;
}
100% {
background-position: 200px 250px, 200px 250px;
}
}
So you will have to set a fixed width to your element too :
.test {
width: 200px;
Fiddle
Edit from comments
if you set your width to viewport units it will work too :
.test {
width: 50vw;
height: 250px;
and in animation
100% {
background-position: 50vw 250px, 50vw 250px;
}
Fiddle
I'm not sure why but looking to computed tab in Firebug shows that viewport units are actually interpreted as fixed px values
Instead of moving the background image, have you tried moving the element?
translate is a very efficient and smooth (because of its anti-aliasing) way to move elements on screen, plus you can use percentages with ease.
An example Fiddle might help explain?
Although I may have completely misunderstood what you're trying to achieve.
A stupid way but works
http://jsfiddle.net/uLedmk5k/9/
Use 4 div and translate
HTML
<div class="test">
<div class="bg"></div><div class="bg"></div>
</div>
CSS
.test {
width: 50%;
height: 250px;
overflow: hidden;
}
.bg {
white-space: nowrap;
width: 100%;
height: 100%;
animation: moving-gradient 1s infinite;
-webkit-animation: moving-gradient 1s infinite;
}
.bg::after, .bg::before {
content: '';
display: inline-block;
width: 100%;
height: 100%;
background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%), linear-gradient(to bottom, green 0%, blue 100%);
background-size: 100% 100%;
}
#keyframes moving-gradient {
0% {
transform: translate(-100%, -100%);
}
100% {
transform: translate(0, 0);
}
}
#-webkit-keyframes moving-gradient {
0% {
transform: translate(-100%, -100%);
}
100% {
transform: translate(0, 0);
}
}