My UX guy come up with a requirement to animate a text inside a text-box. i have this animation css class, when applied to a text-box animates the text-box. Thats how it should be.
<input type="text" style="width:380px" class="login-wrongPassword" value="Animate This Text not the box">
i have created an example for reference
.login-wrongPassword {
-webkit-animation-name: login-wobble-horizontal;
animation-name: login-wobble-horizontal;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
/* Wobble Horizontal */
#-webkit-keyframes login-wobble-horizontal {
16.65% {
-webkit-transform: translateX(8px);
transform: translateX(8px);
}
33.3% {
-webkit-transform: translateX(-6px);
transform: translateX(-6px);
}
49.95% {
-webkit-transform: translateX(4px);
transform: translateX(4px);
}
66.6% {
-webkit-transform: translateX(-2px);
transform: translateX(-2px);
}
83.25% {
-webkit-transform: translateX(1px);
transform: translateX(1px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
<input type="text" style="width:380px" class="login-wrongPassword" value="Animate This Text not the box">
is is possible to animate only the text and not the text box itself. ??
Use CSS text-indent
.login-wrongPassword {
-webkit-animation-name: login-wobble-horizontal;
animation-name: login-wobble-horizontal;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
/* Wobble Horizontal */
#-webkit-keyframes login-wobble-horizontal {
16.65% {
text-indent: 8px;
}
33.3% {
text-indent: -6px;
}
49.95% {
text-indent: 4px;
}
66.6% {
text-indent: -2px;
}
83.25% {
text-indent: 1px;
}
100% {
text-indent: 0px;
}
}
<input type="text" style="width:380px" class="login-wrongPassword" value="Animate This Text not the box">
Yes. Use padding-left instead of transform
/* Wobble Horizontal */
#-webkit-keyframes login-wobble-horizontal {
16.65% {
padding-left: 10px;
}
33.3% {
padding-left: 5px;
}
49.95% {
padding-left: 8px;
}
66.6% {
padding-left: 3px;
}
83.25% {
padding-left: 5px;
}
100% {
padding-left: 0;
}
}
JSFiddle
As Santi mentions, you can fix the right side by using 'box-sizing: border-box'
Related
I have a text which appears when I run contrastShow function like this:
const contrast = document.getElementById("contrast");
function contrastHide() {
//sfxPlay(sfx.caption_hide);
contrast.classList.add("contrastHide");
contrast.classList.remove("contrastShow");
}
function contrastShow(text) {
contrast.innerHTML = text;
contrast.classList.add("contrastShow");
contrast.classList.remove("contrastHide");
}
contrastShow("This is the text");
setTimeout(() => {
contrast.classList.add("zoomIn");
}, 3000);
.contrast-container {
overflow: hidden;
height: 10vh;
width: 100%;
z-index: 11;
/*outline: 0.1vw dashed orange;*/
}
.vertical-center-contrast {
position: absolute;
top: 73.5vh; /*top: 82vh;*/
padding-top: 10px;
margin: 0;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.contrast {
position: relative;
font-family: "Vazir";
direction: rtl;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 1);
text-align: center;
width: 100%;
font-size: 2vw;
color: rgb(248, 247, 250);
opacity: 0;
margin: 0 auto;
}
.contrastShow {
animation: contrastAnimeShow 0.3s ease-in-out;
animation-fill-mode: forwards ;
}
.contrastHide {
animation: contrastAnimeHide 0.3s ease-in-out;
animation-fill-mode: forwards ;
}
#-webkit-keyframes contrastAnimeShow {
0% { opacity: 0; top: 4vh }
100% { opacity: 1; top: 1.2vh }
}
#-webkit-keyframes contrastAnimeHide {
0% { opacity: 1; top: 1.2vh }
100% { opacity: 0; top: 4vh }
}
.zoomIn {
-webkit-animation: heartbeat 1.5s ease-in-out infinite both;
animation: heartbeat 1.5s ease-in-out infinite both;
}
#-webkit-keyframes heartbeat {
from {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-transform-origin: center center;
transform-origin: center center;
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
to {
-webkit-transform: scale(2);
transform: scale(2);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
<div class ="vertical-center-contrast contrast-container">
<p id="contrast" class="contrast"></p>
</div>
Then I want to animate the text by adding a new class attached to a keyframe animation (using a setTimeout at the very end f the code).
But unexpectedly the text just hides and there is no animation ?!
What I missed and how to fix this?
The heartbeat animation is running, your element is just hidden via opacity. You should set the initial value of .contrast opacity to 1 and use the backwards fill-mode. This way it doesn't fallback to 0 if you overwrite the animation.
const contrast = document.getElementById("contrast");
function contrastHide() {
//sfxPlay(sfx.caption_hide);
contrast.classList.add("contrastHide");
contrast.classList.remove("contrastShow");
}
function contrastShow(text) {
contrast.innerHTML = text;
contrast.classList.add("contrastShow");
contrast.classList.remove("contrastHide");
}
contrastShow("This is the text");
setTimeout(() => {
contrast.classList.add("zoomIn");
}, 3000);
.contrast-container {
overflow: hidden;
height: 10vh;
width: 100%;
z-index: 11;
/*outline: 0.1vw dashed orange;*/
}
.vertical-center-contrast {
position: absolute;
top: 73.5vh; /*top: 82vh;*/
padding-top: 10px;
margin: 0;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.contrast {
position: relative;
font-family: "Vazir";
direction: rtl;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 1);
text-align: center;
width: 100%;
font-size: 2vw;
color: rgb(248, 247, 250);
opacity: 1;
top: 1.2vh;
margin: 0 auto;
}
.contrastShow {
animation: contrastAnimeShow 0.3s ease-in-out;
animation-fill-mode: backwards ;
}
.contrastHide {
animation: contrastAnimeHide 0.3s ease-in-out;
animation-fill-mode: backwards ;
}
#-webkit-keyframes contrastAnimeShow {
0% { opacity: 0; top: 4vh }
100% { opacity: 1; top: 1.2vh }
}
#-webkit-keyframes contrastAnimeHide {
0% { opacity: 1; top: 1.2vh }
100% { opacity: 0; top: 4vh }
}
.zoomIn {
-webkit-animation: heartbeat 1.5s ease-in-out infinite both;
animation: heartbeat 1.5s ease-in-out infinite both;
}
#-webkit-keyframes heartbeat {
from {
-webkit-transform: scale(1);
transform: scale(1);
-webkit-transform-origin: center center;
transform-origin: center center;
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
to {
-webkit-transform: scale(2);
transform: scale(2);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
<div class ="vertical-center-contrast contrast-container">
<p id="contrast" class="contrast"></p>
</div>
Am trying to add a scrolling class to a text every 1 minute once the text finished scrolling i will remove the class and wait for the next 1 minute. Please can anyone help me out on this below is my sample code but it doesn't work as expected.
$(function(event){
$infoLongMessage = $("#infoLongMessage");
var wait = 60000;
var timer = ($infoLongMessage.text().length + wait);
setInterval(function(){
$infoLongMessage.toggleClass("scroll-left");
}, timer);
})
.content{
background-color: #000;
color: #fff;
padding: 6px 10px;
overflow: hidden;
}
#infoLongMessage{
overflow: hidden;
white-space: pre;
display:block;
}
.scroll-left{
/* Starting position */
-moz-transform:translateX(100%);
-webkit-transform:translateX(100%);
transform:translateX(100%);
/* Apply animation to this element */
-moz-animation: scrollleft 15s linear infinite;
-webkit-animation: scrollleft 15s linear infinite;
animation: scrollleft 15s linear infinite;
}
/* Move it (define the animation) */
#-moz-keyframes scrollleft {
0% { -moz-transform: translateX(100%); }
100% { -moz-transform: translateX(-100%); }
}
#-webkit-keyframes scrollleft {
0% { -webkit-transform: translateX(100%); }
100% { -webkit-transform: translateX(-100%); }
}
#keyframes scrollleft {
0% {
-moz-transform: translateX(100%); /* Firefox bug fix */
-webkit-transform: translateX(100%); /* Firefox bug fix */
transform: translateX(100%);
}
100% {
-moz-transform: translateX(-100%); /* Firefox bug fix */
-webkit-transform: translateX(-100%); /* Firefox bug fix */
transform: translateX(-100%);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content">
<span id="infoLongMessage" class="scroll-left">Browser sources let you display a webpage from the internet or a local file and are commonly used for widgets and alerts</span>
</div>
You don't need any js to achieve your idea. You need a ticker. Also you can put delay to your animation if you need.
#-webkit-keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
#keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
.ticker-wrap {
position: fixed;
top: 0;
width: 100%;
overflow: hidden;
background-color: #9a1f1f;
color: #fff;
padding: 6px 10px;
padding-left: 100%;
box-sizing: content-box;
}
.ticker-wrap .ticker {
display: inline-block;
height: 2rem;
line-height: 2rem;
white-space: nowrap;
padding-right: 100%;
box-sizing: content-box;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-name: ticker;
animation-name: ticker;
-webkit-animation-duration: 30s;
animation-duration: 30s;
}
.ticker-wrap .ticker__item {
display: inline-block;
padding: 0 1rem;
font-size: 1rem;
color: white;
}
<div class="ticker-wrap">
<div class="ticker">
<div class="ticker__item">Hi Lea!</div>
<div class="ticker__item">Look at them !!!</div>
<div class="ticker__item">Owww new items...</div>
<div class="ticker__item">
offers | save up to 50% — shop now
</div>
</div>
</div>
I'm trying to get the Top and Right values from an element being rotated by a CSS animation, for this I am using the following code:
HTML:
<div id="ball1"> </div>
CSS:
#keyframes spin {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
#ball1 {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10;
height: 10;
border-radius: 10px;
}
Javascript:
console.log(window.getComputedStyle(document.getElementById("ball1"), null).top);
console.log(window.getComputedStyle(document.getElementById("ball1"), null).right);
However it returns a value of 0px, I wanted to get the value from Right and Top as if I was manually setting them (and not by the transform animation).
If this is not possible, is there a way to simulate a "circle" rotation and return the right/top values without using the transform?
ie:
https://66.media.tumblr.com/fb22b61bcbca3785a515e86c2276451b/tumblr_inline_pmimnjEvbK1v6q8wn_1280.gif?fbclid=IwAR2zjgE0hfB8emWOg0f6TOcQb8DWGbEvu9IQOr92fMq4HmMKjiAQRQzLmI0
Use getBoundingClientRect():
const ball = document.getElementById("ball");
setInterval(() => {
const rect = ball.getBoundingClientRect();
console.log(rect.top, rect.right);
}, 300);
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#ball {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
<div id="ball"></div>
Here is an approximation using top/left. The trick is to animate each property individually alternating the ease function to simulate the circular path:
.box {
width:100px;
height:100px;
position:relative;
}
#ball1 {
animation:
Atop 2.5s infinite,
Aleft 2.5s infinite;
position: absolute;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
#keyframes Atop {
0%,50%,100% {
top:50%;
animation-timing-function: ease-out;
}
25% {
top:0%;
animation-timing-function: ease-in;
}
75% {
top:100%;
animation-timing-function: ease-in;
}
}
#keyframes Aleft {
0%,100% {
left:0;
animation-timing-function: ease-in;
}
25%,75% {
left:50%;
animation-timing-function: ease-out;
}
50% {
left:100%;
animation-timing-function: ease-in;
}
}
<div class="box">
<div id="ball1"> </div>
</div>
How Can I fix the below code.. I have used the technique of transform:translateY(-50%) to make a div vertically center. But When I use it with animation , it first takes top:50% then it translates giving a jerk.. I don't want the jerk to happen and the element should automatically come in center.
body,
html {
height: 100%;
background: #c9edff;
text-align: center;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
font-family: arial;
font-size: 20px;
line-height: 1.8em;
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0);
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="element">
Vertical Align is Awesome!
<br /> But with animation its giving a jerk!<br/> Please Fix
</div>
Your animation rule overwrites the translateY(-50%) with scale(), and when the animation is done, the previous rule gets applied again, hence it jumps.
If you add translateY(-50%) to the animation, it will work fine.
A side note, based on whether one put the translateY() before or after the scale(), it animates differently, as transform values gets applied from right to left
body,
html {
height: 100%;
background: #c9edff;
text-align: center;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
font-family: arial;
font-size: 20px;
line-height: 1.8em;
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: translateY(-50%) scale(0);
}
to {
-webkit-transform: translateY(-50%) scale(1);
}
}
#keyframes zoom {
from {
transform: translateY(-50%) scale(0);
}
to {
transform: translateY(-50%) scale(1);
}
}
<div class="element">
Vertical Align is Awesome!
<br /> But with animation its giving a jerk!<br/> Please Fix
</div>
The problem here ist the line-height, but you can actually use calc to fix that.
transform: translateY(calc(- 50% + 1.8em));
body,
html {
height: 100%;
background: #c9edff;
text-align: center;
}
.element {
position: relative;
top: 50%;
transform: translateY(calc(- 50% + 1.8em));
font-family: arial;
font-size: 20px;
line-height: 1.8em;
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0);
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="element">
Vertical Align is Awesome!
<br /> But with animation its giving a jerk!<br/> Please Fix
</div>
I was wondering if it is possible to assign a group of stacking texts in the middle of the page? placing them in the center wasn't too difficult, but the problem was that they are positioned left, right, top, and bottom, which I think means they need to be given: position:absolute. Furthermore, the .headline texts are given fade-in(opacity 0 to 100) and animation commands. In terms of scaling, the texts are responsive, and get smaller as the window gets smaller. In addition they are assigned their own z-index.
In the image below, I have laid out the overall structure I would like to achieve, but I'm experiencing a lot of difficulty doing so because of the text behaviors I want to accomplish.
For functionality reference, here is a jsfiddle.
Please help me and thank you in advance! Please note that I would prefer to use CSS only since it's a simple function that only occurs once upon page load. However, if this is a issue that only javascript can solve, please let me know :)
.animated {
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: 0.5s;
-moz-animation-duration: 0.5s;
-ms-animation-duration: 0.5s;
-o-animation-duration: 0.5s;
animation-duration: 0.5s;
}
.fade {
-webkit-animation-name: fade;
-moz-animation-name: fade;
-o-animation-name: fade;
animation-name: fade;
}
#-webkit-keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-moz-keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-o-keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-webkit-keyframes flowright {
0% {
opacity: 0;
left: -100px;
}
100% {
opacity: 1;
left: 0;
}
}
#keyframes flowright {
0% {
opacity: 0;
left: -100px;
}
100% {
opacity: 1;
left: 0;
}
}
#-webkit-keyframes flowleft {
0% {
opacity: 0;
right: -100px;
}
100% {
opacity: 1;
right: 0;
}
}
#keyframes flowleft {
0% {
opacity: 0;
right: -100px;
}
100% {
opacity: 1;
right: 0;
}
}
#-webkit-keyframes flowup {
0% {
opacity: 0;
margin-top: 100px;
}
100% {
opacity: 1;
margin-top: 0;
}
}
#keyframes flowup {
0% {
opacity: 0;
margin-top: 100px;
}
100% {
opacity: 1;
margin-top: 0;
}
}
#-webkit-keyframes flowdown {
0% {
opacity: 0;
margin-top: -100px;
}
100% {
opacity: 1;
margin-top: 0;
}
}
#keyframes flowdown {
0% {
opacity: 0;
margin-top: -100px;
}
100% {
opacity: 1;
margin-top: 0;
}
}
.flow {
display: inline-block;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: cubic-bezier(0.165, 0.840, 0.440, 1.000);
-webkit-animation-direction: alternate;
-webkit-animation-fill-mode: both;
animation-duration: 1s;
animation-timing-function: cubic-bezier(0.165, 0.840, 0.440, 1.000);
}
.right {
-webkit-animation-name: flowright;
animation-name: flowright;
}
.left {
-webkit-animation-name: flowleft;
animation-name: flowleft;
}
.up {
-webkit-animation-name: flowup;
animation-name: flowup;
}
.down {
-webkit-animation-name: flowdown;
animation-name: flowdown;
}
.sequence01 {
-webkit-animation-delay: 0.1s;
}
.sequence02 {
-webkit-animation-delay: 0.2s;
}
.sequence03 {
-webkit-animation-delay: 0.3s;
}
.sequence04 {
-webkit-animation-delay: 0.4s;
}
/* Headline Typography */
.headline {
font-family: helvetica;
font-weight: bold;
font-size: 4em;
}
/* Rows */
.row01, .row02, .row03 {
clear: both;
}
.row01 {
left:20%;
top: 0;
position: relative;
}
.row02 {
right:10%;
top: 50%;
position: relative;
}
.row03 {
left:10%;
top: 100%;
position: relative;
}
/* General Structure */
body {
width: 100%;
height: 100%;
}
.pagewrap {
height: 100%;
width: 80%;
max-width: 48em;
margin: 0 auto;
background-color: #fff6d6;
}
<body>
<div class="pagewrap">
<div class="headline">
<div class="row01 flow left sequence01">ROW 01</div>
<br/>
<div class="row02 flow right sequence02">ROW 02</div>
<br/>
<div class="row03 flow up sequence03">ROW 03</div>
</div>
</div>
</body>
The solution given by adeneo in the comments may work perfectly fine, but since your layout is strictly vertical, why not just use a block layout instead of inline-block or floats?
fiddle here.
You mention a "padding" percentage between the rows as well. Note that margin and padding css attributes as percentages will key off of the width not the height. I placed divs to solve that, but there are other solutions.
Edit
If the headline needs to be vertically centered to the page, here's a nifty way to do it using the "ghost element technique":
/* Headline Typography */
.wrapper {
position: relative;
height: 100%;
width: 100%;
text-align: center;
}
/* The ghost, nudged to maintain perfect centering */
.wrapper:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
.headline {
display: inline-block;
width: 100%;
vertical-align: middle;
font-family: helvetica;
font-weight: bold;
font-size: 4em;
}
fiddle
I learned of it here.