Strange behaviour in CSS3 transition with linear gradient - html

I am trying to make a progress bar and using css3 transition to give it a fill effect.
jsfiddle here
When I give it a fixed size, it works as usual, but Problem is when I set the background-size:100% the fill becomes stretch.
How can I create fill effect using background-size:100%?
Progressbar1 is with fixed width and background-size
Progressbar2 is with 100% width and background-size

/* PROGRESS */
.progress {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 24em;
}
.progress-bar {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 24em 0.25em;
height: 100%;
position: relative;
width:100%
}
.progress2 {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 100%;
}
.progress-bar2 {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 100% 0.25em;
height: 100%;
position: relative;
width:100%
}
/* ANIMATIONS */
#keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0%;
}
100% {
width: 100%;
}
}
<div class="progress">
<div class="progress-bar">
</div>
</div>
<br>
<div class="progress2">
<div class="progress-bar2">
</div>
</div>

Related

Optimize hover overlay animation

I created a specific hover effect only with HTML and CSS.
.cont {
background: blue;
position: relative;
width: 400px;
height: 200px;
margin: 50px;
}
.pre {
background: green;
position: absolute;
height: 0;
width: 100%;
bottom: 0;
clip-path: polygon(100% 100%, 100% 0, 0 100%);
transition: height 0.5s 0.5s;
}
.pre ~ .pre {
background: red;
bottom: auto;
clip-path: polygon(0 0, 100% 0, 0 100%);
}
.cont:hover .pre {
height: 100%;
transition: height 0.5s;
}
.post {
position: absolute;
height: 100%;
width: 100%;
transition: opacity 0s 0.5s, clip-path 0.5s;
background: green;
opacity: 0;
}
.post ~ .post {
background: red;
position: absolute;
height: 100%;
width: 100%;
clip-path: polygon(0 0, 100% 0, 50% 50%, 0 100%);
}
.cont:hover .post {
opacity: 1;
transition: opacity 0s 0.5s, clip-path 0.5s 0.5s;
}
.post ~ .post:hover {
clip-path: polygon(0 0, 100% 0, 90% 80%, 0 100%);
}
.post:hover ~ .post {
clip-path: polygon(0 0, 100% 0, 10% 20%, 0 100%);
}
<div class="cont">
<div class="pre">
<div style="position:absolute;bottom:80px;right:80px;">
some complex html content
</div>
</div>
<div class="pre">
<div style="position:absolute;top:80px;left:80px;">
different complex html content
</div>
</div>
<div class="post">
<div style="position:absolute;bottom:80px;right:80px;">
some complex html content
</div>
</div>
<div class="post">
<div style="position:absolute;top:80px;left:80px;">
different complex html content
</div>
</div>
</div>
The snippet shows the fully working hover effect, but the implementation is pretty awkward.
It uses two divs (class="pre") for creating the "overlay" effect and two separate divs (class="post"), which are only set to opacity: 1 after the "overlay" effect has completed, for creating the "toggle" effect. Also the "toggle" effect is delayed, thus feels kind of sluggish.
I am looking for an implementation (only HTML+CSS) that only uses two divs (+container div) to create the same effects and/or an implementation that removes the "toggle"-delay.
I've already tried using animation to do the "overlay" effect but to no avail.
Any ideas on how a two-div (no pseudo elements) implementation of this effect could be accomplished?

CSS transform skew only top side

I got this shape and trying to achieve this in css3, what I tried so far is:
.door {
width: 150px;
height: 160px;
background-image: linear-gradient(180deg, #234dbc, #b84295);
position: absolute;
top: 100px;
border-radius: 5px;
transform: rotate(17deg) skew(17deg);
background-size: 200% 200%;
animation: Animation 5s ease infinite;
}
#keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:90% 100%}
100%{background-position:10% 0%}
}
<div class="door"></div>
But I couldn't handle this with skew any idea or solution?
You are almost there. Consider a pseudo element to be able to hide the bottom part using overflow:hidden
.door {
width: 100px;
height: 160px;
display: grid;
border-radius: 10px;
overflow:hidden;
transform-origin: bottom;
transform: skewX(-4deg);
}
.door:before {
content:"";
background-image: linear-gradient(180deg, #234dbc, #b84295);
border-radius: inherit;
transform: skewY(17deg);
transform-origin: bottom left;
background-size: 200% 200%;
animation: Animation 5s ease infinite;
}
#keyframes Animation {
50% {
background-position: 90% 100%
}
}
<div class="door"></div>
Always :before solve the problem
.door {
width: 100px;
height: 160px;
background-image: linear-gradient(180deg, #234dbc, #b84295);
position: absolute;
top: 100px;
border-radius: 5px;
background-size: 200% 200%;
animation: Animation 5s ease infinite;
overflow: hidden;
transform: skewX(-2deg)
}
.door::before {
content: "";
position: absolute;
width: 150px;
height: 52px;
background: rgb(248, 248, 248);
top: -30px;
left: 0px;
transform: skewY(18deg);
}
<div class="door"></div>
You should make the :before background like the background of the area to seem like it's transparent
For that i make the background color of the :before rgb(248, 248, 248)

Responsive shine animation using linear-gradient as background

I want to create a shine loading animation which will appear on multiple elements with different background colors.
Currently, I'm using background-image gradient and I'm animating the background-position using vw units, but it's not scalable, my elements will have different lengths.
Is there a way I can animate background-image with percentage units?
The animation created
body {
background: black;
}
header {
width: 100%;
height: 50px;
background-color: rebeccapurple;
background-image: linear-gradient(
to right,
transparent 0%,
rgba(255,255,255,0.3) 50%,
transparent 100%
);
background-repeat: no-repeat;
background-position: -100vw;
animation: shine 2s infinite;
}
#keyframes shine {
0% {
background-position: -100vw;
}
100% {
background-position: 100vw;
}
}
<header></header>
An idea is to make the size of the gradient to be 3 times bigger than the container and color the middle part of it then you slide it from left to right:
body {
background: black;
}
.box {
height: 50px;
margin:5px;
background:
linear-gradient(90deg,#0000 33%,rgba(255,255,255,0.3) 50%,#0000 66%)
rebeccapurple;
background-size:300% 100%;
animation: shine 2s infinite;
}
#keyframes shine {
0% {
background-position: right;
}
/*100% {
background-position: left; it's the default value, no need to define it
}*/
}
<div class="box"></div>
<div class="box" style="width:60%"></div>
<div class="box" style="width:40%"></div>
Another alternative for a different animation:
body {
background: black;
}
.box {
height: 50px;
margin:5px;
background:
repeating-linear-gradient(90deg,#0000 0,rgba(255,255,255,0.3) 25%,#0000 50%)
rebeccapurple;
background-size:200% 100%;
animation: shine 1s infinite linear;
}
#keyframes shine {
0% {
background-position: right;
}
}
<div class="box"></div>
<div class="box" style="width:60%"></div>
<div class="box" style="width:40%"></div>
Related question: Using percentage values with background-position on a linear-gradient

how to change background color of text bottom up

I am trying to make a text color change either bottom up or up to bottom on hover.
.box {
width: 200px; height: 100px;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, green 50%);
-webkit-transition: background-position 1s;
-moz-transition: background-position 1s;
transition: background-position 1s;
}
.box:hover {
background-position: 0 -100%;
}
<div class="box">Text</div>
the above code makes the box change color instead the text. What can I do to make the text color instead of the box.
You gotta use Background Clip:
.box {
width: 200px;
height: 100px;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, green 50%);
-webkit-transition: background-position 3s;
-moz-transition: background-position 3s;
transition: background-position 3s;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: bold;
font-size: 50pt;
}
.box:hover {
background-position: 0 -100%;
}
<div class="box">Text</div>
Note: I have increased the font size and time to 3 seconds to see the effect well.
You can achieve the effect using an overlay (the before pseudo element) with the background, and mix-blend-mode: screen:
.box {
position: relative;
width: 200px;
height: 100px;
font-size: 5em;
background: white;
}
.box::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, green 50%);
transition: background-position 1s;
content: '';
pointer-events: none;
mix-blend-mode: screen;
}
.box:hover::before {
background-position: 0 -100%;
}
<div class="box">Text</div>

Animate div background-position (CSS)

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);
}
}