For a number of projects now I have had elements on the page which I want to translate out of the screen area (have them fly out of the document). In proper code this should be
One very simple, but not aesthetically pleasing solution is to define the class dynamically:
var stylesheet = document.styleSheets[0];
var ruleBlockHide;
and
//onresize
if(ruleBlockHide) stylesheet.deleteRule(ruleBlockHide);
ruleBlockHide = stylesheet.insertRule('.block.hide{ -webkit-transform:translateY(-'+window.innerHeight+'px); }',stylesheet.cssRules.length);
see: http://jsfiddle.net/PDU7T/
The reason a reference to the rule needs to be kept is that after each screen resize the rule has to be deleted and re-added.
Although this solution gets the job done, there has to be some DOM/CSS combination which would allow this to be done without javascript (something along the lines of a 100%x100% element containing such a block, but I haven't been able to figure out any transform based way).
What I did is use the vh
(view height) unit. It's always relative to the screen size, not the element itself:
/* moves the element one screen height down */
translateY(calc(100vh))
So if you know the position of the element in the screen (say top:320px
), you can move it exactly off the screen:
/* moves the element down exactly off the bottom of the screen */
translateY(calc(100vh - 320px))
Use calc
method (http://jsfiddle.net/ATcpw/2/):
.block{
position:absolute;
top: -webkit-calc(100% - 110px);
right:10px;
left:10px;
height:100px;
background:gray;
-webkit-transition: all 2s;
/*this adds GPU acceleration*/
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
}
.block.hide{
top: -100px;
}
Since you are using -webkit
prefix I used it as well.
calc
is supported by majority of browsers: http://caniuse.com/#search=calc
get the document width. then use a java script trigger to trigger the css3 translation.
function translate(){
var width = document.body.Width;
document.getElementById('whateverdiv').style='translateX(' + width + 'px)';
}
If you wrap the .block div with a container:
<div class="container">
<div class="block"></div>
</div>
<button>Click</button>
you could expand and then, translate the container itself after the click event
document.querySelector("button").addEventListener("click", function () {
document.querySelector(".container").classList.add("hide");
});
with this style
.block {
position:absolute;
bottom:10px;
right:10px;
left:10px;
height:100px;
background:gray;
}
.container {
-webkit-transition: -webkit-transform ease-in-out 1s;
-webkit-transform-origin: top;
-webkit-transition-delay: 0.1s; /* Needed to calculate the vertical area to shift with translateY */
}
.container.hide {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
/* background:#f00; /* Uncomment to see the affected area */
-webkit-transform: translateY(-110%);
}
In this way, it is possible to apply a correct translationY percentage ( a little more than 100%, just to have it out of the way ) and mantaining the button clickable.
You could see a working example here : http://jsfiddle.net/MG7bK/
P.S: I noticed that the transition delay is needed only for the transitionY property, otherwise the animation would fail, probably because it tries to start before having an actual value for the height. It could be omitted if you use the horizontal disappearing, with translateX.
I recently built an app which used precisely this technique for sliding 'panels' (or pages) and tabs of the application in and out of view. A basic implementation of the tabs mechanism can be seen here.
Basically (pesudo-code to illustrate the concept, minus prefixes etc):
.page {
transform: translateY(100%);
}
.page.active {
transform: translateY(0%);
}
The problem I had was that Android Webkit in particular wouldn't calculate percentage values correctly. In the end I had to use script to grab the viewport width and specify the value in pixels, then write the rules using a library for dynamic stylesheet parsing.
But eventually, and in spite of only these minor platform-specific problems, this worked perfectly for me.