I have a function that loads html into a table with jQuery and subsequently adds a class to one of the rows with the callback. The function is triggered by various UI driven events on the page. I also have a css transition rule so the color should fade in (transition: background-color 1000ms linear). The function looks like this:
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
$(row_id).addClass('green');
});
}
Once the html is loaded, the class successfully gets added and row color is set to green. However, my css transition rule seems to be ignored.
When I add a slight delay, even 10ms, it works fine:
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
setTimeout(function() {
$(row_id).addClass('green');
}, 10);
});
}
The jQuery docs for .load() state:
If a "complete" callback is provided, it is executed after
post-processing and HTML insertion has been performed.
To me this would indicate the new elements have been loaded into the dom with existing styles applied and are ready for manipulation. Why does the transition fail in the first example but succeed in the second?
Here is a fully functional example page to demonstrate the behaviour in question:
http://so-37035335.dev.zuma-design.com/
While the example above links jQuery version 2.2.3 from cdn, actual page in question uses version 1.7.1. The same behavior can be observed across both versions.
UPDATE:
After considering some of the comments and answers offered below, I've stumbled upon something altogether more confusing. User #gdyrrahitis made a suggestion which lead me to do this:
function tbody_fade(row_id) {
$('tbody').load("load_tbody.php", function() {
$('tbody').fadeIn(0, function() {
$(this).find(row_id).addClass('green');
});
});
}
Adding the class inside the fadeIn() callback works, even with a duration of 0ms. So this had me wondering... if the element is theoretically there anyway, what background color does the browser think it has before I add that class. So I log the background-color:
console.log($(row_id).css('background-color'));
And do you know what? Simply getting the background-color color made everything work:
function tbody_get_style(row_id) {
$('tbody').load("load_tbody.php", function() {
$(row_id).css('background-color');
$(row_id).addClass('green');
});
}
Just adding the line $(row_id).css('background-color'); which seemingly does nothing at all causes the transition effect to work. Here's a demo:
http://so-37035335-b.dev.zuma-design.com/
I'm just dumbfounded by this. Why does this work? Is it merely adding a small delay or does jQuery getting the css property somehow have a substantial effect on the state of the newly added element?
jQuery load is intended to drop everything that is requested into the page.
You can leverage the power of jQuery Deferred objects by using $.get instead.
Take a look at this plunk.
Code snippet from plunk
function load_tbody(row_id) {
$.when($.get("load_tbody.html", function(response) {
$('tbody').hide().html(response).fadeIn(100, function() {
$(this).find(row_id).addClass('green');
});
}));
}
I am using the $.when which will run its callback as soon the $.get is resolved, meaning will fetch the HTML response. After the response is fetched, it is appended to the tbody, which is fadedIn (fadeIn method) and after it is shown, the .green class is added to the desired row.
Note that if you go and just append the html and then the class to the row_id, you won't be able to see the transition, because it is executed immediately. A little nice visual trick with the fadeIn can do the work.
Update
On newly added elements to the DOM, CSS3 transition is not going to be triggered. This mainly happens because of the internal browser engine that controls all animations. There are numerous articles with workarounds on the issue, as well as stackoverflow answers. Additional resources can be found there, which I believe can explain the topic much better than me.
This answer is about taking a step back and changing the piece of functionality that renders dynamic elements in DOM, without going to use setTimeout or requestAnimationFrame. This is just another way to achieve what you want to achieve, in clear and consistent way, as jQuery works across browsers. The fadeIn(100, ... is what is needed to catch up with the next available frame the browser is about to render. It could be much less, the value is just to satisfy visual aesthetics.
Another workaround is to not use transitions at all and use animation instead. But from my tests this fails in IE Edge, works well on Chrome, Firefox.
Please look at the following resources:
https://www.christianheilmann.com/2015/08/30/quicky-fading-in-a-newly-created-element-using-css/
Update 2
Take a look at the specification please, as interesting stuff lies there regarding CSS3 transitions.
...This processing of a set of simultaneous style changes is called a style change event. (Implementations typically have a style change event to correspond with their desired screen refresh rate, and when up-to-date computed style or layout information is needed for a script API that depends on it.)
Since this specification does not define when a style change event occurs, and thus what changes to computed values are considered simultaneous, authors should be aware that changing any of the transition properties a small amount of time after making a change that might transition can result in behavior that varies between implementations, since the changes might be considered simultaneous in some implementations but not others.
When a style change event occurs, implementations must start transitions based on the computed values that changed in that event. If an element is not in the document during that style change even or was not in the document during the previous style change event, then transitions are not started for that element in that style change event.
When element is added, reflow is needed. The same applies to adding the class. However when you do both in single javascript round, browser takes its chance to optimize out the first one. In that case, there is only single (initial and final at the same time) style value, so no transition is going to happen.
The setTimeout trick works, because it delays the class addition to another javascript round, so there are two values present to the rendering engine, that needs to be calculated, as there is point in time, when the first one is presented to the user.
There is another exception of the batching rule. Browser need to calculate the immediate value, if you are trying to access it. One of these values is offsetWidth. When you are accessing it, the reflow is triggered. Another one is done separately during the actual display. Again, we have two different style values, so we can interpolate them in time.
This is really one of very few occasion, when this behaviour is desirable. Most of the time accessing the reflow-causing properties in between DOM modifications can cause serious slowdown.
The preferred solution may vary from person to person, but for me, the access of offsetWidth (or getComputedStyle()) is the best. There are cases, when setTimeout is fired without styles recalculation in between. This is rare case, mostly on loaded sites, but it happens. Then you won't get your animation. By accessing any calculated style, you are forcing the browser to actually calculate it
Trigger CSS transition on appended element
Explanation For the last part
The .css() method is a convenient way to get a style property from the first matched element, especially in light of the different ways browsers access most of those properties (the getComputedStyle() method in standards-based browsers versus the currentStyle and runtimeStyle properties in Internet Explorer) and the different terms browsers use for certain properties.
In a way .css() is jquery equivalent of javascript function getComputedStyle() which explains why adding the css property before adding class made everything work
Jquery .css() documentation
// Does not animate
var $a = $('<div>')
.addClass('box a')
.appendTo('#wrapper');
$a.css('opacity');
$a.addClass('in');
// Check it's not just jQuery
// does not animate
var e = document.createElement('div');
e.className = 'box e';
document.getElementById('wrapper').appendChild(e);
window.getComputedStyle(e).opacity;
e.className += ' in';
.box {
opacity: 0;
-webkit-transition: all 2s;
-moz-transition: all 2s;
transition: all 2s;
background-color: red;
height: 100px;
width: 100px;
margin: 10px;
}
.box.in {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="wrapper"></div>
Here is the listed work arounds [SO Question]
css transitions on new elements [SO Question]
The main solution is understanding setTimeout(fn, 0) and its usages.
This is not related to CSS animations or jQuery load method.
This is a situation when you do multiple tasks into DOM.
And delay time is not important at all, the main concept is using setTimeout.
Useful answers and tutorials:
Why is setTimeout(fn, 0) sometimes useful? (stackoverflow answer)
Events and timing in-depth (real-life examples of setTimeout(fn, 0))
How JavaScript Timers Work (by jQuery Creator, John Resig)
function insertNoDelay() {
$('<tr><td>No Delay</td></tr>')
.appendTo('tbody')
.addClass('green');
}
function insertWithDelay() {
var $elem = $('<tr><td>With Delay</td></tr>')
.appendTo('tbody');
setTimeout(function () {
$elem.addClass('green');
}, 0);
}
tr { transition: background-color 1000ms linear; }
.green { background: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr><td>Hello World</td></tr>
</tbody>
</table>
<button onclick="insertNoDelay()">No Delay</button>
<button onclick="insertWithDelay()">With Delay</button>
This is a common problem caused by browsers. Basically, when new element is inserted it is not inserted immediately. So when you add the class, it is still not in the DOM and how it will be rendered is calculated after the class is added. When the element is added to the DOM, it already has the green background, it never had a white background so there is no transition to do. There are workarounds to overcome this as suggested here and there. I suggest you use requestAnimationFrame like this:
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
requestAnimationFrame(function() {
$(row_id).addClass('green');
});
});
}
Edit:
Seems like the above solution doesn't work for all cases. I found an interesting hack here which triggers an event when an element is really parsed and added to the DOM. If you change the background color after the element is really added, the problem will not occur. Fiddle
Edit: If you want to try this solution (Won't work below IE9):
Include this CSS:
#keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
#-moz-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
#-webkit-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
#-ms-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
#-o-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
.nodeInsertedTarget {
animation-duration: 0.01s;
-o-animation-duration: 0.01s;
-ms-animation-duration: 0.01s;
-moz-animation-duration: 0.01s;
-webkit-animation-duration: 0.01s;
animation-name: nodeInserted;
-o-animation-name: nodeInserted;
-ms-animation-name: nodeInserted;
-moz-animation-name: nodeInserted;
-webkit-animation-name: nodeInserted;
}
And use this javascript:
nodeInsertedEvent= function(event){
event = event||window.event;
if (event.animationName == 'nodeInserted'){
var target = $(event.target);
target.addClass("green");
}
}
document.addEventListener('animationstart', nodeInsertedEvent, false);
document.addEventListener('MSAnimationStart', nodeInsertedEvent, false);
document.addEventListener('webkitAnimationStart', nodeInsertedEvent, false);
function load_tbody(row_id) {
$('tbody').load("load_tbody.php", function() {
$(row_id).addClass('nodeInsertedTarget');
});
}
Can be made into a generic solution or library. This is just a fast solution.
Related
I have a DIV with the following CSS code attached:
.active,#foo:active {background-color: rgba(0,0,0,0.75)}
In addition, I have set up keydown and keyup javascript routines to convert a selected keypress to add and remove the 'active' class, darkening it accordingly. My problem is when the user clicks on the DIV (darkening it as expected)...but in a setInterval I have running, polling the DIV and several more like it periodically to get state information, I run into the problem of not being able to tell the current DIV state.
Getting the state via the active class is easy enough. I simply have to do this...
document.getElementById("foo").classList.contains("active")
That gives me a boolean on/off I can use, but the following does not work to read a mouse long click.
document.getElementById("foo").classList.contains(":active")
This is because activated pseudoes do not show up in classList. I tried rewriting the mouse-examining check to look like this:
document.getElementById("foo") === document.activeElement
But as the element is a DIV, this never resolves to a true as document.activeElement stays stuck on the BODY element of the page. I also tried looking at the current background-color, but the following doesn't update when :active is in use.
document.getElementById("foo").style.backgroundColor === "rgba(0,0,0,0.75)"
Is there another way to proceed without needing to resort to removing :active from the CSS and installing onclick() and onmouseout() to my code? Using that particular workaround does not scale well depending on how many DIVs I set up in this fashion. I would much rather detect when the DIV is currently using the CSS rule described above.
Please, no jQuery solutions or external libraries. I want to use vanilla JavaScript.
Pseudo elements are not part of the DOM so you cannot trigger events on them.
https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
In addition .style prototype function does not work as intended, to look for computed style use
var ele = document.querySelector('.example-value')
window.getComputedStyle(ele, null).backgroundColor === "rgba(0,0,0,0.75)"
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
Polling to get the current state of an element is a bad idea, instead use events.
When polling, you are making CPUs always process for nothing, it can make your page irresponsible, cause useless bottlenecks, but most of all, it consumes a lot of electricity for nothing. Always think about the trees when coding.
But one has to admit that for the :active status, it may be a bit cumbersome to listen to all the events that can trigger it.
So we've got to be a bit smarter, and create our own event from there.
We can create an empty animation triggered only in the :active state.
Then we just have to listen for the animationstart event to act as an replacement for our pseudo-class activation event.
/* older browsers might need vendor prefixes... */
foo.addEventListener('animationstart', function(evt){
// to be sure it's our correct event, we check for the animationName
console.log('active', evt.animationName === 'active');
});
#foo:active{
background-color: #FAFFAA;
-webkit-animation: active 0s linear;
-o-animation: active 0s linear;
-ms-animation: active 0s linear;
animation: active 0s linear;
}
#keyframes active{}
#-webkit-keyframes active{}
#-o-keyframes active{}
#-ms-keyframes active{}
<div id="foo">
click me to activate me
</div>
And if ever you need to know at any time if an element has an pseudo-class, you can use Element.matches(cssRule).
The word "active" has different meanings:
An element with the :active pseudo-class. This means the element is in the process of being clicked, usually. This is most commonly used for creating some visual effect when the user mouse-downs on a button, and remove it when he mouse-ups, for example. This is probably not relevant to your use case.
The element given by document.activeElement. This does not mean the element with the :active pseudo-class; it means the element with focus. It will be the body if there is no specific focus, or it could be some input element, or it could be any other element with a tabindex attribute. This is also the element with the :focus pseudo-class. An element can be focused by clicking on it, or tabbing to it, or calling HTMLElement#focus on it.
Some application-defined concept of "active", such as the currently active tab in a tabbed interface, often represented by the presence of a user-defined class on the element, such as your .active.
In general, people write far too much JavaScript to check things, or intercept events, or set magic variables, or add and remove classes or even local styles, or in the worst jQuery style add and remove elements from the DOM, or God forbid do polling, when in many cases CSS could handle what needs to be done if used properly. A trivial example is writing mouseover handlers when :hover could do the job.
I don't fully understand what you are trying to accomplish, or what the desired behavior is. However, the following code might give you some clues:
const activeElement = document.getElementById("activeElement");
const divElement = document.getElementById("div");
function showActiveElement() {
activeElement.textContent = document.activeElement.tagName;
}
function updateActiveElement() { setInterval(showActiveElement, 500); }
function setFocus() { divElement.focus(); }
updateActiveElement();
/* Show a message if the div is active (being clicked on). */
#activeMessage { display: none; }
#div:active ~ #activeMessage { display: block; }
/* Show a message if the div is focused. */
#focusMessage { display: none; }
#div:focus ~ #focusMessage { display: block; }
/* Style the div when it is focused. */
#div:focus { background-color: rgba(0, 0, 0, 0.75); color: white; }
#div { border: 1px solid gray; }
<p>
Here is the div we are working with.
Click on it, or tab to it, to give it the focus.
</p>
<!-- The div in question. Give it a tabindex to allow focus. -->
<div id="div" tabindex="1">
Hello Bob
</div>
<p id="activeMessage">
The div is active, in the sense that the mouse is being clicked on it, and
therefore its <tt>:active</tt> pseudo-class is set.
</p>
<p id="focusMessage">
The div is active, in the sense that it has the focus,
therefore its <tt>:focus</tt> pseudo-class is set.
<p>
The element with focus at the moment (<tt>document.activeElement<//tt>) is
<span id="activeElement"></span>
</p>
<button onclick="setFocus()">Make the div focused ("active")</button>
I've tried a dozen libraries to achieve this effect but I must be making a mistake somewhere. I'm currently using this library:- zeusdeux/isInViewport.
In my css I have a style called .animated-element like so:-
.animation-element {
}
.in-view {
}
and I have several css elements that start an animation when the .in-view class is added:-
.trans-1 {
-webkit-transition: 2s;
transition: 2s;
}
.fade {
opacity: 0;
}
.fade.in-view {
opacity: 1;
}
In my html I have div elements with these classes for animating:-
<div class="fade trans-1 animation-element">
<h2 class="medium-subheader-bold">Header</h2>
</div>
Finally, the javascript checks whether an element is in the viewport using the library, and adds a class to the element if it is. Thereby changing the .fade to .fade.in-view (opacity 0 to 1):-
(function($) {
$(document).ready(function() {
$(window).scroll(function() {
$('.animation-element').removeClass('in-view');
$('.animation-element:in-viewport').addClass('in-view');
});
});
}(jQuery));
When I load the page in a browser, all the elements in the page are loaded immediately and animated. When I inspect the webpage to check elements that are not visible in the viewport, I can see that they are rapidly flickering between adding and removing the in-view class. I've also tried removing the $('.animation-element').removeClass('in-view'); line from the above javascript but the in-view class is still added immediately, even though elements are far out of the viewport.
I've tried this with several libraries and keep running into the same problem, so it must be the way I'm implementing it and not the fault of the library.
I should also say I'm using Pug to generate the html, regular css, and serving whole pages through node.js.
I finally figured out what the issue was. I spent a whole day trying to recreate it in JSFiddle and modifying different parts. In the end it was because I didn't put <!DOCTYPE html> at the top of the html document. Its crazy that everything else worked, even the animations when scrolling up, just not scrolling down, because of that one line.
In the past with JS transitions, one could specify some behavior to happen after the transition, via a callback. E.g.
//jQuery
function hideTheContent() {
$('#content').fadeOut(1000,function() {
mandatoryLogicAfterHidingContent();
});
}
Now with CSS3 transitions, we can do something like this.
//CSS
#content {
opacity:1;
transition: opacity 1s;
}
.hidden {
opacity:0;
transition: opacity 1s;
}
//jQuery
function hideTheContent() {
$('#content').addClass('hidden');
// still need to run mandatoryLogicAfterHidingContent
}
I know of the new transitionend events, so hypothetically we could do something like this:
//jQuery
function hideTheContent() {
$('#content').on('transitionend', function(e) {
mandatoryLogicAfterHidingContent()
})
$('#content').addClass('hidden');
}
but since we're now separating out the JS from the UI, it's possible that someone else could come along with a new UI where content-hiding is instant, remove the CSS3 transition, and inadvertently break the JS call to mandatoryLogicAfterHidingContent().
Another scenario, say I have a box and there's a reset function that resizes said box to size 50x50 (with transition), then calls a mandatoryLogicAfterResize(). If I call the reset fn twice, I don't think the transition event is guaranteed to fire in this case - but I still need mandatoryLogicAfterResize to run both times.
In more complex codebases, I also worry about other transitions getting called before the specific transition I'm targeting. and prematurely triggering the mandatoryLogic(). I guess the core problem here is, with CSS3 transitions, how can I defensively tie the mandatoryLogicAfterHidingContent() event handler with my and only my invocation of addClass('hidden'), like I could with the jQuery callback?
I have a couple of classes: hide is display: none, and transparent is opacity: 0. The element pr_container has -webkit-transition: opacity 1s. The following JQuery-based code makes an element appear in an animated fasion:
pr_container.removeClass("hide");
setTimeout(function() { pr_container.removeClass("transparent"); }, 0);
However, when I remove setTimeout and instead just remove the second class, there is no animation. Why?
Edit: I'm using the latest Chrome, I haven't checked other browsers yet.
Edit: I tried putting both calls in the same setTimeout callback - no animation. So it's clearly about separation.
Edit: here's the jsFiddle: http://jsfiddle.net/WfAVj/
You can't make a transition if you are changing display property at the same time. So in order to make it work you have to hide your element some other way. For example:
.hide {
height: 0;
width: 0;
/* overflow: hidden; padding: 0; border: none; */
}
http://jsfiddle.net/dfsq/WfAVj/1/
There's no reasonable "curve" to transit from one display status to another, so in current implementation of browsers, any transition that somehow involves display will end up with no transition at all.
With this code:
pr_container.removeClass("hide");
pr_container.removeClass("transparent");
You can imagine the two statements execute in a single "blocking" queue, so browsers practically renders the element from class="hide transparent" to class="", and as stated above, the hide class practically invalidates any existing transition.
By using
pr_container.removeClass("hide");
setTimeout(function() { pr_container.removeClass("transparent"); }, 0);
You told browsers to remove the "transparent" class "as soon as possible, but no in the same queue", so browser first removes "hide", and then moves on. The removal of "transparent" happens when the browser think it has resource to spare, thus the transition does not get invalidated.
only the "transperent" class produce animation .. "hide" is instant. So start the animation and if needed "hide" after 1 second:
test.addClass("transparent");
//hide after 1 sec, when the animation is done
setTimeout(function() {test.addClass("hide"); }, 1000); //1000ms = 1sec
http://jsfiddle.net/WfAVj/4/
By using suggestions in the linked question, I made a version that I'm satisfied with:
.test {
-webkit-transition: visibility 1s, opacity 1s;
}
.hide {
visibility: hidden;
}
.transparent {
opacity: 0;
}
http://jsfiddle.net/xKgjS/
Edit: now the two classes can even be combined to one!
Thanks to everyone!
I am trying to get off javascript animations and use CSS animations instead. I am currently using jQuery's animation functionality.
I came across this website with a bunch of wonderful css animations. Such as:
.demo1 {
-webkit-transition:all .5s ease-out;
-moz-transition:all .5s ease-out;
-ms-transition:all .5s ease-out;
-o-transition:all .5s ease-out;
transition:all .5s ease-out;
}
.demo1:hover {
-webkit-transform:translate(0px,10px);
-moz-transform:translate(0px,-10px);
-ms-transform:translate(0px,-10px);
-o-transform:translate(0px,10px);
transform:translate(0px,-10px);
}
What I can't figure out is how to activate these animations programmatically. So for example, instead of on a hover, how can I translate the element by calling elem.translate()?
I may be misinterpreting what you're asking, but I think you may be under a mistaken impression of what "translate" is on an element. A DOM element has an attribute called "translate", as well as a css property "translate". However, the element attribute "translate" is just a boolean flag specifying whether the text in the element should be translated in the linguistic sense, it is not a callable function and has nothing to do with the css property.
That aside, there are still plenty of ways to translate an element programmatically. Some other people already gave a pretty good idea of how to do this with jQuery. If you don't wish to use jQuery, you can still add and remove classes manually (same goes for styles).
Here's an example I cooked up for class addition/removal. It's pretty straightforward, but here's the relevant code for class modification:
.translator {
-webkit-transform:translate(0px,100px);
-moz-transform:translate(0px,-100px);
-ms-transform:translate(0px,-100px);
-o-transform:translate(0px,100px);
transform:translate(0px,-100px);
}
...
function move_box() {
var the_box = document.getElementById("the-box");
if (the_box.classList.contains("translator")) {
the_box.classList.remove("translator");
} else {
the_box.classList.add("translator");
}
}
By applying the class, the animation will begin (and removing it will reverse it). This can happen as many times as you'd like.
One important note: for this example, I still have the style "transition:all .5s ease-out;" applied to the div before anything happens. This is just a universal default that governs how animation effects are applied to the element. There are a couple of different approaches to this, but for simplicities sake I'm going to just leave it like this.
Otherwise, you can add the styles directly, like so:
function move_box() {
var the_box = document.getElementById("the-box");
set_translate(the_box, 100);
}
function set_translate(e, pix) {
e.style["-webkit-transform"] = "translate(0px, "+ pix +"px)";
e.style["-moz-transform"] = "translate(0px, -" + pix +"px)";
e.style["-ms-transform"] = "translate(0px, -" + pix + "px)";
e.style["-o-transform"] = "translate(0px, " + pix + "px)";
e.style["transform"] = "translate(0px, -" + pix + "px)";
}
Nothing too complex here - it sets each relevant element directly by manipulating the styles on the element. As before, it relies on a separate class to specify the transition style.
Personally, I think the class addition/removal is far superior. Technically speaking, direct modification of styles is more flexible, but if that's what you're aiming for you probably should use a good library like jQuery transit (as mentioned in the comments). However, if you just want to be able to programmatically apply a few canned effects, modifying classes on the fly is a fine solution.
If you already have the CSS in place, you can trigger it in jquery by doing $('.demo1').trigger('hover'); to simulate a hover event, or change your css selector from .demo:hover to .class-name and just add that class using $('.demo').addClass('class-name');
You can use jQuery.css.fn to apply the css rules.
$('.demo1').click(function(){
$(this).css({
transform: 'translate(0px,-10px)'
});
});
Or add a class to the element:
$('.demo1').click(function(){
$(this).toggleClass('translate');
});
.translate {
-webkit-transform:translate(0px,10px);
-moz-transform:translate(0px,-10px);
-ms-transform:translate(0px,-10px);
-o-transform:translate(0px,10px);
transform:translate(0px,-10px);
}