Percentage with keyframes broke seconds - css

This code with pixels work perfect but with % seconds change.
Can you help me to find a solution?
Thank you for all your help on this question.
I need to write something... then I write this.
/* .qt-quotes */
.qt-quotes {
width: 600px;
background: linear-gradient(to right, grey 10px, white 0);
animation: qt-qotes-height 1s normal both, qt-qotes-width 1s normal 1s both, qt-qotes-shadow 1s 2s normal both;
}
.qt-quotes p {
height: max-content;
width: max-content;
padding: 2.5px 20px;
animation: qt-qotes-text 1s 2s normal both;
}
#keyframes qt-qotes-height {
from{max-height: 0;}
to{max-height: 100%;}
}
#keyframes qt-qotes-width {
from{max-width: 10px;}
to{max-width: 100%;}
}
#keyframes qt-qotes-text {
from{visibility: hidden;; opacity: 0;}
to{visibility: visible; opacity: 1;}
}
#keyframes qt-qotes-shadow {
from {box-shadow: none;}
to {box-shadow: 0px 0px 30px 0px grey;}
}
/* .qt-not-copyable */
.qt-not-copyable {
user-select: none;
}
<div class="qt-quotes qt-not-copyable">
<p><i>"This isn't a second..."</i></p>
<p>idk</p>
</div>

Related

Define CSS variables inside animation and trigger inner animation from variable inside animation

I'm investigating if I can create a glow effect to jQuery Terminal underline cursor animation that is created with box-shadow.
TL;DR at the bottom there is a demo that is my attempt to define CSS variables inside the animation.
The way to change the animation in jQuery Terminal is to set variable:
:root {
--animation: terminal-underline;
}
and underline animation look like this:
#keyframes terminal-underline {
0%, 50% {
box-shadow: 0 2px 0 #aaa;
box-shadow: 0 2px 0 var(--original-color, #aaa);
}
50.1%, 100% {
box-shadow: none;
}
}
See Demo
To keep the current API of setting animation, my first attempt was to create an inner pseudo-element that will have a height of 2px that will be in the same place as a current underline cursor. To animate it I came up with this hack:
:root {
--size: 1.4;
--glow: 1;
--animation: terminal-underline-2;
}
#keyframes terminal-underline-2 {
0%, 50% {
--terminal-underline: terminal-underline-pseudo 1s infinite linear;
}
50.1%, 100% {
--terminal-underline: terminal-underline-pseudo 1s infinite linear;
}
}
.cmd-cursor [data-text] {
position: relative;
}
.cmd-cursor [data-text]::before {
position: absolute;
content: '';
display: block;
width: 100%;
z-index: 100;
height: 2px;
bottom: -2px;
animation: var(--terminal-underline);
}
#keyframes terminal-underline-pseudo {
0%, 50% {
box-shadow: 0 2px 0 #aaa;
box-shadow: 0 2px 0 var(--original-color, #aaa),
0 2px calc(var(--glow) * 5px) var(--original-color, #aaa);
}
50.1%, 100% {
box-shadow: none;
}
}
But it doesn't work. If I set the animation terminal-underline-pseudo manually it works fine, but I need to trigger it when the main CSS variable --animation is set to terminal-underline.
this works:
.cmd-cursor [data-text]::before {
animation: terminal-underline-pseudo 1s infinite linear;
}
But I need that animation to be conditional.
I also can't use terminal-underline-pseudo as my main animation because box-shadow is outside of the cursor box, not around the border. The original animation use trick where box-shadow x is 0 so only the bottom part of the box-shadow is visible.
Here is the POC of this, but it doesn't work. In Chrome, it shows the color as red but in Firefox it doesn't work at all:
#keyframes animation-var {
0%, 100% {
--anim: animation-inner 1s infinite linear;
--color: red;
}
}
#keyframes animation-inner {
0%, 50% {
background: black;
color: white;
}
50.1%, 100% {
background: white;
color: black;
}
}
.foo {
animation: animation-var 1s infinite linear;
}
.bar {
color: var(--color);
animation: var(--anim);
}
<div class="foo">
<div class="bar">xxxx</div>
</div>
Do have any idea how to make this work? Or maybe how to create

Blend colors in CSS animation

My CSS and a snippet for demonstration:
/*compatibility*/
#-moz-keyframes rainbow {
from {background-position: -100vh 0}
to {background-position: 100vh 0}
}
#-webkit-keyframes rainbow {
from {background-position: -100vh 0}
to {background-position: 100vh 0}
}
#-ms-keyframes rainbow {
from {background-position: -100vh 0}
to {background-position: 100vh 0}
}
#-o-keyframes rainbow {
from {background-position: -100vh 0}
to {background-position: 100vh 0}
}
.rainbow {
padding:0 0 3px 0 !important;
border-bottom: 1px solid transparent;
border-radius: 10px;
/*added a colourstop here, without the third colourstop you get a hard edge*/
background: linear-gradient(#181717, #181717),
linear-gradient(60deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3);
background-origin: border-box;
background-clip: content-box, border-box;
animation-name: rainbow;
animation-duration: 4s;
/*set animation to continue forever, and to move at a single rate instead of easing*/
animation-iteration-count: infinite;
animation-timing-function: linear;
}
https://codepen.io/jhendrix13/pen/zYrMZQz
Is there a way to further increase the gradient/blend between the colors?
I'm trying to get it similar to this snippet, which has a much smoother blend/transition between colors:
https://codepen.io/mike-schultz/pen/NgQvGO
But my knowledge of CSS is minimal, and I'm not sure how to get that result. I think it has something to do with the animation definition itself, but when I try to take the animation definition from the second snippet and put it in the first snippet the animation stops working and goes static.
If you use ::after you can achieve a better effect:
.box {
margin: 20px;
}
.text {
color: white;
padding: 10px 0;
text-align: center;
}
#-webkit-keyframes rainbow {
0% {
background-position: 500% 0%;
}
100% {
background-position: 0% 0%;
}
}
.rainbow {
border-radius: 6px;
background: #000;
}
.rainbow::after {
content: "";
display: block;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
height: 5px;
width: 100%;
background: linear-gradient( 60deg, #ff2400, #e81d1d, #e8b71d, #e3e81d, #1de840, #1ddde8, #2b1de8, #dd00f3, #dd00f3, #ff2400);
background-size: 500% 500%;
animation-name: rainbow;
animation-duration: 50s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
<div class="box rainbow">
<div class="text">
This is a box with a rainbow border.
</div>
</div>
Set it to display block so the width can be set to 100%, move most of the CSS you had in .rainbow over and set the background-size property, then use percent in the keyframes to loop round to the start (use 200% for this, if you use 100% it won't animate).
EDIT
I've just realised this didn't exactly answer your original question. For blending the colors more smoothly, you can increase the background-size of the element and background-position of the animation, then increase the duration, just tweak until it looks right.
I've edited my snippet to show an example.

Display none after css animation ended

I have a working animation that starts on load with pure CSS. The problem with both opacity and visibility is that even if the div is hidden, it still takes up space.
Question
How can I make the div disapear like display: none after the animation is done?
Notes
I would prefer to have a pure CSS solution. The less hackish solution, the better.
I've seen similar questions, but not exactly this case and no good answers for this problem.
I use animation and not transition because it animates on load.
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
padding: 1rem;
}
#keyframes autohide {
0% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
You could use the height property to achieve this effect:
#keyframes autohide {
0% {
opacity: 1;
}
90% {
opacity: 1;
}
99% {
height: auto;
padding: 1rem;
}
100% {
opacity: 0;
height: 0;
padding: 0;
}
}
height is kept auto until near the end of the animation (99%), then set to 0 as it completes.
You could set to zero the padding and the font-size at the last keyframe
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
padding: 1rem;
}
#keyframes autohide {
0% {
opacity: 1;
}
85% {
opacity: 1;
}
95% {
opacity: 0;
padding: 1rem;
font-size: inherit;
}
100% {
padding: 0;
font-size: 0;
opacity: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
There you go i think this is what you want.
By giving height to 0 works perfectly with transition
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
transition: height 2s ease;
}
#keyframes autohide {
0% {
opacity: 1;
height: auto;
}
90% {
opacity: 1;
height: auto;
}
100% {
opacity: 0;
height: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
You can play with transition as per req.

Make blinking cursor disappear at end of CSS animation

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).

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/

Resources