I'm trying to recreate the effect shown in the gif here. It's fine even to have two separate images - I don't need to recreate the greyscale/blur effect (although I can with webkit filters) - it's just the masking that I'm having trouble with.
Basically I've got a carousel slider, and as it slides left and right, the background underneath the current slide will be blurred, to make the text on top more visible. I can't manage to keep the background in the same place as the slider moves along as a mask. How can I recreate this?
edit: I've managed to figure this out: http://jsfiddle.net/9xk410wk/18/
I used CSS transforms in opposite directions:
.tile {
-webkit-transform: translate3d(-400px, 0px, 0px);
}
.blur > div {
-webkit-transform: translate3d(400px, 0px, 0px);
}
.tile:hover {
-webkit-transform: translate3d(400px, 0px, 0px);
}
.tile:hover .blur > div {
-webkit-transform: translate3d(-400px, 0px, 0px);
}
You could use a webkit grayscale filter for this:
FIDDLE (hover over the image to see the effect)
Markup
<div class="pic">
<div class="mask">SLIDER</div>
</div>
CSS
.pic {
width:288px;
height: 214px;
background: url(https://dl.dropboxusercontent.com/u/51558405/pic.png) no-repeat;
position:relative;
overflow: hidden;
}
.pic:hover .mask {
-webkit-transform: translate3d(228px, 0, 0);
background-position: 100% 0;
}
.mask {
width: 60px;
height: 214px;
position: absolute;
left:0;
top:0;
color: #fff;
background: url(https://dl.dropboxusercontent.com/u/51558405/pic.png) 0 0 no-repeat;
-webkit-transition: all 1.5s linear;
transition: all 1.5s linear;
-webkit-transform: translate3d(0, 0, 0);
-webkit-filter: grayscale(100%);
z-index:1;
}
I'm not sure exactly the issue you are running into without seeing code, but here is a crude fiddle that I created which mimics the gif:
http://jsfiddle.net/z71g26by/
I just used a CSS3 linear animation and changed the opacity of the moving panel. I just used colors, but it should work the same with a background image.
CSS:
body {
/*To hide the horizontal scroller */
overflow: hidden;
}
.container {
width: 500px;
height: 420px;
background-color:blue;
}
.panel {
width: 200px;
height: 420px;
background-color: white;
opacity: .8;
-webkit-animation: move 5s linear infinite;
}
#-webkit-keyframes move {
0% {margin-left: 1000px;}
100% {margin-left: -1000px;}
}
HTML:
<div class="container">
<div class="panel"><p>SLIDER</p></div>
</div>
Note: This only works in webkit, but you can add the appropriate pre-fixes to get it working in other browsers.
Related
I've got a container, which contains some things including a box at the bottom. I have a need to transition that box from the bottom to the top.
from {
bottom: 4px;
top: auto;
}
to {
bottom: auto;
top: 4px;
}
For obvious reasons, this doesn't work. You can't transition/animate with an auto value. I've worked around this by having the box fade out and slide off the bottom, then fade in and slide on the top. This works, but it feels longer than it needs to be.
The box has dynamic height, and the entire thing is responsive so pre-calculated values are right out.
Any ideas? Or is what I have now the best I can do?
So it's definitely possible, but instead of trying to achieve it with a combination of top and bottom, you can achieve it with using top and translate. This will allow you to have a clear point for your stop and start whilst still giving you the freedom of a responsive container.
It would look something like this:
from {
top: 4px;
transform: translateY(0);
}
to {
top: calc(100% - 4px);
transform: translateY(-100%);
}
Here's an example in action, (I've used a textarea so that you can resize and keep testing, the button(+js) is just there to help facilitate the class change)
$('.go').click(function(){
$('textarea').toggleClass('up');
});
textarea {
position: fixed;
top: 0;
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-transition: all 1s ease 0s;
transition: all 1s ease 0s;
left: 150px;
}
textarea.up {
top: 100%;
-webkit-transform: translateY(-100%);
transform: translateY(-100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="go">
TRANSITION
</button>
<textarea></textarea>
And a Fiddle if you prefer that instead.
You can simulate the top property by using the calc() CSS function :
from {
bottom: 4px;
}
to {
bottom: calc(100% - 4px - yourContainerHeight);
}
You can use animations to do this. You don't have to change bottom to top. Just use one of them. I chose to use 'bottom' . Then to simulate the top:4px you move the box with bottom:calc(100% - 4px) and together with transform:translateY(100%) . This is equal to top:4px .
see snippet below
.container {
height: 300px;
width: 300px;
border: 1px solid red;
position: relative;
}
.box {
position: absolute;
bottom: 4px;
background: red;
width: 100%;
height: 10px;
animation-name: fromBottom;
animation-delay: 1s;
animation-duration: 0.8s;
animation-fill-mode: forwards;
animation-timing-function: ease-out;
transform: translateY(0%)
}
#keyframes fromBottom {
0% {
bottom: 0;
transform: translateY(0%)
}
100% {
bottom: calc(100% - 4px);
transform: translateY(100%)
}
}
<div class="container">
<div class="box">
</div>
</div>
I think I found a bug related with percentages on Safari in the animations. I would like to know if really it is a bug or a Safari custom.
Explanation of the bug:
On Safari or iOS when you start an animation with a translate with percentages, the position is wrong and the animation is shown in another place.
In the next example, the square should not move because the transform is the same and it should start with a 10% 10% "margin" of its size. The bug occurs when it is adding via JavaScript after some time (like 500 ms).
If you see the bug, you will see a jump from 0 0 to 10% 10% in Safari and iOS.
var div = document.createElement('div');
setTimeout( function(){
document.body.appendChild(div);
}, 500);
div {
background: red;
width: 200px;
height: 200px;
-webkit-transform: translate(10%, 10%);
-webkit-animation: 1s bugAnimation;
}
#-webkit-keyframes bugAnimation {
from {
-webkit-transform: translate(10%, 10%);
background: blue; /* To see the animation */
}
to {
-webkit-transform: translate(10%, 10%);
background: red; /* To see the animation */
}
}
Possible solutions:
Changing the percentage values by viewport units or another.
Obviously that options is not valid for all cases because I need the percentage but it could be a small solution for now if I know the size of the div (vw, vh, px...).
Do somebody know this bug?
Tested on Safari 10.1.1 and iOS 9.3.1 (with webview).
EDIT:
Really I need the translate2D because I am rotating a DIV in the center of the page and the size is unknown, an example:
var div = document.createElement('div');
setTimeout( function(){
document.body.appendChild(div);
}, 500);
div {
background: red;
width: 200px;
height: 200px;
position: fixed;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-webkit-animation: 1s bugAnimation;
-webkit-transform-origin: center center;
}
#-webkit-keyframes bugAnimation {
from {
-webkit-transform: rotate(0deg) translate(-50%, -50%);
}
to {
-webkit-transform: rotate(360deg) translate(-50%, -50%);
}
}
Ok, a workaround maybe using em instead of %
var div = document.createElement('div');
setTimeout( function(){
document.body.appendChild(div);
}, 500);
div {
background: red;
width: 200px;
height: 200px;
-webkit-animation: 1s bugAnimation forwards;
}
#-webkit-keyframes bugAnimation {
from {
-webkit-transform: translate(0, 0);
background: blue; /* To see the animation */
}
to {
-webkit-transform: translate(1.3em, 1.3em);
background: red; /* To see the animation */
}
}
Ok, please take another look at that approach. I wondered why you are using keyframed animation. Maybe the example is not representative but in this case you can just animate with a simple transition. Please take another look here:
setTimeout(function() {
document.getElementById("div").classList.add("animated");
}, 1000);
div {
background: red;
width: 200px;
height: 200px;
position: absolute;
top: 50%;
left: 50%;
-webkit-transition: transform 1s;
-moz-transition: transform 1s;
-ms-transition: transform 1s;
-o-transition: transform 1s;
transition: transform 1s;
}
.animated {
transform: translate(-50%, -50%) rotate(360deg);
}
<div id="div"></div>
Looks like a Mac Safari issue,
I removed -webkit-transform property from keyframes which fixes the jumping problem on Safari and also works fine on Chrome too. Try this code,
var div = document.createElement('div');
setTimeout( function(){
document.body.appendChild(div);
}, 500);
div {
background: red;
width: 200px;
height: 200px;
-webkit-transform: translate(10%, 10%);
-webkit-animation: 1s bugAnimation;
}
#-webkit-keyframes bugAnimation {
from {
background: blue; /* To see the animation */
}
to {
background: red; /* To see the animation */
}
}
With the reference from this Rotate image with onclick , I am trying to apply a css3 transition to a div, when the div element is clicked. The demo is here Everything is working perfect.
HTML
<div class="testRotate">Test rotate</div>
CSS
.testRotate{
width: 300px;
height: 50px;
border: 1px solid black;
padding: 20px;
margin: 0px auto;
margin-top: 50px;
-moz-transition: transform 1s;
-webkit-transition: transform 1s;
transition: transform 1s;
}
.testRotate.rotate{
transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
JS
$(function(){
$("div").click( function(){
$(this).addClass("rotate");
setTimeout(function(){$("div").removeClass("rotate");}, 1500);
});
});
In this example, when onclicking the div, rotate class will be applied to it, so it will rotate for 360 degree, as defined in css. After sometimes we are removing the rotate class, so again the div is rotating back to its original position.
Now what i need is, when it clicked the element is has to rotate for 360 degree, but it should not suppose to rotate back once the rotate class got removed from it.
You can add a new class for transition and remove rotate as well as the class for transition.
$(function(){
$("div").click( function(){
$(this).addClass("testRotate rotate");
setTimeout(function(){$("div").removeClass("testRotate rotate");}, 1500);
});
});
.test {
width: 300px;
height: 50px;
border: 1px solid black;
padding: 20px;
margin: 0px auto;
margin-top: 50px;
}
.testRotate{
-moz-transition: transform 1s;
-webkit-transition: transform 1s;
transition: transform 1s;
}
.testRotate.rotate{
transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test testRotate">Test rotate</div>
Fiddle Demo
Fiddle
$("div").click(function() {
if ( $(this).css( "transform" ) == 'none' ){
$(this).css("transform","rotate(360deg)");
} else {
$(this).css("transform","");
}
});
I am building a Single Page Application and I am using position absolute on my views (pages) in order to achieve page transitions while I navigate to different pages. I am using css animations and the effect I am after is one page to slide out to the right and at the same time the next page to slide in from the left.
This works fine as it is, but the problem is that most mobile browsers render the absolute positioned elements as a different layout and this has a negative effect on performance.
I wonder if there is an alternative to absolute positioning in order to achieve the effect I described above. I have tried to use display: flex and float: left, but could not achieve the same effect.
Check a very basic example of what I am doing:
#-webkit-keyframes moveFromLeft {
from { -webkit-transform: translateX(-100%); }
}
#keyframes moveFromLeft {
from { -webkit-transform: translateX(-100%); transform: translateX(-100%); }
}
#-webkit-keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); }
}
#keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); transform: translateX(100%); }
}
.moveFromLeft {
-webkit-animation: moveFromLeft .7s ease both;
animation: moveFromLeft .7s ease both;
}
.moveToRight {
-webkit-animation: moveToRight .7s ease both;
animation: moveToRight .7s ease both;
}
html,
body,
.page-container {
height: 100%;
position: relative;
width: 100%;
}
.page {
height: 400px;
color: #FFF;
position: absolute;
left: -100%;
top: 0;
width: 100%;
display: none;
}
.page.active {
display: block;
left: 0;
}
.page1 {
background: #000;
}
.page2 {
background: #0F0;
}
Fiddle
Here's my website: http://adamshort2.hostoi.com/index.html
As you can see when you hover over the nav links it brings up a "ribbon" style white box around the list element. What I'd like is for that to slide down from the top (animated) instead of just appearing. If possible just stick to CSS but I don't mind Javascript/Jquery if needed.
This can be done with pure CSS. You cannot do it with the <a> alone because you need the text to stay where it is while the background animates. Changing background-position is possible, but I chose to use another element (specifically a pseudo element).
#nav a {
/* required to keep absolute background on top */
z-index: 1;
/* required to keep text on top of absolute bg */
position: relative;
/* not mandatory; makes it look better when animating out
because during that time it will be white on white */
transition: color 1s;
}
#nav li a:before {
background-color: #FFF;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
display: block;
width: 100%;
height: 100%;
/* element will not appear without this */
content: " ";
position: absolute;
/* height of the <a> so bg is off screen */
top: -175px;
left: 0;
transition: top 1s;
/* text will appear above bg */
z-index: -1;
}
#nav li a:hover {
color: red;
}
#nav li a:hover:before {
top: 0px;
}
Working demo: http://jsfiddle.net/cLsue/
The CSS "transition" property should suit your needs as a pure CSS solution, as long as you aren't concerned about compatibility with older browsers.
Here are 2 quick links that cover CSS transition.
http://www.w3schools.com/css3/css3_transitions.asp
http://www.creativebloq.com/css3/animation-with-css3-712437
If I may make a suggestion:
In this scenario it's better practice to take advantage of CSS3's translate3d because it's hardware-accelerated whereas animating using the left property is not hardware-accelerated.
There are plenty of articles that documents the increase in performance when comparing the two. Here's one for example: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css
Here's how to achieve the animation using Explosion Pill's example:
#nav a {
/* required to keep absolute background on top */
z-index: 1;
/* required to keep text on top of absolute bg */
position: relative;
/* not mandatory; makes it look better when animating out
because during that time it will be white on white */
transition: color 1s;
}
#nav li a:before {
background-color: #FFF;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
display: block;
width: 100%;
height: 100%;
/* element will not appear without this */
content: " ";
position: absolute;
/* height of the <a> so bg is off screen */
/* text will appear above bg */
z-index: -1;
-webkit-transform: translate3d(0, -225px, 0);
-moz-transform: translate3d(0, -225px, 0);
-ms-transform: translate3d(0, -225px, 0);
-o-transform: translate3d(0, -225px, 0);
transform: translate3d(0, -225px, 0);
-webkit-transition: -webkit-transform 1s ease;
-moz-transition: -moz-transform 1s ease;
-o-transition: -o-transform 1s ease;
transition: transform 1s ease;
/* Prevents flickering */
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
#nav li a:hover {
color: red;
}
#nav li a:hover:before {
-webkit-transform: translate3d(0, -50px, 0);
-moz-transform: translate3d(0, -50px, 0);
-ms-transform: translate3d(0, -50px, 0);
-o-transform: translate3d(0, -50px, 0);
transform: translate3d(0, -50px, 0);
}