Shine effect html animation - html

I have a problem with the animation, I would like the transition to happen only once, or not be visible on both sides. The text stops in the middle or on the sides, trying to change background-position it also did not work
<div class="content">
<p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
</div>
.content p{
font-size: 20px;
line-height: 35px;
font-weight: bold;
font-family: sans-serif;
cursor: pointer;
}
.content p{
background: linear-gradient(to right, white, hsl(0, 0%, 0%) 10%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: shine 2s infinite linear;
}
#keyframes shine {
0% {
background-position: 0;
}
60% {
background-position: 600px;
}
100% {
background-position: 600px;
}
}

Using Reza's code, I was able to modify slightly ".content div" by changing "animation:shine 2.5s infinite;" to "animation:shine 2.5s 1;", and "left" to "-100px".
.content {
position: relative;
overflow: hidden;
width: 600px;
}
.content p {
font-size: 20px;
line-height: 35px;
font-weight: bold;
font-family: sans-serif;
cursor: pointer;
}
.content div {
position: absolute;
top: 0;
height: 100%;
left: -100px;
width: 30%;
background: linear-gradient(to right, white, transparent 50%);
-webkit-text-fill-color: transparent;
animation: shine 2.5s 1;
overflow: hidden;
}
#keyframes shine {
0% {
left: -10%;
}
100% {
left: 110%
}
<div class="content">
<p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<div>
</div>
</div>
https://jsfiddle.net/jasonbruce/1gdx706t/1/

Related

How to create a text slide in animation with CSS?

So I am trying to create a text reveal / text-slide-in animation.
I've created this:
#keyframes slide {
0% {
left: 0;
}
100% {
left: 105%;
}
}
.text-slide-in:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 105%;
animation: slide 1.5s ease infinite;
background: white;
box-shadow: 0 0 15px white, 0 0 10px white, 0 0 5px white;
}
<h1 class="text-slide-in">Lorem ipsum dolor, sit amet consectetur adipisicing elit.</h1>
And that is precisely the effect/animation I am after. The problem is that this basically creates an uneccesary width. You can see the horizontal scrollbar on the snippet.
The other problem with this approach becomes clear when adding a background-color to the parent element:
.site-wrap {
max-width: 700px;
margin: 0 auto;
}
section {
padding: 4rem;
border-radius: 8px;
background-color: red;
}
#keyframes slide {
0% {
width: 100%;
}
100% {
width: 0;
}
}
.text-slide-in {
position: relative;
}
.text-slide-in:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
animation: slide 1.5s ease infinite;
background: white;
box-shadow: 0 0 15px white, 0 0 10px white, 0 0 5px white;
}
<div class="site-wrap">
<section>
<h1 class="text-slide-in">
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
</h1>
</section>
</div>
As you can see, it will not work when a background-color is set.
I've also tried doing this with transform & translateX css properties, but I cannot get that to work either.
What would be a solid solution in this case?
Use clip-path:
#keyframes slide {
0% {
clip-path: inset(0 100% 0 0);
}
100% {
clip-path: inset(0 0 0 0);
}
}
.text-slide-in {
animation: slide 1.5s ease infinite;
}
body {
background:linear-gradient(90deg,red,lightblue);
}
<h1 class="text-slide-in">Lorem ipsum dolor, sit amet consectetur adipisicing elit.</h1>
You could animate the width and start your position on the right instead of animating the left:
#keyframes slide {
0% {
width: 100%;
}
100% {
width: 0;
}
}
.text-slide-in:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
animation: slide 1.5s ease infinite;
background: white;
box-shadow: 0 0 15px white, 0 0 10px white, 0 0 5px white;
}
<h1 class="text-slide-in">Lorem ipsum dolor, sit amet consectetur adipisicing elit.</h1>

Different transition on remove class

Below is the code what I have tried. What I need is when the class get removed after 5s. The notification box should not move up. Just get fade out at same place.
This can be done by adding one more class in setTimeout. I am looking to avoid that.
$('.notify').click(function() {
$('.note').addClass('show');
setTimeout(function() {
$('.note').removeClass('show');
}, 5000);
})
.note {
top: 0%;
width: 300px;
position: fixed;
background: #ccc;
padding: 10px;
left: 50%;
height: 100px;
margin: -50px 0 0 -150px;
opacity: 0;
transition: top 1s, opacity 1.5s;
}
.show {
top: 50%;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="notify">click here</button>
<div class="note">Lorem Ipsum is simply dummy text of the printing and typesetting industry. </div>
Use delay in transition: top 1s 1.5s, opacity 1.5s; and add transition: top 1s,opacity 1.5s; in .show class
$('.notify').click(function() {
$('.note').addClass('show');
setTimeout(function() {
$('.note').removeClass('show');
}, 5000);
})
.note {
top: 0%;
width: 300px;
position: fixed;
background: #ccc;
padding: 10px;
left: 50%;
height: 100px;
margin: -50px 0 0 -150px;
opacity: 0;
transition: top 1s 1.5s, opacity 1.5s;
}
.show {
top: 50%;
opacity: 1;
transition: top 1s,opacity 1.5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="notify">click here</button>
<div class="note">Lorem Ipsum is simply dummy text of the printing and typesetting industry. </div>
You can also do it pure CSS with the :target selector and simple animation:
#note {
width: 300px;
position: fixed;
top: 0;
left: 50%;
background: #ccc;
padding: 10px;
height: 100px;
margin: -50px 0 0 -150px;
opacity: 0;
transition: all 1s;
}
#note:target {
top: 50%;
animation: fadeOut 6s forwards;
}
#keyframes fadeOut {
16.67%, 83.33% {opacity: 1}
100% {opacity: 0}
}
<button class="notify">click here</button>
<div id="note">Lorem Ipsum is simply dummy text of the printing and typesetting industry. </div>
But the only limitation is that it can only run once.

Typewriter effect only with SCSS (width animation)

I am developing a typewritter effect with SCSS, here is the Codepen. To achieve the effect, I animate the width, to 0 to 30rem. I am trying to achieve a more modular workaround, which works in any desired width, no matter the width of the content.
For the moment, I have been only to think with a kind of #mixin which get the width (or max-width) value of the content, but it's not what I am looking for.
I have also tried with a flex container and flex-grow content but I had no luck.
How can achieve this? I am also looking for a way to improve and refactor my code, so I am open to any advice that you could give me.
Here is the snippet (this is CSS, not SCSS as my pen shows):
#import url(https://fonts.googleapis.com/css?family=Anonymous+Pro);
body {
background-color: #1a1a1a;
color: rgba(255, 255, 255, 0.75);
font-size: 16px;
font-family: 'Anonymous Pro', monospace; }
body .typewriter-text {
margin: 4rem auto 0 auto;
white-space: nowrap;
overflow: hidden;
border-right: 1px solid rgba(255, 255, 255, 0.75);
width: 0;
border-right: 1px solid rgba(255, 255, 255, 0.75); }
.line-1 {
animation: blink 1s step-end 7 backwards, type 2s 2s steps(30, end) forwards, blink 1s 3.6s step-end 7, remove-blink 1s 6.3s step-end forwards; }
.line-2 {
animation: remove-blink 0s 0s step-end forwards, type 3s 7.5s steps(40, end) forwards, remove-blink 0s 10.5s forwards; }
.line-3 {
animation: remove-blink 0s 0s step-end forwards, type 3s 10.5s steps(40, end) forwards, blink 1s 14s infinite alternate; }
#keyframes type {
0% {
width: 0;
border-right: 1px solid rgba(255, 255, 255, 0.75); }
100% {
width: 20rem;
border-right: 1px solid rgba(255, 255, 255, 0.75); } }
#keyframes blink {
50% {
border-color: transparent; } }
#keyframes remove-blink {
to {
border-color: transparent; } }
<div class="typewritter-wrapper">
<h1 class="typewriter-text line-1">Lorem Ipsum D</h1>
<p class="typewriter-text line-2">Lorem ipsum dolor sit amet, consectetur adipiscing
elit.</p>
<p class="typewriter-text line-3">Donec vitae est commodo, imperdiet nulla at.</p>
</div>
Thanks!
CSS doesn't have a method to calculate and adjust one element according to another, which would be needed here.
What one can do though, is to use transform, where one cover the text with a pseudo and then move the text element to the left and the pseudo to the right, revealing the text.
The downside, not being able to calculate width's, is that with wider content it will go faster and narrower slower, and the only reasonable way to solve that is to either calculate the text length server side and set the steps/duration using inline style, or client side using a script.
Note, in below sample I removed the "blinking" effect to simplify the code.
Stack snippet
#import url(https://fonts.googleapis.com/css?family=Anonymous+Pro);
body {
background-color: #1a1a1a;
color: rgba(255, 255, 255, 0.75);
font-size: 16px;
text-align: center;
font-family: 'Anonymous Pro', monospace;
}
.typewriter-wrapper {
overflow: hidden;
display: inline-block;
}
.typewriter-text {
display: none;
position: relative;
margin: 2rem auto;
white-space: nowrap;
overflow: hidden;
display: inline-block;
transform: translateX(50%);
padding: 0 2px;
}
.typewriter-text::after {
content: '';
position: absolute;
left: 2px;
top: 0;
right: 0;
bottom: 0;
background: #1a1a1a;
border-left: 1px solid white;
}
.line-1 {
animation: type 2s 0.5s steps(30, end) forwards;
}
.line-1::after {
animation: type2 2s 0.5s steps(30, end) forwards;
}
#keyframes type {
0% {
transform: translateX(50%);
}
100% {
transform: translateX(0);
}
}
#keyframes type2 {
0% {
transform: translateX(0);
}
100% {
transform: translateX(calc(100% - 1px));
}
}
<div class="typewriter-wrapper">
<h1 class="typewriter-text line-1">Lorem Ipsum Dolor</h1>
</div>
<hr>
<div class="typewriter-wrapper">
<p class="typewriter-text line-1">Lorem ipsum dolor Lorem ipsum dolor Lorem ipsum dolor</p>
</div>
Updated.
I also found a solution at CSS Tricks using width, cleverly combined with Flexbox, though the typing faster/slower for short/long text issue applies here too.
Stack snippet
#import url(https://fonts.googleapis.com/css?family=Anonymous+Pro);
body {
background-color: #1a1a1a;
color: rgba(255, 255, 255, 0.75);
font-size: 16px;
text-align: center;
font-family: 'Anonymous Pro', monospace;
}
.typewriter-wrapper {
display: flex;
justify-content: center;
}
.typewriter-text {
position: relative;
margin: 2rem auto;
white-space: nowrap;
overflow: hidden;
width: 0;
border-right: 1px solid white;
}
.line-1 {
animation: type 3s 0.5s steps(30, end) forwards,
blink .5s step-end infinite;
}
#keyframes type {
0% {
width: 0;
}
100% {
width: 100%;
}
}
#keyframes blink {
0%,
100% {
border-color: transparent
}
50% {
border-color: white
}
}
<div class="typewriter-wrapper">
<div>
<h1 class="typewriter-text line-1">Lorem Ipsum Dolor</h1>
</div>
</div>
<hr>
<div class="typewriter-wrapper">
<div>
<p class="typewriter-text line-1">Lorem ipsum dolor Lorem ipsum dolor Lorem ipsum dolor</p>
</div>
</div>

Positioning elements with position:fixed side-by-side each other

For a web application meant for mobile browsers, I want to integrate this simple yet elegant preloader. It's going to reside on top of a translucent overlay. It's also going to have some words on top of it (e.g. "Please wait...", or "Hold on a minute..." etc).
I tried integrating all that. The result is below (run the snippet). It has 3 distinct problems (can you help me solve them all):
1) I haven't been able to position the preloader + it's text on top of the translucent overlay (although I've used a high z-index).
2) Moreover, the preloader graphic is getting skewed in accordance with the length of the sentence on top of it. I want it to be independent of that.
3) Lastly, they're not positioned in the exact middle (vertically speaking).
body{background:#ECF0F1}
.parent{
position:fixed;
z-index:1;
top:50%;
left:50%;
transform:translate(-50%, -50%);
}
.caption{
margin-bottom:1em;
color:gray;
position:relative;
z-index:10;
}
.load{
width:50px;
height:50px;
position:relative;
z-index:10;
}
.load hr{border:0;margin:0;width:40%;height:40%;position:fixed;border-radius:50%;animation:spin 2s ease infinite}
.load :first-child{background:#19A68C;animation-delay:-1.5s}
.load :nth-child(2){background:#F63D3A;animation-delay:-1s}
.load :nth-child(3){background:#FDA543;animation-delay:-0.5s}
.load :last-child{background:#193B48}
#keyframes spin{
0%,100%{transform:translate(0)}
25%{transform:translate(160%)}
50%{transform:translate(160%, 160%)}
75%{transform:translate(0, 160%)}
}
.overlay{
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
opacity:0.6;
z-index:100;
background-color:#FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient(
to right,
#FAFAFA,
#FAFAFA 50px,
#E8F5E9 50px,
#E8F5E9 100px
);
}
<body>
<div class="overlay">
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr><hr><hr><hr>
</div>
</div>
</div>
<body>
Note: I'm hoping for pure CSS solutions, no JS involvement. I'd also want to avoid flex-box, and go for something universal (in a backward compatibility sense). E.g. flex-box support dwindles in older versions of Android browser (according to caniuse.com). I want to respect those versions too, hence it's best to stick to well-supported CSS 2.1 properties.
The issue is with the hr element they are placed fixed and they should be absolute to keep their relation with parent container. And then simply add margin:auto to load to center them.
And since parent and overlay elements are both fixed position you can separate them to be able to correctly use z-index and avoid the opacity being applied of overlay:
body {
background: #ECF0F1
}
.parent {
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.caption {
margin-bottom: 1em;
color: gray;
position: relative;
z-index: 10;
}
.load {
width: 50px;
height: 50px;
position: relative;
z-index: 10;
margin: auto;
}
.load hr {
border: 0;
margin: 0;
width: 40%;
height: 40%;
position: absolute;
border-radius: 50%;
animation: spin 2s ease infinite
}
.load :first-child {
background: #19A68C;
animation-delay: -1.5s
}
.load :nth-child(2) {
background: #F63D3A;
animation-delay: -1s
}
.load :nth-child(3) {
background: #FDA543;
animation-delay: -0.5s
}
.load :last-child {
background: #193B48
}
#keyframes spin {
0%,
100% {
transform: translate(0)
}
25% {
transform: translate(160%)
}
50% {
transform: translate(160%, 160%)
}
75% {
transform: translate(0, 160%)
}
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.6;
z-index: 100;
background-color: #FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient( to right, #FAFAFA, #FAFAFA 50px, #E8F5E9 50px, #E8F5E9 100px);
}
<div class="overlay">
</div>
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr>
<hr>
<hr>
<hr>
</div>
</div>
The preloader is a child of the overlay, therefore it will have the parent opacity, no way to avoid that but setting it outside the overlay, maybe as a sibling, and adjust the overlay with a negative z-index
As for the sizing, the he are ignoring the parent size as they are set to position:fixed, should be absolute
body {
background: #ECF0F1
}
.parent {
position: fixed;
z-index: 1;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.caption {
margin-bottom: 1em;
color: gray;
position: relative;
z-index: 10;
}
.load {
width: 50px;
height: 50px;
position: relative;
z-index: 10;
margin: auto;
}
.load hr {
border: 0;
margin: 0;
width: 40%;
height: 40%;
position: absolute;
border-radius: 50%;
animation: spin 2s ease infinite
}
.load :first-child {
background: #19A68C;
animation-delay: -1.5s
}
.load :nth-child(2) {
background: #F63D3A;
animation-delay: -1s
}
.load :nth-child(3) {
background: #FDA543;
animation-delay: -0.5s
}
.load :last-child {
background: #193B48
}
#keyframes spin {
0%,
100% {
transform: translate(0)
}
25% {
transform: translate(160%)
}
50% {
transform: translate(160%, 160%)
}
75% {
transform: translate(0, 160%)
}
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.6;
z-index: -10;
background-color: #FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient( to right, #FAFAFA, #FAFAFA 50px, #E8F5E9 50px, #E8F5E9 100px);
}
<div class="overlay">
</div>
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr>
<hr>
<hr>
<hr>
</div>
</div>

css3 animation delay on right side only

I am creating CSS3 animation to make a div move infinity from left to right.
The code is working except for when the div goes to right side, it has a delay of 3 seconds. On the left side, it is working great.
Here is my code:
#najava {
width: 197px;
height: 22px;
border-radius: 2px;
background-color: transparent;
opacity: 0.8;
font-weight: bold;
position: relative;
padding-left: 5px;
padding-right: 5px;
animation: mymove 5s linear 0s infinite alternate-reverse;
font-size: 16px;
font-family: Tahoma, Geneva, sans-serif;
}
#keyframes mymove {
0% {
left: 0px;
}
100% {
left: 200px;
}
}
#keyframes mymove {
0% {
background-color: transparent;
left: 0px;
right: 0px;
}
33% {
background-color: yellow;
left: 250px;
right: 0px;
}
66% {
background-color: blue;
left: 250px;
right: 250px;
}
100% {
background-color: green;
left: 0px;
right: 250px;
}
}
<div id="najava">
<p>text text text text text</p>
</div>
Here is the reason why this is happening.
Your problem lies in the fact that at 66%, nothing is happening. The left remains at 250px which makes it just stay where it's at. The animation is running as it is programmed to do.
To fix this unwanted behavior, you need to remove the 66% line and change it to a simple 0%, 50%, 100% animation.
#keyframes mymove {
0% {background-color:transparent; left:0px; right:0px;}
50% {background-color:yellow; left:250px; right:0px;}
100% {background-color:green; left:0px; right:250px;}
}
This alteration ensures that at 50%, the div is to the right, and at 100%/0%, it's all the way to the left.
Different organization of keyframes, maybe?
#najava {
width: 197px;
height: 22px;
border-radius: 2px;
background-color: transparent;
opacity: 0.8;
font-weight: bold;
position: relative;
padding-left: 5px;
padding-right: 5px;
animation: mymove 3s linear 0s infinite alternate-reverse;
font-size: 16px;
font-family: Tahoma, Geneva, sans-serif;
}
#keyframes mymove {
0% { left: 0px; }
100% { left: 200px; }
}
#keyframes mymove {
0% {background-color:transparent; left:0px; }
25% {background-color:yellow; left:100px; }
50% {background-color:blue; left:200px; }
75% {background-color:red; left:100px; }
100% {background-color:green; left:0px;}
}
<div id="najava">
<p>text text text text text</p>
</div>
p.s. added 5 steps but you can play with the values...
Change your css a bit
CSS:
#keyframes mymove {
0% {background-color:transparent; left:0px}
33% {background-color:yellow; left:250px}
66% {background-color:blue; left:0px; right:250px;}
100% {background-color:green; left:250px;}
}
Full working code:
#najava {
width: 197px;
height: 22px;
border-radius: 2px;
background-color: transparent;
opacity: 0.8;
font-weight: bold;
position: relative;
padding-left: 5px;
padding-right: 5px;
animation: mymove 5s linear 0s infinite alternate-reverse;
font-size: 16px;
font-family: Tahoma, Geneva, sans-serif;
}
#keyframes mymove {
0% {background-color:transparent; left:0px}
33% {background-color:yellow; left:250px}
66% {background-color:blue; left:0px; right:250px;}
100% {background-color:green; left:250px;}
}
<div id="najava">
<p>text text text text text</p>
</div>
Here is the working Demo