How to animate a dropdown menu using CSS3 animations? - css

I would like to add a CSS3 effect to my dropdown. (Just like that one in Instagram.com on "My profile").
I'm using Animate.css for the CSS3 effects.
I tried this, but it doesn't work.
HTML
<%=fa_icon "bell"%>
<ul id="dropdownalerts" class="f-dropdown text-left animated bounceInDown" data-dropdown-content>
<li><%=link_to "Facebook", "#"%></li>
<li><%=link_to "Email", "#" %></li>
</ul>
JS
$(document).ready(function(){
$('a').hover(function(){
$("ul").addClass('animated bounceInDown');
});
});
You can find a live version on Zapping.io

I got it working in an example. I used the HTML you provided, and then downloaded the bounceInDown animation and used that for the CSS in the examples below.
jsFiddle example here - hover method
jQuery
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){
$("ul").removeClass('animated bounceInDown');
});
});
If you want to add a delay when hovering off, use something like this:
jsFiddle example - hover method with delay.
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){setTimeout(function(){
$("ul").removeClass('animated bounceInDown');
}, 750);});
});
Those examples are assuming you want the animation fired on hover. If you want it fired on click, use something like this instead:
jsFiddle example click method - Look below for an alternative non-JS method.
$(document).ready(function(){
$('a').click(function() {
$("ul").toggleClass('animated bounceInDown');
});
});
Alternative method - No JS/jQuery
If you don't want to use JavaScript/jQuery, you can use the checkbox hack in CSS.
This essentially toggles between :checked, thus activating the animation.
jsFiddle example - It works in all current browsers.
HTML
<label id="click" for="dropdown">Click here</label>
<input style="display:none" type="checkbox" id="dropdown">
<ul id="dropdownalerts" class="f-dropdown text-left" data-dropdown-content>
<li>Facebook</li>
<li>Email</li>
</ul>
CSS - (only part of it) See the example above for full CSS.
input[type=checkbox]:checked ~ #dropdownalerts {
display:inline-block;
-webkit-animation: bounceInDown 1s both;
-moz-animation: bounceInDown 1s both;
-o-animation: bounceInDown 1s both;
animation: bounceInDown 1s both;
}

Related

Adding sliding transition to ng-repeat div

Our team has created a widget in ServiceNow that shows a row of icons and show/hide additional details in a div when icons are clicked. This is what our html and client controller looks like:
<div class="icons">
<ul class="flex justify-content-center align-items-center">
<li ng-repeat="item in c.data.linksArray track by $index">
<a class="link" href="javascript:void(0)" ng-click="c.getInfo(item)">
<i title="{{item.titles}}" class='fa {{item.icon}} fa-3x circle-icon'></i>
</a>
</li>
</ul>
</div>
<div class="linkList text-center"
ng-repeat="thing in c.data.linksArray track by $index"
ng-if="thing.isVisible==true">
<ul>
<li class="m-b-sm" ng-repeat="link in thing.links">
{{link.link_title}}
</li>
</ul>
</div>
function($scope) {
/* widget controller */
var c = this;
c.getInfo = function(item) {
var isDisplaying = false;
if(item.isVisible== true){
isDisplaying = true;
}
for(var i=0; i<c.data.linksArray.length; i++){
c.data.linksArray[i].isVisible = false;
}
if(isDisplaying == true){
item.isVisible = false;
}else{
item.isVisible=!item.isVisible;
}
}
console.log('icon-link-list');
console.log($scope);
}
This all works fine, but we'd like to refine it by adding a sliding effect to the .linkList class. Right now, when an icon is clicked, the .linkList div appears very abruptly. Is there a way to add a sliding transition effect to that div using css?
You can solve this by pure css animations. Aplly this css to the item which will we hidden/shown. The animation will play anytime css attribute 'display' will change. I guess it's the linkList element?
.linkList {
animation: slideFromLeft .2s;
animation-timing-function: ease;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes slideFromLeft{
0% {
opacity: 0;
transform: translateX(50px);
}
100% {
opacity: 1;
transform: none;
}
}
Edit: you maybe have to change ng-if on linkList to ng-show.
From the Docs:
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to an HTML element within your application, you can apply animations to it.
As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add an ng-enter class to the element that is being added. When removed it will apply an ng-leave class and when moved around it will apply an ng-move class.
For more information, see
AngularJS Developer Guide - Animations

display transition (multiple transition) [duplicate]

This question already has answers here:
Transitions on the CSS display property
(37 answers)
Closed 4 years ago.
I have following code:
HTML:
<div id="container">
text text text
</div>
<img id="img1" src="img1.png" />
<img id="img2" src="img2.png" />
CSS:
#container {
display: block;
margin-top: 0vh;
transition: margin-top 1s ease-in 0.1s, display 0.1s linear 5s ;
}
JS:
$("img#img1").on('click', function () {
$("#container").css('margin-top', '50vh');
$("#container").css('display', 'none');
});
$("img#img2").on('click', function () {
$("#container").css('margin-top', '0vh');
$("#container").css('display', 'block');
});
Looking on CSS file, my intention is:
margin-top property, change after 0.1 second, for 1 second
display property, change after 5 second, for 0.1s
But it doesn't work. The display property is changed immediately after click on image.
How to fix it?
To add a delay in JavaScript, you can use the setTimeout function.
To add a five-second delay in your code, you would do the following:
$("img#img1").on('click', function () {
$("#container").css('margin-top', '50vh');
setTimeout(function() {
$("#container").css('display', 'none');
}, 5000);
});
$("img#img2").on('click', function () {
$("#container").css('margin-top', '0vh');
setTimeout(function() {
$("#container").css('display', 'block');
}, 5000);
});
The 5000 in this code is 5 seconds represented in millseconds. Hopefully the rest is self-explanatory - a function is specified which is executed after the set length of time.
Not quite sure what you mean about changing display for 0.1s though. An element is either displayed or it isn't - there is no in-between. If want something to fade, change its opacity instead. You probably ought to remove ", display 0.1s linear 5s" from your CSS too.

How to use ng-animate to add slide effect on menu

I am trying to implement a slide effect using ng-animate and CSS styles, but can't figure out what's wrong with my code...
Can I do this using values in percentages for min-height and max-height? I cant use fixed values in px.
JSFIDDLE
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
Click to toggle menu
<div class="menu" ng-show="collapsed" ng-animate="{show: 'menu-show', hide: 'menu-hide'}">
<div class="files">
<input type="checkbox" />
<label>first</label>
<input type="checkbox" />
<label>second</label>
</div>
<div class="diffs">
<input type="checkbox" />
<label>first</label>
<input type="checkbox" />
<label>second</label>
</div>
</div>
</div>
CSS:
.menu-show-setup, .menu-hide-setup {
transition:all 0.5s ease-out;
overflow:hidden
}
.menu-show-setup {
max-height:0;
}
.menu-show-setup.menu-show-start {
max-height:25%;
}
.menu-hide-setup {
max-height:25%;
}
.menu-hide-setup.menu-hide-start {
max-height:0;
}
First ensure you have angular and angular-animate loaded.
The CDN for angular-animate is ...
<script src="//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-animate.js"></script>
Then you need to reference the animations that ngAnimate gives ...
https://docs.angularjs.org/api/ngAnimate
For example, ng-if when switched from false to true will add the class .fade AND .ng-enter to the element on which the ng-if is located. These classes will be automatically removed after a short time. ngAnimate does this for you.
What you HAVE to do is to style what these classes do ...
example:
.fade.ng-enter {
transition:0.5s linear all;
opacity:0;
}
/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
opacity:1;
}
now ng-animate will animate from .fade.ng-enter to .fade.ng-enter.ng-enter-active
if you do not define these styles ng-animate will do nothing.
You will see classes being added and remove by ng-animate if you inspect the relevant element in your browser's develop tools. If you cannot see these classes being added and removed then something is wrong with your loading of angular or ng-animate.

Angular ng-repeat animate once

I am using ngAnimate to animate entries in an ng-repeat. When loading the data all elements are animated as I have defined in my css:
.chat-message.notice.ng-enter {
-webkit-animation: rubberBand 1s;
-moz-animation: rubberBand 1s;
-ms-animation: rubberBand 1s;
animation: rubberBand 1s;
}
This works when a notice is appended with the following html:
<ul>
<li class="media chat-message pointer fade-animate"
ng-repeat-start="message in guestbook.messages track by $index"
ng-if="!message.bot">
<!-- more html -->
</li>
<li class="chat-message notice" ng-repeat-end ng-if="message.bot">
<div>
<p class="text-center">
{{ message.message }}
<small>({{ message.date | amTimeAgo }})</small>
<span class="close pull-right" ng-click="guestbook.remove(message)">×</span>
</p>
</div>
</li>
</ul>
However, when a new message is appended (at the top), every element is again animated. Is there a way that elements animate only once? That when a new message is appended to the array, only that element will animate?
JSFIDDLE
EDIT
After a few clicks on a 'new message', I can see not all notices are animated. Maybe it has something to do with the ng-repeat-start and ng-repeat-end?
If understood correctly just change this:
$scope.messages.unshift(message);
to this:
$scope.messages.push(message);
Even above answer fixed the problem, my solution might be helpful in other scenarios. The fix is pretty straightforward.
Use Angular varible $first and just add CSS class for the first element using ng-class directive in your HTML. In this example, class "first" will be added only to first element in ng-repeat:
ng-class="{'first': $first===true}"
and then apply animation rules to element with "first" CSS class
.chat-message.notice.first.ng-enter {
color:red !important;
font-weight:bold;
animation: rubberBand 1s;
}
Updated JSFIDDLE: http://jsfiddle.net/t6x3a1zj/7/

How do I make my text disappear when I hover over my div?

This is the only thing in the body of the HTML:
<div id="box">
<p id="text"> Enter The Disco! </p>
</div>
and this is my CSS relating to the problem:
#box:hover{
-webkit-transform:rotate(360deg);
opacity:1;
background-image:url("Logo.jpg");
width:428px;
height:208px;
font-size:38px;
}
#text:hover{
padding:18% 0% 0% 0%;
color:red;
}
And what I want to do is make the text inside the div disappear when I hover over it how do I do this? It already spins and changes background but i just want the text to disappear after it has finished its animation.
You could use the color CSS attribute and instead of making it invisible, just make it transparent, which should have the same effect:
#text:hover {
/* other rules */
color: transparent;
}
you can use different way too. It is easy too like another solutions:
#text:hover {
display:none;
}
It's no problem to let it disappear: use display:none, opacity:0, visibility:hidden or color:transparent; but hiding it AFTER the animation? This seems to be a bit more difficult. I don't think that this is possible without javascript:
<div id="box" onmouseover="spin();">
<p id="text"> Enter The Disco! </p>
</div>
<script type="text/javascript">
var i; var rotate;
function spin() {
i = 180; rotate = setInterval("spinInterval()",3);
}
function spinInterval() {
document.getElementById('box').style.WebkitTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.MozTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.OTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.Transform = "rotate("+ i +"deg)";
i++;
if(i>360) {
document.getElementById("text").style.opacity = 0;
clearInterval(rotate);
}
}
</script>
PS: this works for all browsers, not only on Chrome :)

Resources