how do animation without keyframes but with transition - javascript

div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
}
#keyframes example {
0% {}
35% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");}
36% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");}
100% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");transform: rotateY(160deg);}
}
div:hover {
animation-fill-mode: forwards;
animation-name: example;
animation-duration: 1s;
}
<div></div>
I don't use keyframes because i need set unique url for every animation. If i do this then need creator more 100 keyframes.
And i want to do this because with transition can set different url method js. But this not look how i want.
div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
transition:
/* step 1 */
transform 1s,
/* step 2 */
background 0.0s 0.5s;
}
div:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
}
<div></div>

My solution, you can create two elements front and back that lies inside card-container element and animate accordingly:
$(document).ready(function () {
$('.card-container').click(function () {
$(this).toggleClass('clicked');
});
});
.card-container {
position: relative;
overflow: hidden;
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
}
.card-container > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 1.3vmin;
transition: transform 1s, background 0.0s 0.5s;
transform-style: preserve-3d;
}
.card-container .front {
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
background-color: black;
transform: rotateY(0deg);
}
.card-container .back {
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
background-size: contain;
transform: rotateY(180deg);
}
.card-container.clicked .front {
transform: rotateY(180deg);
}
.card-container.clicked .back {
transform: rotateY(0deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card-container">
<div class="front"></div>
<div class="back"></div>
</div>
<div class="card-container">
<div class="front"></div>
<div class="back"></div>
</div>

Move the transition to the hover state and adjust the delay and you will have exactly the same thing:
div.card {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
}
div.card:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
transition: transform 1s linear, background 0s 0.5s linear;
}
<div class="card"></div>

Why do you need 100 URL's to do this? You only need the front of the card image and the back of the card image.
img {
width:100%;
border:1px solid #e0e0e0;
border-radius:1vw;
}
.container {
/* Position and Size the Container */
position: absolute;
top: 17%;
bottom:0; /* Needed to keep the overall height larger than the card. */
left: 20%;
width: 25%;
/* Will inherit to children only (not all descendants) */
perspective: 900px;
}
#card .front {
/* Flip the front side of the card by rotating it around the y-axis. */
transform: rotateY(180deg);
}
#card:hover {
/* Rotate the card as a whole: */
transform: rotateY(180deg);
}
#card div {
/* Forces both elements to come out of the normal flow and occupy the same space on the page. */
position: absolute;
/*
The backface-visibility CSS property determines whether or not the back
face of the element is visible when facing the user. The back face of
an element is always a transparent background, letting, when visible,
a mirror image of the front face be displayed. If your foreground element
is opaque, this property may not need to be set.
*/
backface-visibility: hidden;
}
#card {
/*
Indicates that the children of the element should be positioned in the 3D-space.
And, pass any inherited perspective along to children.
*/
transform-style: preserve-3d;
/*
Changes to the transform property should take 1 second to
change from their current value to their new value.
*/
transition: transform 1s cubic-bezier(.75,1.25,.5,1.25);
}
<!-- The "container" will be the 3D space for us to work in. -->
<div class="container">
<!-- The "card" is the single entity that we will manipulate. -->
<div id="card">
<!-- The child elements make up pieces of the overall object.-->
<div class="front"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Ace_of_spades.svg/2000px-Ace_of_spades.svg.png"></div>
<div class="back"><img src="https://thumb1.shutterstock.com/display_pic_with_logo/3172829/620603528/stock-vector-ace-of-spades-with-eyel-vintage-design-t-shirts-620603528.jpg"></div>
</div>
</div>

You'll need to use a transition-timing-function with palindromic timing, so the card image changeover can always be in the middle. Examples of this include linear or ease-in-out (incorporated below).
Note that some browsers don't support transition on background-image though, so you may need to approach this effect differently for it to work in IE, for example.
div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
transition: transform 1s ease-in-out, background 0s .5s;
}
div:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
}
<div></div>

Related

How to remove shaking from overflow css animation?

I'm currently doing a React app which shows what music I'm listening at that time. Obviously some of song names, album name etc. are longer than others so I want to show overflowing part with animation. I managed to do this and it's kinda okay. Longer text scrolls nicely but my problem is it also animates short texts and that causes some shaking on them during the animation.
Any ideas how to remove that shaking? Also Javascript based solutions are appreciated but this seemed to be shorter solution.
div {
width: 100px;
border: 1px solid black;
}
div p {
overflow: hidden;
white-space: nowrap;
display: inline-block;
position: relative;
min-width: 100%;
animation: 5s linear 0s infinite alternate scrolltext;
}
#keyframes scrolltext {
0%,
25% {
transform: translateX(0%);
left: 0%;
}
75%,
100% {
transform: translateX(-100%);
left: 100%;
}
}
<div>
<p>This is a very long text and rolls nicely</p>
<p>And these</p>
<p>two shaking?!</p>
</div>
use margin-left and margin-right instead of left and right
div {
width: 100px;
border: 1px solid black;
}
div p {
overflow: hidden;
white-space: nowrap;
display: inline-block;
position: relative;
min-width: 100%;
animation: 5s linear 0s infinite alternate scrolltext;
}
#keyframes scrolltext {
0%,
25% {
transform: translateX(0%);
margin-left: 0%;
}
75%,
100% {
transform: translateX(-100%);
margin-left: 100%;
}
}
<div>
<p>This is a very long text and rolls nicely</p>
<p>And these</p>
<p>two shaking?!</p>
</div>

CSS tile flip on hover

I have some Div Boxes how can i get them flipped on hover? I tried already some examples i found but i cant get it working? Can someone please help me?
.kachel_a_image_1 {
height:150px;
width:150px;
margin:auto auto;
margin-top:15px;
background:red;
}
.kachel_wrapper {
margin: auto auto;
width: 90%;
min-height: 450px;
margin-top: 55px;
text-align: center;
padding:10px;
padding-top:30px;
padding-bottom:20px;
}
.kachel_text {
font-size:10px;
color:white;
line-height:15px;
text-align:center;
}
.kachel {
height: 180px;
width: 180px;
margin-top: 20px;
margin-left: 58px;
background: #6e7176;
display: inline-block;
margin-bottom:30px;
}
<div class="kachel"><div class="kachel_a_image_1"></div><div class="kachel_text">Social</div></div>
I only want to use Css and no JS if its possible. Can someone explain me how this works or giving me a really simple example :S ?
Use transform:
.kachel:hover{
transform: rotateX(150deg);
}
more Information: http://www.w3schools.com/css/css3_3dtransforms.asp
Also if you want to add a duration to the animation use transition-duration
.kachel{
transition-duration: 5s;
}
for changing the content after the hover use the pseudo element :after and the attribute content.
For example:
.kachel:hover:after{
content: 'hovering';
}
You may have to change it a bit, i haven't tested it.
Using transition and backface-visibility.
Probably the best soultion is to use simple transform and backface-visibility. jsfiddle
.front, .back{
width: 100px;
height: 100px;
}
.front{
background-color: blue;
}
.back{
background-color: red;
background-image: url("https://yt3.ggpht.com/-Bvvd30cZJe4/AAAAAAAAAAI/AAAAAAAAAAA/CxN5F1_QEU8/s100-c-k-no/photo.jpg");
background-size: cover;
}
/* entire container, keeps perspective */
.flip-container {
perspective: 1000;
}
/* flip the pane when hovered */
.flip-container:hover .flipper, .flip-container.hover .flipper {
transform: rotateY(180deg);
}
.flip-container, .front, .back {
width: 100px;
height: 100px;
}
/* flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* front pane, placed above back */
.front {
z-index: 2;
/* for firefox 31 */
transform: rotateY(0deg);
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
}
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front">
</div>
<div class="back">
</div>
</div>
</div>
Using #-webkit-keyframe
Another approach is to use animation and #-webkit-keyframes. However this will run the animation one time initially. (jsfiddle)
.box, .wrapper {
width: 100px;
height: 100px;
position: absolute;
}
.back {
transform: rotateY(90deg);
background-color: red;
-webkit-animation: in 0.2s forwards;
animation in 1s forwards;
-webkit-animation-delay: 0.2s; /* Chrome, Safari, Opera */
animation-delay: 0.2s;
}
.front {
transform: rotateY(90deg);
background-color: blue;
-webkit-animation: out 0.2s forwards;
animation out 0.2s forwards;
background-image: url("https://yt3.ggpht.com/-Bvvd30cZJe4/AAAAAAAAAAI/AAAAAAAAAAA/CxN5F1_QEU8/s100-c-k-no/photo.jpg");
background-size: cover;
}
.wrapper:hover .box.back {
-webkit-animation: out 0.2s forwards;
animation: out 0.2s forwards;
}
.wrapper:hover .box.front {
-webkit-animation: in 0.2s forwards;
animation: in 0.2s forwards;
-webkit-animation-delay: 0.2s; /* Chrome, Safari, Opera */
animation-delay: 0.2s;
}
#-webkit-keyframes in {
from {
-webkit-transform: rotateY(90deg);
}
to {
-webkit-transform: rotateY(0deg);
}
}
#-webkit-keyframes out {
0% {
-webkit-transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(90deg);
}
}
<div class="wrapper">
<div class="box back"></div>
<div class="box front"></div>
</div>
For this I would use backface-visibility in conjunction with transform
<div class="container">
<div class="box front">image</div>
<div class="box back">Social</div>
</div>
CSS:
.container {
width: 180px;
height: 180px;
position: relative;
-webkit-transition: all .4s linear;
transition: all .4s linear;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.box {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
color: white;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.front {
background: red;
z-index: 2;
}
.back {
z-index: 1;
background-color: green;
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
color:white;
}
.container:hover {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
Here's a JS fiddle
EDIT: The above fiddle has been edited to have an outer wrapper which initiates the flip. This ensures that the animation doesn't jitter.
.wrapper {
width: 180px;
}
.wrapper:hover .container {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}

Sliding doors animation in CSS like Twitter notification

I'm trying to imitate Twitter's notification animation
This is what i came up with so far:
$('button').click(function() {
$('#left').css('width', '400px');
$('#right').css('width', '400px');
});
.wrapper {
position: relative;
min-height: 50px;
}
.left {
position: absolute;
left: 0;
height: 50px;
background: #00AEEF;
}
.right {
position: absolute;
right: 0;
height: 50px;
background: #00AEEF;
}
.banner {
width: 0%;
overflow: hidden;
-webkit-transition: width 1s ease-in-out;
-moz-transition: width 1s ease-in-out;
-o-transition: width 1s ease-in-out;
transition: width 1s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="wrapper">
<div id="left" class="banner left"></div>
<div id="right" class="banner right"></div>
</div>
<div style="margin: 10px;">
<button>start animation</button>
</div>
</div>
But using 2 different divs for left and right animation feels like a hack.
Is there a nicer built-in css animation of that type (to be used on a single div)?
Sliding doors effect (only)
(see below for a full-effect demo)
You could animate the background-position of two linear-gradients placed in a single element (so you wouldn't even need to use two more empty elements for styling purpose) e.g.
div {
background:
linear-gradient(to left, #00AEEF 50%, transparent 0),
linear-gradient(to right, #00AEEF 50%, transparent 0);
background-position: 50vw 0, -50vw 0;
background-repeat: no-repeat;
height: 50px;
transition: background-position 1s;
}
:checked + div {
background-position: 0 0, 0 0;
}
Just set a class via js to trigger the transition (for the sake of simplicity I've activated the effect with a :checked pseudoclass)
Codepen demo
You could also obtain the same effect by the opposite animation: if you place a white gradient over a blue background-color you could animate just the background-size of the gradient like so
div {
background: #00AEEF linear-gradient(to right, #fff, #fff);
background-position: 50% 0;
background-repeat: no-repeat;
background-size: 100% 100%;
height: 50px;
transition: background-size 1s;
}
:checked ~ div { background-size: 0 100%; }
Codepen demo
Comparing the two approaches I personally prefer the last one (less code to type, one single gradient to be animated and it seems smoother. Furthermore, the second demo prevents an annoying rounding issue that sometimes happens in the first one, when repositioning the two gradients occurs, as you can see from the screenshot below)
Full effect (with all the animations/transitions)
To recreate the full effect of this notification, markup and style should of course slightly change: starting from the last demo, I moved the main effect on the <a> element inside the wrapper and I inserted other effects, like the # pulsing with an animation and the final slide down after 5 seconds.
The right arrow is made by the unicode symbol U+3009 and it is placed as the content of the a::after pseudoelement
Note: all properties are unprefixed. Add prefixes where necessary
Codepen Demo (Full effect)
Markup
<div class="notification">
<span>#</span>Miro mentioned you
</div>
CSS (embedding Lato font from google fonts)
* {
font : 1rem "Lato", Arial;
box-sizing : border-box;
}
.notification {
position : relative;
overflow : hidden;
font-weight : 100;
font-size : 1.5rem;
}
.notification a {
display : block;
padding : 1em 3em 1em 2.25em;
width : 100%;
font-size : inherit;
font-weight : inherit;
color : transparent;
background : #00AEEF linear-gradient(to right, #fff, #fff);
text-decoration : none;
background-position : 50% 0;
background-repeat : no-repeat;
background-size : 100% 100%;
}
/* The at-sign: I've also tried to use :first-letter but it
* is unreliable when the first char is not a letter or a digit
*/
.notification a span {
position : absolute;
line-height : 1;
top : 50%;
left : 50%;
color : #fff;
font-weight : bold;
transform : translate(-50%, -50%) scale(0);
transform-origin : 50% 50%;
}
/* The arrow */
.notification a:after {
position : absolute;
content : "\3009";
right : 1em;
top : 50%;
transform : translateY(-50%);
}
/* sliding doors effect, color change and final slide down
* all with proper delays
*/
:checked ~ .notification a {
transition: background-size .2s, color .33s 1s, transform 1s 5s;
transform: translateY(100%);
background-size: 0 100%;
color: #fff;
}
/* pulsing and moving the #-sign */
:checked ~ .notification a span {
animation: pulse-at .66s ease-in-out .33s forwards;
}
#keyframes pulse-at {
0% { transform: scale(0) translate(-50%, -50%); }
20% { transform: scale(1.1) translate(-50%, -50%); }
25% { transform: scale(1) translate(-50%, -50%); }
40% { transform: scale(1) translate(-50%, -50%); left: 50%; }
100% { transform: scale(1) translate(0, -50%); left: 1em; }
}
Final result

CSS/Jquery: Peel corner on hover and fold in half on click

Saw this cool 3x3 grid on this site and cant seem to re-create the animation it has.
The image folds a bit on hover and folds completely in half on a click.
Reference: http://doyouimpress.com/
I've tried doing something similar in CSS however the :active psuedo selector won't open the page completely unless you hold click. Would I only be able to re-create this animation w jquery?
Here's what I've done so far (webkit only): http://jsfiddle.net/JDH9/4wrnf/8/
HTML
<div id="container">
<div id="test">
<div id="left"></div>
<div id="center"></div>
</div>
CSS
#container {
position: absolute;
top: 50%;
left: 50%;
margin: -200px 0 0 -100px;
-webkit-perspective: 1000;
}
#test {
position: relative;
}
#test div {
width: 200px;
height: 400px;
}
#left {
background: grey;
z-index: 3;
-webkit-transform-origin: 0% 50%;
-webkit-transition-delay: 1s;
}
#center {
background: grey;
z-index: 1;
}
#left {
position: absolute;
top: 0;
left: 0;
-webkit-transition-duration: 2s;
}
#test:hover #left {
-webkit-transform: rotateY(-45deg);
-webkit-transition-delay: 0s;
}
#test:active #left {
-webkit-transform: rotateY(-180deg);
-webkit-transition-delay: 0s;
}

how do I zoom a background image on a div with background-size

I want a div element to stretch across that is 33% width with a background image done in css
background-image:url(); background-size:cover
How do I animate a zoom-in of the image of the background in the div on mouseover or mouseneter, is there a plugin that can do this? The background div has to use background-size:cover because it's an elastic page.
I don't have a fiddle yet cos I don't know where or how to start
Answer for those who wants to hack CSS transitioning zooming to get applied on background-size: cover;
-- if not, than read the second section for standard ways to achieve such effect
<div class="wrap">
<div></div>
<p>hello</p>
</div>
html, body {
height: 100%;
}
div.wrap {
height: 33%;
width: 33%;
overflow: hidden;
position: relative;
}
div.wrap > div {
position: absolute;
height: 100%;
width: 100%;
-moz-transition: all .5s;
-webkit-transition: all .5s;
transition: all .5s;
-moz-transform: scale(1,1);
-webkit-transform: scale(1,1);
transform: scale(1,1);
background-image: url('http://pimg.tradeindia.com/00288122/b/0/Our-Valuable-Client-List-Click-on-Image-.jpg');
-moz-background-size: cover;
-webkit-background-size: cover;
background-size: cover;
z-index: -1;
}
div.wrap:hover > div {
-moz-transform: scale(2,2);
-webkit-transform: scale(2,2);
transform: scale(2,2);
}
Demo (Using background-size: cover; to transition/zoom the element)
As you said that transitioning the cover size is necessary, so I came up with the trick which I had told you previously, here I have a child element nested under position: relative; element where am having the child element set to position: absolute; with background-image having background-size set to cover and then on hover of parent, I zoom in the element using the transform: scale(2,2); property.
Also, a crucial thing while working with this solution is that we need to set the z-index of the position: absolute; element lower than what the elements you will be placing inside, so it will act like a background
Answer for those who want to go clean with HTML and CSS
You cannot animate a background-size if it's value is cover so either you will need px or %, or you can also use an img tag with transform: scale(2,2); property.
Demo
Demo 2 (zoom-in or zoom-out from the center)
div {
height: 200px;
width: 200px;
background: url('http://pimg.tradeindia.com/00288122/b/0/Our-Valuable-Client-List-Click-on-Image-.jpg');
background-size: 100% 100%;
-moz-transition: all .5s;
-webkit-transition: all .5s;
transition: all .5s;
}
div:hover {
background-size: 150% 150%;
}
If you want to stick with background-size: cover; than you will have to wrap entire element inside a wrapper element having fixed dimensions with overflow: hidden; and than scale the child element on hover of parent element.
As you commented, for an img tag example, you can use transform: scale(2,2); to achieve that with the parent element set to overflow: hidden;
Demo 2
div {
height:300px;
width: 300px;
overflow: hidden;
}
div img {
-moz-transition: all .5s;
-webkit-transition: all .5s;
transition: all .5s;
-moz-transform: scale(1,1);
-webkit-transform: scale(1,1);
transform: scale(1,1);
}
div:hover img {
-moz-transform: scale(2,2);
-webkit-transform: scale(2,2);
transform: scale(2,2);
}
<script>
function animate(){
document.getElementById('a').style.webkitTransitionDuration='1s';
document.getElementById('a').style.backgroundSize="200% 200%";
}
</script>
<div id="a" onmouseover="animate()" style="width: 200px; height: 70px; border: 1px solid; background: url('http://www.wpclipart.com/food/fruit/apple/apples_4/apple_honeycrisp_small.png') no-repeat;background-size: 100% 100%; ">
</div>
You can do something like this for webkit browsers.
Demo Here

Categories