i am trying to make a collapsible content, but the css won't accept the "max-content" property in animation. i get the error: "Invalid value: max-content" for the height of the content.
when i set the the height without #keyframes it works, but i want it to be animated
.full {
animation-name: fullText;
animation-duration: 0.2s;
animation-fill-mode: forwards;
}
.short{
animation-name: shortText;
animation-duration: 0.2s;
animation-fill-mode: forwards;
}
#keyframes fullText {
from { height: 150; }
to { height: max-content; }
}
#keyframes shortText {
from { height: max-content; }
to { height: 150; }
}
Make sure your browser support max-content
https://caniuse.com/#search=max-content
Related
I am new to css and javascript. I am trying to animate the spans within an h2 to fall from the top of the page on load and then on hover to have a bouncy effect. I was able to make them happen both BUT now the problem is that the animation delay I intended for the fall animation are applying to the bounce animation as well. When I add the animation name to the animation delay all the letter fall at the same time. What am I missing?
I tried specifying the animation name for the animation delay but it didn't work. When I add the animation name to the animation delay all the letter fall at the same time. What am I missing?. And I also tried to change the animation delay in JS after the first animation happens but wasn't able to figure out.
This is my html
<h2 class="test">
<span class="q">T</span><span class="q">a</span><span class="q">d</span><span
class="q">a</span><span class="q">a</span><span class="q">k</span><span class="q">i</span>
</h2>
<h2 class="test2">
<span class="q2">K</span><span class="q2">u</span><span class="q2">w</span><span
class="q2">a</span><span class="q2">y</span><span class="q2">a</span><span
class="q2">m</span><span class="q2">a</span>
</h2>
This is the CSS
span {
color: black;
font-size: 1em;
display: flex;
margin-bottom: 0;
padding-bottom: 0;
}
.onLoadAnimation {
position: relative;
transform: translateY(-100vh);
animation: fall 1s forwards;
animation-iteration-count: 1;
}
#keyframes fall {
100% {
transform: translateY(0);
}
}
.test span:nth-child(2) {
animation-delay: 0.1s;
}
.test span:nth-child(3) {
animation-delay: 0.2s;
}
.test span:nth-child(4) {
animation-delay: 0.3s;
}
.test span:nth-child(5) {
animation-delay: 0.4s;
}
.test span:nth-child(6) {
animation-delay: 0.5s;
}
.test span:nth-child(7) {
animation-delay: 0.6s;
}
.test2 span:nth-child(1) {
animation-delay: 0.1s;
}
.test2 span:nth-child(2) {
animation-delay: 0.12s;
}
.test2 span:nth-child(3) {
animation-delay: 0.3s;
}
.test2 span:nth-child(4) {
animation-delay: 0.4s;
}
.test2 span:nth-child(5) {
animation-delay: 0.5s;
}
.test2 span:nth-child(6) {
animation-delay: 0.6s;
}
.test2 span:nth-child(7) {
animation-delay: 0.7s;
}
.test2 span:nth-child(8) {
animation-delay: 0.8s;
}
.spanHoverEffect {
color: #0f4c5c;
animation: animate 0.6s;
}
#keyframes animate {
25% {
transform: scale(0.8, 1.3);
}
50% {
transform: scale(1.1, 0.8);
}
75% {
transform: scale(1.1, 0.8);
}
}
This is the JS
let letters = document.getElementsByClassName("q");
let lettersTwo = document.getElementsByClassName("q2");
window.onload = () => {
for (l of letters) {
l.classList.toggle('onLoadAnimation');
l.addEventListener('mouseover', function () {
this.classList
.remove('onLoadAnimation')
.add('spanHoverEffect')
});
l.addEventListener('mouseout', function () {
this.classList
.remove('onLoadAnimation')
.remove('spanHoverEffect')
});
}
for (l of lettersTwo) {
l.classList.toggle('onLoadAnimation');
l.addEventListener('mouseover', function () {
this.classList
.remove('onLoadAnimation')
.add('spanHoverEffect')
});
l.addEventListener('mouseout', function () {
this.classList
.remove('onLoadAnimation')
.remove('spanHoverEffect')
});
}
};
In this fiddle, I made two changes. The letters fall in sequence in Chrome, Firefox and Edge and the animation delay is not present when moused over in any of those browsers.
I added the onLoadAnimation class to the CSS for each letter.
.test .onLoadAnimation:nth-child(2) {
animation-delay: 0.1s;
}
And I removed the chained changes to classList, which is not something that classList supports in any of the browsers mentioned above.
l.classList.remove('onLoadAnimation')
l.classList.add('spanHoverEffect')
The reason I mention web browsers is that "this.classList.remove('onLoadAnimation').add('spanHoverEffect')" causes an error in all of those browsers, because remove returns undefined, so I am wondering if you are using a less-used browser that may work differently.
I have the following Gauge component:
The component is also rendering here: https://codesandbox.io/s/react-example-e3nxg
The component takes the prop rating as a number.
What I'd love to learn how to do is animate the path's opacity values. For example, if the prop for rating is passed a value of 5... How to make it so the component animates in each path, one at a time on a set time-delay between each path.
Any ideas on how this could be done?
Please checkout the sandbox url
Sandbox link
I made a little change in the css
#gauge {
fill: red;
}
.Animate-Draw {
fill-opacity: 0;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
animation-name: FillIn;
animation-duration: 4s 0.5s;
/* animation-delay: .5s; */
}
.Animate-Draw:nth-child(1) {
animation-delay: 0.5s;
}
.Animate-Draw:nth-child(2) {
animation-delay: 1s;
}
.Animate-Draw:nth-child(3) {
animation-delay: 1.5s;
}
.Animate-Draw:nth-child(4) {
animation-delay: 2s;
}
.Animate-Draw:nth-child(5) {
animation-delay: 2.5s;
}
.Animate-Draw:nth-child(6) {
animation-delay: 3s;
}
.Animate-Draw:nth-child(7) {
animation-delay: 3.5s;
}
.Animate-Draw:nth-child(8) {
animation-delay: 4s;
}
#keyframes FillIn {
from {
fill-opacity: 0;
}
to {
fill-opacity: 1;
}
}
I hope this is what you are looking for.
I'm trying to slide in a div and slide out another from left to right.
<div class="moveleft" ng-switch="article">
<div ng-switch-when="1">
...hi...
</div>
<div ng-switch-when="2">
...bye...
</div>
</div>
I want to do this sliding on a button click:
<button ng-click="changeori()">Hi</button>
In my AngularJS file:
$scope.article = 1;
$scope.changeori = function() {
$scope.article = $scope.article == 1 ? 2 : 1;
}
And for my moveleft class:
.moveleft, .moveright {
transition: 2000ms cubic-bezier(0.420, 0.000, 0.580, 1.000) all;
}
.moveleft.ng-enter {
left: 100%;
}
.moveleft.ng-enter-active {
left: 0;
}
.moveleft.ng-leave {
left: 0;
}
.moveleft.ng-leave-active {
left: -100%;
}
Problem: On clicking the button, the first div hides after 2 seconds and the second div comes on the click as expected, but the animations for slide are not happening.
You are probably using the ng-animate wrong.
See this working demo
2 items(div) respond through animation css as below
.item {
position: absolute;
top: 35px;
bottom: 0;
right: 0;
left: 0;
animation-duration: 0.30s;
animation-timing-function: ease-in-out;
-webkit-animation-duration: 0.30s;
-webkit-animation-timing-function: ease-in-out;
}
.item.ng-enter {
animation-name: slideFromRight;
-webkit-animation-name: slideFromRight;
}
.item.moveToLeft.ng-enter {
animation-name: slideFromLeft;
-webkit-animation-name: slideFromLeft;
}
.item.ng-leave {
animation-name: slideFromLeft;
animation-direction: reverse;
-webkit-animation-name: slideFromLeft;
-webkit-animation-direction: reverse;
}
.item.moveToLeft.ng-leave {
animation-name: slideFromRight;
animation-direction: reverse;
-webkit-animation-name: slideFromRight;
-webkit-animation-direction: reverse;
}
So I have got different animations made in CSS, though the problem is that they start right away when the page loads (ofcourse). I do not want this though. Is there a way in Vanilla JavaScript to get the animation to fire up only when it is in the viewport?
I have searched in a lot of places, but I either find a plugin I need to use or jQuery.
HTML:
<div class="introduction">
<h1>I can do the following for you:</h1>
<ul>
<li>Create a custommade, new website.</li>
<li>Code a PSD template into a working website.</li>
<li>Rework an outdated website.</li>
<li>Clean up messy code of a website.</li>
</ul>
</div>
CSS:
#keyframes showOnLoad {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.introduction li {
list-style-type: none;
margin-bottom: 5px;
text-align: center;
opacity: 0;
-webkit-animation: showOnLoad;
animation: showOnLoad;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.introduction li:nth-child(2) {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.introduction li:nth-child(3) {
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.introduction li:nth-child(4) {
-webkit-animation-delay: 3s;
animation-delay: 3s;
}
This is the code you need.
window.addEventListener("scroll", onScroll);
function onScroll() {
for (var item of document.querySelectorAll(".introduction li")) {
elementVisible(item);
}
}
function elementVisible(el) {
let top = el.offsetTop;
let height = el.offsetHeight;
let bottom = top + height;
let IsOverBottom = top > (window.pageYOffset + window.innerHeight);
let IsBeforeTop = bottom < window.pageYOffset;
if (!IsOverBottom && !IsBeforeTop) {
el.classList.add("show");
}
}
And a bit of CSS
#keyframes slideIn {
0% {
opacity: 0;
transform: translateX(100%);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
.show {
animation: slideIn 5s ease-in-out;
}
This is a basic implementation but it gets you closer.
http://jsbin.com/hetapaj/1/edit?css,js,output
I have some keyframe animations in my css file. There is already an animation-delay specified.
The wrapper div has the attribute data-delay.
I want to get the animation-delay in the css file and add the value of data-delay to it.
Then i want that the animation start with the new delay.
I tried ele[i].style.animationDelay.
But it seems that this returns null until I set a value to it.
If I set ele[i].style.animationDelay = '5s' the animation still runs with the delay of the css file.
HTML
<div id="wrapper" data-delay="2s" >
<h1 id="hi">Hi</h1>
<h1 id="name">test!</h1>
</div>
CSS
body { font-size: 300%; }
#wrapper h1 { position: absolute; }
#hi {
transform: translate(-200px, 100px);
animation-name: hi;
animation-duration: .5s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 0s;
}
#name {
transform: translate(-200px, 150px);
animation-name: name;
animation-duration: .5s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
#keyframes hi{
100% { transform: translate(50px, 100px) };
}
#keyframes name{
100% { transform: translate(50px, 150px) };
}
JS
var wrapper = document.getElementById('wrapper');
var ele = wrapper.children;
var delay = wrapper.getAttribute('data-delay');
for (var i=0;i<ele.length;i++) {
alert(ele[i].style.animationDelay);
ele[i].style.animationDelay = delay;
alert(ele[i].style.animationDelay);
}
http://jsfiddle.net/FHuKN/4/
I've only tested this on Mac 10.8 Chrome 25, Safari 6.0, and FF 18.0.
Sounds like the main thing you wanted to do was add the data-delay value to whatever existing animation delay was applied to the elements.
HTML - unchanged
<div id="wrapper" data-delay="5.1s" >
<h1 id="hi">Hi</h1>
<h1 id="name">test!</h1>
</div>
CSS - Vendor prefixes and initial keyframes (0%) were added.
body { font-size: 300%; }
#wrapper h1 { position: absolute; }
#hi {
-webkit-transform: translate(-200px, 100px);
-webkit-animation-name: hi;
-webkit-animation-duration: .5s;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
-webkit-animation-delay: 2.1s;
-moz-transform: translate(-200px, 100px);
-moz-animation-name: hi;
-moz-animation-duration: .5s;
-moz-animation-timing-function: linear;
-moz-animation-fill-mode: forwards;
-moz-animation-delay: 2.1s;
transform: translate(-200px, 100px);
animation-name: hi;
animation-duration: .5s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 2.1s;
}
#name {
-webkit-transform: translate(-200px, 150px);
-webkit-animation-name: name;
-webkit-animation-duration: .5s;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
-webkit-animation-delay: 3.1s;
-moz-transform: translate(-200px, 150px);
-moz-animation-name: name;
-moz-animation-duration: .5s;
-moz-animation-timing-function: linear;
-moz-animation-fill-mode: forwards;
-moz-animation-delay: 3.1s;
transform: translate(-200px, 150px);
animation-name: name;
animation-duration: .5s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 3.1s;
}
#-moz-keyframes hi{
0% { -moz-transform: translate(-200px, 100px); }
100% { -moz-transform: translate(50px, 100px); }
}
#-webkit-keyframes hi {
0% { -webkit-transform: translate(-200px, 100px); }
100% { -webkit-transform: translate(50px, 100px); }
}
#keyframes hi{
0% { transform: translate(-200px, 100px); }
100% { transform: translate(50px, 100px); }
}
#-moz-keyframes name {
0% { -moz-transform: translate(-200px, 150px); }
100% { -moz-transform: translate(50px, 150px); }
}
#-webkit-keyframes name {
0% { -webkit-transform: translate(-200px, 150px); }
100% { -webkit-transform: translate(50px, 150px); }
}
#keyframes name {
0% { transform: translate(-200px, 150px); }
100% { transform: translate(50px, 150px); }
}
JAVASCRIPT
On an element, the style property doesn't hold all the style information because it only represents what is being set directly on the element via the style attribute. MDN
window.getComputedStyle() seems to work pretty well.
Juggling the prefixed properties is a little clunky, but it worked in the browsers I tested with.
(function(undefined) {
var wrapper = document.getElementById('wrapper'),
elms = wrapper.children,
delay = wrapper.getAttribute('data-delay'),
prop,
styl,
cur,
i;
delay = !delay ? 0 : Number(delay.replace(/[^\d\.]/g, ''));
if (!elms.length) {
return;
}
styl = window.getComputedStyle(elms[0]);
if (styl.getPropertyValue('animation-delay')) {
prop = 'animation-delay';
} else if (styl.getPropertyValue('-webkit-animation-delay')) {
prop = '-webkit-animation-delay';
} else if (styl.getPropertyValue('-moz-animation-delay')) {
prop = '-moz-animation-delay';
} else {
console.log('unable to find prop');
return;
}
// console.log('prop', prop);
for (i = 0; i < elms.length; i++) {
styl = window.getComputedStyle(elms[i]);
cur = styl.getPropertyValue(prop);
cur = Number(cur.replace(/[^\d\.]/g, ''));
elms[i].style.setProperty(prop, (cur + delay) + 's');
console.log('delay: ' + cur + 's -> ' + (cur + delay) + 's')
}
})();
http://jsfiddle.net/FHuKN/11/
Old Firefoxes (at least up to 16), Opera before migrating to Blink (<15), IE at least 10 - will not redraw the animation if we just change some of its attributes like (-prefix-)animation-delay. In order to make them do so, we have to apply some depper tricks.
The first will be removing and reinserting the animated element. And - for the sake of Webkit - applying all the style changes on it.
Just change the code from #tiffon's fiddle
elms[i].style.setProperty(prop, (cur + delay) + 's');
To
var newEl = elms[i].cloneNode(true);
newEl.style.setProperty(prop, (cur + delay) + 's', '');
elms[i].parentNode.replaceChild(newEl,elms[i]);
http://jsfiddle.net/FHuKN/28/
Remove the class name ar the attribute value, which the animation is attached to, wait for a bit (setTimeout) of - better - trigger the reflow (say, element.offsetWidth = element.offsetWidth;), and add the class name again.
http://jsfiddle.net/FHuKN/29/
The idea is not mine, all credit goes to Chris Coyer