Make blinking cursor disappear at end of CSS animation - css

I have a blinking cursor animation set up with two lines of text.
I want to have the cursor appear as the text appears, and vanish at the end of the first line – but leave it blinking at the end of the second line.
Someone asked a very similar question, but the solution makes the cursor completely invisible:
Stopping a blinking cursor at end of css animation
Tested this answer code (on several browsers), and it just doesn't work.
Here's what I have:
Code:
.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>

Only Example 2 is fully explained at the moment. Example 3 is exactly the same HTML and CSS as the question with minor changes.
Example 1 — Redesign for background images and gradients
HTML
First, we can clean up the HTML. This is a single paragraph, so let's wrap it in one paragraph element:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
Second, we need to reveal each line individually, so we wrap each line in a nested span element and manually break the line with a line break:
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence. </span>
</span>
</p>
Full Example 1
Current Limitation: We have to set a fixed pixel width for left.
.typewriter {
position: relative;
height: 500px;
margin: 0 auto;
width: 310px;
overflow: hidden;
}
.typewriter .slide,
.inner-slide {
display: inline-block;
overflow: hidden;
height: 1.1em;
}
.typewriter .slide {
position: relative;
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end infinite;
left: -310px;
border-right: .15em solid transparent;
}
.typewriter .slide:nth-of-type(1) {
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end 2.6;
}
.inner-slide {
position: relative;
animation: typing2 2s steps(30, end) forwards;
white-space: nowrap;
left: 310px;
}
.typewriter .slide:nth-of-type(2),
.typewriter .slide:nth-of-type(2) .inner-slide {
animation-delay: 2s;
}
#keyframes typing {
from {
left: -310px;
}
to {
left: 0;
}
}
#keyframes typing2 {
from {
left: 310px;
}
to {
left: 0;
}
}
/*The typewriter cursor effect */
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
body {
background: linear-gradient(to bottom right, #CCC 0, #F00 100%) no-repeat;
}
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence.</span>
</span>
</p>
Example 2 — Original. Suitable for solid colour backgrounds
The HTML
First, we can clean up the HTML. This is a single paragraph, so let's wrap it in one paragraph element:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
Second, we need to reveal each line individually, so we wrap each line in a span element and manually break the line with a line break:
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
The CSS
Now we need an element that will cover our text and act as an animated cursor. We can use a pseudo-element that will start at 100% width and have a left border, like so:
.typewriter > span::before {
content: '';
border-left: .15em solid #00aeff;
position: absolute;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
}
The height is just enough to cover all the text including below the baseline.
The right negative value will pull it outside its parent so the cursor doesn't show on the first line thanks to overflow-hidden on the parent.
It starts at 100% width which is animated to 0.
It is positioned absolute to the span which has a relative position.
In order to keep the cursor on the last line, we need to give it a 0 right value:
.typewriter > span:last-of-type::before {
right: 0;
}
Now it will no longer be pulled outside the parent.
The second line needs to be delayed by the same amount of time as the animation run time:
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
Because we want the paragraph widths to be determined by the width of the text and the span to accept widths, we need to make them inline-block:
.typewriter,
.typewriter > span {
display: inline-block;
}
Lastly, we reverse the typing animation to go from 100% to 0:
#keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
Full Example 2
.typewriter,
.typewriter > span {
display: inline-block;
}
.typewriter > span {
position: relative;
overflow: hidden;
padding-right: 4px;
}
.typewriter > span::before {
content: '';
position: absolute;
border-left: .15em solid #00aeff;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
animation: blink-caret .75s step-end infinite, typing 2s steps(30, end) forwards;
}
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
.typewriter > span:last-of-type::before {
right: 0;
}
/* The typing effect*/
#keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
/*The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent
}
}
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
Example 3 — Using exactly the example from the question
Change the iteration count as appropriate for the first line caret. In this example the value is 4.1. This animation will iterate 4.1 times and then stop:
animation: blink-caret .75s step-end 4.1
The border that creates the caret is changed to transparent:
border-right: .15em solid transparent
and the animation is flipped:
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
Now the stopped state is transparent and the first line will disappear on the first line.
Full Example 3
body {
width: 330px;
}
.typewriter1 p {
overflow: hidden;
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 4.1;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>

I just changed infinite from .typewriter1 p { to 5.
.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 5;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>

If you're not necessarily glued to writing your own animations for this, TypeIt's (https://typeitjs.com) API makes it possible w/ a lot less custom code:
https://codepen.io/alexmacarthur/pen/MWWEPxa
const secondInstance = new TypeIt('.typewriter2 p');
const firstInstance = new TypeIt('.typewriter1 p', {
afterComplete: function (instance) {
document.querySelector('.typewriter1 p .ti-cursor').remove();
secondInstance.go();
}
}).go();
The only downside to this approach is that you have less control over the animation itself (you'd need to override the CSS animation provided by the library).

Related

CSS animations without gradual and with instant change of properties

Using the #keyframes in CSS I can get animations where the properties are changed gradually over the animation-duration. But I want something to change the properties instantly. So that throughout 0% to 25% property of a tag would be one and then it would instantly change, not gradually. How do I do that?
.move-me {
display: inline-block;
padding: 20px;
color: white;
position: relative;
margin: 0 0 10px 0;
}
.move-me-1 {
animation: move-in-steps 8s steps(4) infinite;
}
.move-me-2 {
animation: move-in-steps 8s steps(4, start) infinite;
}
.move-me-3 {
animation: move-in-steps 8s infinite;
}
body {
padding: 20px;
}
#keyframes move-in-steps {
0% {
left: 0;
background: blue;
}
100% {
left: 100%;
background: red;
}
}
<div class="move-me move-me-1">steps(4, end)</div>
<br>
<div class="move-me move-me-2">steps(4, start)</div>
<br>
<div class="move-me move-me-3">no steps</div>
what you need might be steps() in css animation
The code snippet I refer from this page
https://css-tricks.com/using-multi-step-animations-transitions/

How to make CSS animation to do vice versa after being completed?

The code below is a part of my code :
.myBox:hover::after {
animation-name: underline;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
It works nicley, but I want to do it vice versa when animation completed, I mean when it finished then width should be 0 again, In fact for this part I want to do it when my element is not hovered. Which property can help me ?
You need to use alternate and run 2 iterations of the animation:
.box {
height:200px;
background:red;
animation: underline 500ms alternate 2 forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
<div class="box">
</div>
Or consider the use of transition if you want the effect on hover:
.box {
height: 200px;
background: red;
width: 0;
transition: 500ms;
}
body:hover .box {
width: 100%;
}
<div class="box">
</div>
You can specify multiple values for animations rather then from and to using percentage:
#keyframes underline {
0%, 100% { width: 0; }
50% { width: 100%; }
}
More detailed information can be found here.
.myBox:hover::after {
animation-name: underline infinite;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
You infinite for this

how to write css animation for text typing?

<sytle>
.typing{
display: inline-block;
width: 100%;
white-space:nowrap;
overflow:hidden;
-webkit-animation: type 2s steps(50, end) alternate;
animation: type 2s steps(50, end) alternate;
-webkit-animation-iteration-count: infinite; /* Chrome, Safari, Opera */
animation-iteration-count: infinite;
}
#keyframes type{
from { width: 0; }
}
#-webkit-keyframes type{
from { width: 0; }
}
<style>
<div id="top" class="header">
<div class="text-center">
<h1 class="typing" >
<b>Find anything for your Business Instantly</b>
<b>Source >> Supply >> Grow your Business Online</b>
<b>Create your Home & Global website online</b>
</h1>
</div>
</div>
i have 3 bold tags which is in h1 tag, here it should display in one line, As one after another bold tag as shown in the link see this link : http://www.indiamart.com/
Please can anyone help me.
Original code by Lea Verou
#-webkit-keyframes typing {
from { width: 0 }
to { width:16.3em }
}
#-moz-keyframes typing {
from { width: 0 }
to { width:16.3em }
}
#-webkit-keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: black }
}
#-moz-keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: black }
}
body { font-family: Consolas, monospace; }
h1 {
font-size:150%;
width:16.3em;
white-space:nowrap;
overflow:hidden;
border-right: .1em solid black;
-webkit-animation: typing 17s steps(30, end), /* # of steps = # of characters */
blink-caret 1s step-end infinite;
-moz-animation: typing 17s steps(30, end), /* # of steps = # of characters */
blink-caret 1s step-end infinite;
}
<h1>This is a css typewriter</h1>
Use Keyframes to add typing animation to html elements.
.text {
font: bold 200% Consolas;
border-right: .1em solid black;
width: 28ch;
white-space: nowrap;
overflow: hidden;
margin: 30px;
-webkit-animation: type 4s steps(28, end),
blink-caret .4s step-end infinite alternate;
}
#-webkit-keyframes type { from { width: 0; } }
#-webkit-keyframes blink-caret { 50% { border-color: transparent; } }
<p class="text">Stay Hungry ! Stay Foolish !</p>
See Demo here :- http://codingflag.in/mysketch.php?sketch=6

How to make an item fall down with css3 animation

I am working on an exercise about CSS 3 animation. I am stuck on how to keep the item falling down the page at full speed without requiring the user to follow it down with the mouse without resorting to javascript. So just when you hover the mouse over the box the box will fall down.
Here is my code:
<p class="exp9"><strong>box</strong></p>
strong {
margin-top: 20em;
}
p:hover strong {
display: block;
}
p:hover strong:hover {
margin-top: 20em;
}
My code just make the text inside the box drop down. Any idea? Thank you
Use this
/*newly added items start faded out and translated 400px upwards on the y-axis*/
li.new-item {
opacity: 0;
animation: new-item-animation .3s linear forwards;
}
#keyframes new-item-animation {
from {
opacity: 0;
transform: translateY(-400px);
}
to {
opacity: 1;
transform : translateY(0);
}
}
Here is an example of what you can do:
<div class="box">
<p class="innerbox">
Hover
</p>
</div>
CSS:
.innerbox
{
Width:150px;
height:20px;
background-color: lightBlue;
Text-align: center;
Padding:10px 0px;
}
.box
{
Display:inline-block;
Transition: 0.3s 0s All linear;
}
.box:hover
{
Padding-top:20em;
}
In the context of your HTML:
strong
{
Text-align: center; /* this makes it more aesthetic */
Padding:10px 20px; /* this makes the text more easy to hover over */
}
p
{
Display: inline-block; /* this is so the box doesn't stretch the width of the page */
Transition: 0.3s 0s all linear;
}
p:hover
{
padding-top: 20em;
}
Not sure if this is the result you want.
p{
width: max-content; /*add this if you don't want the paragraph to take the whole width*/
}
p strong{
display: block;
}
p:hover strong{
animation: fall .1s linear forwards;
}
#keyframes fall{
0%{
transform: translateY(0);
}
100%{
transform: translateY(20em);
}
}
<p class="exp9"><strong>box</strong></p>

Stop animation and start transition on hover

I have a link that's running an infinite animation with the background color. I want to stop the animation and transition into a different background color on hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation-play-state: paused;
background-color: #014a2a;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
Why is this code not working? And is there an alternate way to get this done? (preferably without Javascript).
Try -webkit-animation: 0;. Demo here. 0 is the default value for animation or what you must set to disable any existing CSS3 animations.
-webkit-animation-play-state: paused
and
-webkit-animation-play-state: running
Found another way round to achieve this.
Write another animation keyframe sequence and call it on your hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation:hoverColor infinite;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
#-webkit-keyframes hoverColor
{
background: #014a2a;
}
I was trying to achieve the same kind of thing and after trying to dynamically change keyframes and all, I found a weird solution by using basic css, see fiddle here. It is not very elegant but does exactly what I (and you, I hope) want.
#menu, #yellow{
position: fixed;
top: 2.5vw;
right: 2.5%;
height: 25px;
width: 25px;
border-radius: 30px;
}
#menu{
animation: blink 2s infinite;
transition: 1s;
}
#keyframes blink{
0% { background-color: grey; }
50% { background-color: black; }
100% { background-color: grey; }
}
#yellow{
background-color: rgba(255, 0, 0, 0);
transition: 1s;
}
#disque:hover #yellow{
pointer-events: none;
background-color: rgba(255, 0, 0, 1);
}
#disque:hover #menu{
opacity: 0;
}
<div id="disque">
<div id="menu"></div>
<div id="yellow"></div>
</div>
I have the same issue and the solution I found is the following.
Create the animation you want and for the element you and to each assign each one a different class.
Then use .mouseover() or .mouseenter() jQuery events toggle between the classes you assigned to each animation.
It is similar to what you use for a burger menu, just with a different handler.
For those who are interested by animation slide with stop between 2 images
var NumImg = 1; //Img Number to show
var MaxImg = 3; //How many Img in directory ( named 1.jpg,2.jpg ...)
function AnimFond() {
NumImg = NumImg> MaxImg ? 1 : NumImg +=1;
var MyImage = "http://startinbio.com/Lib/Images/Fond/" + NumImg + ".jpg";
$("#ImgFond1").attr("src", MyImage);
$("#ImgFond2").fadeOut(3000, function() {
$("#ImgFond2").attr("src", MyImage);
$("#ImgFond2").fadeIn(1);
});
}
setInterval("AnimFond()", 10000); //delay between 2 img
#AnimFond {
position: fixed;
height: 100%;
width: 100%;
margin: 0 0 0 -8;
}
#AnimFond img {
position: absolute;
left: 0;
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div id="AnimFond">
<img id="ImgFond1" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
<img id="ImgFond2" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
</div>

Resources