I am trying to make a CSS marquee whose text fades in from the right edge and fades out on the left edge. Only the letters on the edges should turn transparent. I'd call it an "opacity mask" that is feathered onto the left/right edges.
I can find CSS marquee code samples but none with such a fade in/out effect. I'd also like the background to be completely transparent, with just the text having the edge effects.
I've tried adding a gradient to the container but, in hind sight, that doesn't seem to be the right path. Below is the code I've come up with thus far. Please assist, thanks!
#Bernard Borg: I've updated my code with the second new sample. Other than this not using opacity - and therefore being A) dependent on being hardcoded to the underlying background color and B) only working on a solid background - this is acceptable for my use case. Thanks! (Any idea how to cover the marquee with opacity rather than a color?)
div#container {
width: 60%;
height: 100%;
position: absolute;
background-color: #e6e9eb;
}
div#marquee-container {
overflow: hidden;
}
p#marquee {
animation: scroll-left 10s linear infinite;
}
#keyframes scroll-left {
0% {transform: translateX( 140%)}
100% {transform: translateX(-140%)}
}
div#marquee-cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: linear-gradient(to right, rgba(230, 233, 235, 1) 0%, rgba(230, 233, 235, 0) 15%, rgba(230, 233, 235, 0) 85%, rgba(230, 233, 235, 1) 100%);
}
<div id="container">
<div id="marquee-container">
<p id="marquee">The quick brown fox jumps over the lazy dog</p>
<div id="marquee-cover"/> <!--thanks Bernard Borg-->
</div>
</div>
For anyone coming to this question in the future - the answer to this question was a joint effort. Find the answer in the question.
This is the closest I was able to get to your updated question;
body {
margin: 0;
}
#container {
width: 100%;
height: 100vh;
background-color: grey;
display: flex;
align-items: center;
}
#marquee-container {
overflow: hidden;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
p#marquee {
font-family: 'Segoe UI', sans-serif;
font-size: 30px;
font-weight: bold;
height: 80%;
animation: scroll-left 5s linear infinite;
white-space: nowrap;
}
#first-cover,
#second-cover {
height: 100vw;
backdrop-filter: opacity(50%);
width: 30vw;
z-index: 100;
}
#first-cover {
background: linear-gradient(90deg, rgba(0, 0, 0, 0.8), rgba(128, 128, 128, 0.2));
}
#second-cover {
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.8), rgba(128, 128, 128, 0.2));
}
#keyframes scroll-left {
0% {
transform: translateX(130%);
}
100% {
transform: translateX(-130%);
}
}
<div id="container">
<div id="marquee-container">
<div id="first-cover"></div>
<p id="marquee">The quick brown fox jumps over the lazy dog</p>
<div id="second-cover"></div>
</div>
</div>
For some reason backdrop-filter (specifically with opacity) isn't doing anything. Weird.
Edit:
You could probably define an image for the background of the marquee (with gradients on each side) and then use mix-blend-mode in some way to fade the text. Perhaps I'm overcomplicating this. ¯\(ツ)/¯
Animate the opacity property (cleaned up the code for better readability);
body {
margin: 0;
}
div#marquee-container {
width: 600px;
height: 150px;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 15%, rgba(255, 255, 255, 1) 85%, rgba(255, 255, 255, 0) 100%);
}
p#marquee {
text-align: right;
animation: scroll-left 10s linear infinite;
}
#keyframes scroll-left {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
transform: translateX(-80%);
opacity: 0;
}
}
<div style="background-color: black; width: 100%; height: 100%;">
<div id="marquee-container">
<p id="marquee">Testing</p>
</div>
</div>
Side note: You don't need vendor prefixes for animation anymore.
div#container {
width: 100%;
height: 100%;
position: absolute;
background-color: grey;
}
div#marquee-container {
width: 600px;
height: 150px;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 15%, rgba(255,255,255,1) 85%, rgba(255,255,255,0) 100%);
}
p#marquee {
width: 80%;
height: 80%;
--opacity: 0;
moz-animation: scroll-left 1s linear infinite;
-webkit-animation: scroll-left 1s linear infinite;
animation: scroll-left 10s linear infinite;
}
#-moz-keyframes scroll-left {
0% {-moz-transform: translateX( 100%);}
100% {-moz-transform: translateX(-100%);}
}
#-webkit-keyframes scroll-left {
0% {-webkit-transform: translateX( 100%)}
100% {-webkit-transform: translateX(-100%)}
}
#keyframes scroll-left {
0% {-moz-transform: translateX( 100%); -webkit-transform: translateX( 100%); transform: translateX( 100%); opacity: 0;}
30%{
opacity: 1;
}
60%{
opacity: 0;
}
100% {-moz-transform: translateX(-100%); -webkit-transform: translateX(-100%); transform: translateX(-100%);opacity: 0; }
}
}
<div id="container">
<div id="marquee-container">
<p id="marquee">Testing</p>
</div>
</div>
Related
I'm a novice to web development, and I'd like to make a circle rotate the orientation of its linear gradient smoothly, but there is a jump in between each orientation.
I expected it to be smooth, since I used steps and set the animation-timing-function to linear, but there is a jump in between each step of the animation.
I'm not quite sure how to display the code here, if anyone has any tips for a beginner I would appreciate it.
Edit: Here is the code :)
/* The animation: */
#keyframes gradientShift {
0% {background-image: linear-gradient(to right, rgb(0, 4, 255), rgb(0, 162, 255));}
25% {background-image: linear-gradient(rgb(0, 4, 255), rgb(0, 162, 255));}
50% {background-image: linear-gradient(to right, rgb(0, 162, 255), rgb(0, 4, 255));}
75% {background-image: linear-gradient(rgb(0, 162, 255), rgb(0, 4, 255));}
100% {background: linear-gradient(to right, rgb(0, 4, 255), rgb(0, 162, 255));}
}
/* The other styles*/
.circle-wrapper {
background-image: linear-gradient(to right, rgb(0, 4, 255), rgb(0, 162, 255));
animation: gradientShift;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: linear;
margin-top: 28vh;
width: 12vh;
height: 12vh;
margin-left: 35vh;
border-radius: 100px;
position: absolute;
padding: 3px;
z-index: 1000;
}
<div class="circle-wrapper">
<div class="circle-module"> </div>
</div>
That is because CSS cannot handle transitions in background images. Basically your CSS animation is "stepped" and will have 5 distinct frames with no interpolation in between.
Seeing that you are only rotating the angle of the gradient and not performing and color changes, you can simply set the linear-gradient on a pseudo-element and rotate it instead:
/* The animation: */
#keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
/* The other styles*/
.circle-wrapper {
margin-top: 28vh;
width: 12vh;
height: 12vh;
margin-left: 35vh;
border-radius: 100px;
position: absolute;
padding: 3px;
z-index: 1000;
overflow: hidden;
}
.circle-wrapper::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: linear-gradient(to right, rgb(0, 4, 255), rgb(0, 162, 255));
animation: rotate;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: linear;
content: '';
}
.circle-wrapper>* {
position: relative;
}
<div class="circle-wrapper">
<div class="circle-module"> </div>
</div>
There is no way in css to animate the background-image property.
You see the CSS Animated Properties to know what are the animatable css properties.
But it still possible with javascript, you can use setInterval() with a very small amount of time to change your rotation degree:
let circle = document.getElementsByClassName("circle-wrapper")[0]
let rotateDeg = 0
setInterval(function() {
circle.style.backgroundImage = "linear-gradient(" + ++rotateDeg + "deg, rgb(0, 4, 255), rgb(0, 162, 255))"
}, 2000/360)
.circle-wrapper {
background-image: linear-gradient(to right, rgb(0, 4, 255), rgb(0, 162, 255));
margin-top: 28vh;
width: 12vh;
height: 12vh;
margin-left: 35vh;
border-radius: 100px;
position: absolute;
padding: 3px;
z-index: 1000;
}
<div class="circle-wrapper">
<div class="circle-module"> </div>
</div>
I have a 3D triangle with a base color for every shape, but I want the base (aka the square) to have an animated color, but after adding the animation, the triangles all lay flat all of the sudden. When I remove the animation, the shapes readjust as they should.
For the animation I hue-rotate the linear-gradient color of the square in #keframes animate.
Here is the html code:
<div class="wrapper">
<div class="pyramid">
<div class="square">
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
<div class="triangle"></div>
</div>
</div>
</div>
And CSS:
#-webkit-keyframes animate {
0%, 100% {
filter: hue-rotate(0deg);
}
50% {
filter: hue-rotate(360deg);
}
}
#keyframes animate {
0%, 100% {
filter: hue-rotate(0deg);
}
50% {
filter: hue-rotate(360deg);
}
}
#-webkit-keyframes rotate {
from {
transform: rotateX(120deg) rotateZ(0deg);
}
50% {
transform: rotateX(120deg) rotateZ(180deg);
}
to {
transform: rotateX(120deg) rotateZ(360deg);
}
}
#keyframes rotate {
from {
transform: rotateX(120deg) rotateZ(0deg);
}
50% {
transform: rotateX(120deg) rotateZ(180deg);
}
to {
transform: rotateX(120deg) rotateZ(360deg);
}
}
.wrapper {
position: relative;
display: flex;
justify-content: center;
align-items: center;
top: 500px;
left: 50%;
margin-bottom: 0;
transform-style: preserve-3d;
width: 3.75rem;
height: 3.75rem;
transform-origin: 1.875rem 1.875rem;
transform: rotateX(120deg) rotateZ(45deg);
-webkit-animation: rotate 4s linear infinite;
animation: rotate 4s linear infinite;
}
.pyramid {
position: absolute;
perspective: 500px;
transform-style: preserve-3d;
}
.square {
width: 3.75rem;
height: 3.75rem;
transform-style: preserve-3d;
background: linear-gradient(to left, #008aff, #00ffe7);
-webkit-animation: animate 5s linear infinite;
animation: animate 5s linear infinite;
}
.triangle {
position: absolute;
width: 5rem;
height: 5rem;
}
.triangle:nth-child(1) {
width: 3.75rem;
top: -33%;
background: #f1ecfb;
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
transform-origin: 50% 100%;
transform: rotateX(-68deg);
}
.triangle:nth-child(2) {
width: 3.75rem;
background: #f1ecfb;
-webkit-clip-path: polygon(50% 100%, 0 0, 100% 0);
clip-path: polygon(50% 100%, 0 0, 100% 0);
transform-origin: 50% 0%;
transform: rotateX(68deg);
}
.triangle:nth-child(3) {
height: 3.75rem;
left: -33%;
background: white;
transform-origin: 100% 50%;
-webkit-clip-path: polygon(100% 100%, 0 50%, 100% 0);
clip-path: polygon(100% 100%, 0 50%, 100% 0);
transform: rotateY(68deg);
}
.triangle:nth-child(4) {
height: 3.75rem;
background: white;
transform-origin: 0% 50%;
-webkit-clip-path: polygon(0 100%, 100% 50%, 0 0);
clip-path: polygon(0 100%, 100% 50%, 0 0);
transform: rotateY(-68deg);
}
I changed it so that the animation changes the background color which resolves the issue.
#-webkit-keyframes animate {
0%, 100%{
background: #ffadad;
}
12.5%{
background: #ffd6a5;
}
25%{
background: #fdffb6;
}
37.5%{
background: #caffbf;
}
50%{
background: #9bf6ff;
}
62.5%{
background: #a0c4ff;
}
75%{
background: #bdb2ff;
}
87.5%{
background: #ffc6ff;
}
}
#keyframes animate {
0%, 100%{
background: #ffadad;
}
12.5%{
background: #ffd6a5;
}
25%{
background: #fdffb6;
}
37.5%{
background: #caffbf;
}
50%{
background: #9bf6ff;
}
62.5%{
background: #a0c4ff;
}
75%{
background: #bdb2ff;
}
87.5%{
background: #ffc6ff;
}
}
I am developing an interactive touchscreen at my work which has four tiles on the main screen that look much like the Windows logo. At the moment they are different static colours and they don't look 'alive' and interactive. I want to make them glow or pulsate slightly in random areas and intervals. I thought about creating a white radial gradient and moving it randomly around the outside of each tile so the tile gradient changed, however, I am not sure how to code this in CSS.
I have tried to adapt some copied code that uses radial gradient animations that cycles through the complete hue gradient. The problem with this is I don't want to change the colours because they form the background for text (which can mess with the contrast). The changes can also be rather dramatic, going from a dark colour to very bright, which again messes with the text contrast.
I have already tried a linear gradient but am not happy with it as it is rather predictable and boring (the same gradient going back and forth).
What I am after ideally would be something like this:
Here is a code snippet of what is currently running:
body,html{
margin:0;
padding:0;
height:100%;
}
.box{
height:100%;
width:100%;
}
.gradDynamic{
position:relative;
}
.gradDynamic:after, .gradDynamic:before{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
content:"";
z-index:-1;
}
.gradDynamic:after{
background:radial-gradient(circle,red,transparent);
background-size:400%;
animation:colorSpin 30s linear infinite;
}
.gradDynamic:before{
background-color:yellow;
}
#keyframes colorSpin{
25%{background-position:0 100%}
50%{background-position:100% 100%}
75%{background-position:100% 0}
100%{filter:hue-rotate(360deg)}
}
<div class="box gradDynamic"></div>
I have achieved the animated background with linear gradient background. Lets try this example and comment for further assistance.
.gradient {
height: 400px;
width: 100%;
background: linear-gradient(180deg, #1846c4, #98b2ff, #1846c4);
background-size: 200% 200%;
-webkit-animation: Animation 8s ease infinite;
-moz-animation: Animation 8s ease infinite;
animation: Animation 8s ease infinite;
}
#-webkit-keyframes Animation {
0% {
background-position: 10% 0%;
}
50% {
background-position: 91% 100%;
}
100% {
background-position: 10% 0%;
}
}
#-moz-keyframes Animation {
0% {
background-position: 10% 0%;
}
50% {
background-position: 91% 100%;
}
100% {
background-position: 10% 0%;
}
}
#keyframes Animation {
0% {
background-position: 10% 0%;
}
50% {
background-position: 91% 100%;
}
100% {
background-position: 10% 0%;
}
}
<div class="gradient"></div>
Updated fiddle.
#demo {
width: 100%;
height: 300px;
position: relative;
background: linear-gradient(to bottom, #3bd6f7 0%, #1539b9 100%);
z-index: 2;
}
#demo:after {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
content: "";
z-index: -1;
}
#demo::after {
background-size: 400%;
background-size: 400%;
animation: colorSpin 40s linear infinite;
background: radial-gradient(ellipse at top, rgba(0, 0, 0, 0.1), transparent);
}
#demo::after {
background: radial-gradient(ellipse at bottom, rgba(0, 0, 0, 0.1), transparent);
}
#keyframes colorSpin {
25% {
background-position: 0 100%
}
50% {
background-position: 100% 100%
}
75% {
background-position: 100% 0
}
100% {
filter: hue-rotate(360deg)
}
}
#demo::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(to top, #1539b9 0%, #1539b9 100%);
opacity: 0;
animation: bg 2800ms ease-in-out 3s infinite alternate-reverse;
z-index: -1;
}
#keyframes bg {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="demo">Demo</div>
I have problem to get this border animation working on other browsers (IE).
http://babarogic.disclosed.site check for live preview or snippet down.
Did alot of search on this problem and none of it worked for me. Maybe i am making mistake somewhere.
Thank you
body {
background-color: black;
}
.border-main {
position: fixed;
right: 0%;
left: 0%;
top: 0%;
bottom: 0%;
width: 75%;
/* 90% of viewport vidth */
height: 60%;
/* ratio = 9/16 * 90 = 50.625 */
max-height: 70vh;
max-width: 140vh;
/* 16/9 * 90 = 160 */
margin: auto;
overflow: hidden;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
z-index: 9;
pointer-events: none;
-webkit-animation: clipMe 8s linear infinite;
animation: clipMe 8s linear infinite;
-webkit-border-image:
-webkit-gradient(linear, 0 100%, 0 0, from(white), to(rgba(0, 0, 0, 0))) 1 100%;
-webkit-border-image:
-webkit-linear-gradient(bottom, white, rgba(0, 0, 0, 0)) 1 100%;
-o-border-image:
-o-linear-gradient(bottom, white, rgba(0, 0, 0, 0)) 1 100%;
border-image:
-webkit-gradient(linear, left bottom, left top, from(white), to(rgba(0, 0, 0, 0))) 1 100%;
border-image:
linear-gradient(to top, white, rgba(0, 0, 0, 0)) 1 100%;
}
#-webkit-keyframes clipMe {
0% { height: 0%; }
100% { height: 60%; }
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
#keyframes clipMe {
0% { height: 0%; }
100% { height: 60%; }
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
<div class="border-main"></div>
It works on IE11 here if you put some order in the animation frames:
#keyframes clipMe {
0% { height: 0%; opacity: 0; }
50% { opacity: 1; }
100% { height: 60%; opacity: 0; }
}
Check the result here.
According to MDN, IE11 is doing the right thing: discard repeated keyframes taking only the latest.
If a keyframe is defined multiple times but not all affected
properties are in each keyframe, only the values specified in the
latest keyframe are considered.
I'm creating a CSS3 loading icon effect instead of using GIF. I have created the loading icon effect but I'm unable to make it circle. It is revolving in square instead of circle. Border-radius not working with border-image property ?
HTML
<div id="progress">
<span class="spinner-icon"></span>
</div>
CSS
#progress {
pointer-events: none;
}
#progress .spinner-icon {
width: 30px;
height: 30px;
display:block;
border: solid 2px transparent;
border-radius:50%;
-webkit-animation: progress-spinner 600ms linear infinite;
animation: progress-spinner 600ms linear infinite;
-moz-border-image: -moz-linear-gradient(top, #3acfd5 0%, #3a4ed5 100%);
-webkit-border-image: -webkit-linear-gradient(top, #3acfd5 0%, #3a4ed5 100%);
border-image: linear-gradient(to bottom, #3acfd5 0%, #3a4ed5 100%);
border-image-slice: 1;
}
#progress {
position: absolute;
}
#-webkit-keyframes progress-spinner {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes progress-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
http://jsfiddle.net/44athund/3/
This won't work with border-image. The radius is being applied to the object however the border-image with a gradient will not be respected.
Based on what you what, I've created a fiddle here https://jsfiddle.net/a9dpg582/1/ I think this is what you're after.
#progress {
pointer-events: none;
position: relative;
}
#progress .spinner-icon::after {
content: '';
border-radius: 50%;
background-color: #FFF;
width: 26px;
height: 26px;
position: absolute;
left: 2px;
top: 2px;
}
#progress .spinner-icon {
width: 30px;
height: 30px;
display: block;
background-image: -webkit-linear-gradient(top, #3acfd5 0%, #3a4ed5 100%);
border-radius: 50%;
-webkit-animation: progress-spinner 600ms linear infinite;
animation: progress-spinner 600ms linear infinite;
}
#progress {
position: absolute;
border-radius: 50%;
}
#-webkit-keyframes progress-spinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes progress-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}