I am trying to implement a 3D flip effect using two faces in IE (no preserve-3d). See this CodePen for an example: http://codepen.io/djskinner/pen/XbdPpj
The problem is that the two faces overlap at the edges. The issue is present in both Chrome and IE so I assume that there is a problem in the way I have converted this effect to take account for the lack of preserve-3d in IE. Is there a way to prevent this from occurring?
I have achieved the effect without any glitches by utilising the transform-origin property, which then allowed a simple rotation rather than having to perform rotations and translations.
Updated code pen can be found here: http://codepen.io/djskinner/pen/NqNVPx.
Inspiration taken from this code pen: http://codepen.io/jonathan/pen/xiJLn.
Here is an update of your codepen your origin's where updated and I have also added a z-index to your active state so that on hover you cant see the hidden div at the bottom of your 3d box.
hope it helps.
http://codepen.io/anon/pen/pJymRP
$('.cube').hover(function(event) {
$(this).addClass('active');
event.preventDefault();
}, function(event) {
$(this).removeClass('active');
event.preventDefault();
});
$cube-height: 100px;
$negative-half-cube-height: -0.5*$cube-height;
.cube {
border: 1px solid #000;
height: $cube-height;
margin: 0 auto;
position: relative;
width: 60%;
perspective: 1000px;
}
// The two faces of the cube
.default-state,
.active-state {
backface-visibility: visible;
height: $cube-height;
position: absolute;
left: 0;
top: 0;
transition: transform 1.5s ease;
transform-origin: center center $negative-half-cube-height;
-webkit-transform-origin: center center $negative-half-cube-height;
width: 100%;
}
// Position the faces
.default-state {
background-color: #1d92c9;
transform:perspective(1000px) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
.active-state {
transform:perspective(1000px) rotateX(90deg) rotateY(0deg) rotateZ(0deg);
}
.active {
.default-state {
transform:perspective(1000px) rotateX(-90deg) rotateY(0) rotateZ(0deg);
}
.active-state {
z-index:99999;
transform:perspective(1000px) rotateX(0deg) rotateY(0deg) rotateZ(0);
}
}
/* Demo styling */
body {
font-family: 'Montserrat', sans-serif;
font-weight: 400;
margin: 70px;
background: #f1f1f1;
}
h1 {
font-size: 20px;
text-align: center;
margin-top: 40px;
}
.cube {
text-align: center;
margin: 0 auto;
}
.default-state, .active-state {
background: #2ecc71;
font-size: 16px;
text-transform: uppercase;
color: #fff;
line-height: $cube-height;
}
.active-state {
background: darken(#2ecc71, 7%);
}
#flipto {
display: block;
text-align: center;
text-decoration: none;
margin-top: 20px;
color: #ccc;
}
<h1>3D FLIP IN IE</h1>
<div class="cube">
<div class="active-state">
<span>...and I flip</span>
</div>
<div class="default-state">
<span>Hover</span>
</div>
</div>
Related
I want to:
Align the circle (containing exclamation mark) with the dashed vertical line.
Make the circle bounce along the vertical line while changing the height of the dashed vertical line accordingly.
Can you please tell me how can I achieve that in CSS? thank in advance.
.pin{
display:inline-block;
align-contents: center;
}
.circle {
color: #ffffff;
background: #ff5500;
width: 30px;
height: 30px;
border-radius: 50%;
text-align: center;
font-size: 25px;
font-weight: bold;
display: inline-block;
animation: blinkingBackground 1s infinite;
}
#keyframes blinkingBackground {
0% {
opacity: 0;
transform: translateY(-10px);
}
25% {
opacity: 0.025;
transform: translateY(10px);
}
50% {
opacity: 0.05;
transform: translateY(-10px);
}
75% {
opacity: 0.075;
transform: translateY(10px);
}
100% {
opacity: 1;
}
}
.vline{
border-left: 1px dashed orangered;
height: 50px;
position: relative;
}
<div class="pin">
<div class="circle">
!
</div>
<div class="vline"></div>
</div>
#1 Align circle with line
For your .vline class add those two properties. Width in order to have the one pixel width from your border. And margin: 0 auto will center your div inside the parent div.
width: 1px;
margin: 0 auto;
#2 Reduce height while bouncing
Just add another animation to your .vline class.
In the example below I also changed the height from 50px to 0, that's keeping the .vline at zero pixels after animation is done. And instead I'm setting at keyframe 0% the height to 50px.
Depending on how many pixels you want to reduce it, you will need more keyframes. In the example I've reduced the height by 10px per second, so I have 5 keyframes with 10px steps.
#keyframes reduceHeight {
0% {
height: 50px;
}
20% {
height: 40px;
}
40% {
height: 30px;
}
60% {
height: 20px;
}
80% {
height: 10px;
}
100% {
height: 0px;
}
}
And here the working example
.pin{
display:inline-block;
align-contents: center;
}
.circle {
color: #ffffff;
background: #ff5500;
width: 30px;
height: 30px;
border-radius: 50%;
text-align: center;
font-size: 25px;
font-weight: bold;
display: inline-block;
animation: blinkingBackground 1s infinite;
}
.vline{
width: 1px;
margin: 0 auto;
border-left: 1px dashed orangered;
height: 0;
position: relative;
animation: reduceHeight 5s;
}
#keyframes blinkingBackground {
0% {
opacity: 0;
transform: translateY(-10px);
}
25% {
opacity: 0.025;
transform: translateY(10px);
}
50% {
opacity: 0.05;
transform: translateY(-10px);
}
75% {
opacity: 0.075;
transform: translateY(10px);
}
100% {
opacity: 1;
}
}
#keyframes reduceHeight {
0% {
height: 50px;
}
20% {
height: 40px;
}
40% {
height: 30px;
}
60% {
height: 20px;
}
80% {
height: 10px;
}
100% {
height: 0px;
}
}
<div class="pin">
<div class="circle">
!
</div>
<div class="vline"></div>
</div>
It's not perfect yet and you'll have to play around with positionings (maybe even have to add them to the animations), depending on what exactly you wanna acchieve. But it should give you a general idea and ONE possibility on how to do it. There might be different methods to do the same.
I have a heading text and a button below it. When I hover on button, the text into the heading and the button is shaking. I fixed it with the css property backface-visibility and then the text into the elements was blurred. How to solve this problem without the blurry effect ?
e.g. https://codepen.io/yozhikk/pen/odJVeY
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 1.7;
color: #777777;
padding: 30px;
}
.header {
position: relative;
height: 95vh;
background-image: linear-gradient( to right bottom, rgba(126, 213, 111, 0.8), rgba(40, 180, 131, 0.8)), url(../img/hero.jpg);
background-size: cover;
background-position: top;
clip-path: polygon( 0% 0%, 0% 100%, 100% 75vh, 100% 0%)
}
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
.heading-primary {
color: #ffffff;
text-transform: uppercase;
margin-bottom: 60px;
-webkit-backface-visibility: hidden;
-webkit-transform: translateZ(0) scale(1.0, 1.0);
}
.heading-primary-main {
font-weight: 400;
font-size: 60px;
letter-spacing: 35px;
display: block;
animation: moveInLeft 1.5s ease-out
}
.heading-primary-sub {
font-weight: 700;
font-size: 20px;
letter-spacing: 17.4px;
display: block;
animation: moveInRight 1.5s ease-out
}
.text-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.btn:link,
.btn:visited {
text-decoration: none;
text-transform: uppercase;
display: inline-block;
border-radius: 100px;
padding: 15px 40px;
transition: all .2s;
-webkit-backface-visibility: hidden;
-webkit-transform: translateZ(0) scale(1.0, 1.0);
}
.btn:hover {
transform: translateY(-3px);
}
.btn:active {
transform: translateY(-1px);
}
.btn {}
.btn-white {
background-color: #fff;
color: #777777;
}
#keyframes moveInLeft {
0% {
opacity: 0;
transform: translateX(-100px)
}
80% {
transform: translateX(10px)
}
100% {
opacity: 1;
transform: translate(0)
}
}
#keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100px)
}
80% {
transform: translateX(-10px)
}
100% {
opacity: 1;
transform: translate(0)
}
}
<header class="header">
<div class="logo-box">
<img src="img/logo-white.png" alt="" class="logo">
</div>
<div class="text-box">
<h1 class="heading-primary">
<span class="heading-primary-main">outdoors</span>
<span class="heading-primary-sub">is where live happens</span>
</h1>
Discover our tours
</div>
Remove these lines:
.btn:hover {
transform: translateY(-3px);
}
.btn:active {
transform: translateY(-1px);
}
They move the button up on hover / active for no apparent reason, which I assume is the shaking you are talking about. So just not doing that should fix it.
Give the same property you added to the hover state to the initial state but make it invisible. If you give the hover state (border : 2px solid and pink;) add it in the initial state but you can make the color transparent( border: 3px solid transparent;) so it won't show before hovering on it
After translating an element in CSS it's transformation origin stays in it's original location. In this particular case I want the transformation origin to stay centered relative to the element during all transforms. I want the origin to sort of follow the element being transformed. I know about the transform-origin property but that seems to require me to manually move the origin with the element each time...And even if I could do that in JavaScript, it seems very math heavy and not intuitive.
The animation below behaves exactly as intended except for the last wide rotation. I want that last rotation to revolve around the center of the actual element. Not it's original location. How can I move the transform origin back to the center of this element. Ideas?
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #fdfdfd;
color: #aaa;
font-family: Arial, 'sans-serif';
font-size: 0.8rem;
letter-spacing: 0.1rem;
}
.tri {
width: 0;
height: 0;
border-left: 1rem solid transparent;
border-right: 1rem solid transparent;
border-bottom: 1rem solid #555;
transform: scaleY( 2 );
border-radius: 50%;
}
.status, .instr {
position: absolute;
}
.status {
top: 0;
}
.instr {
bottom: 0;
}
<head>
<style>
.tri-bx {
animation-name: start;
animation-duration: 5s;
animation-iteration-count: infinite;
}
#keyframes start {
0% {
transform: rotate( 0deg );
}
33% {
transform: rotate( 315deg );
}
66% {
transform: rotate( 315deg ) translate( 0, -5rem );
}
100% {
transform: rotate( 720deg ) translate( 0, -5rem );
}
}
</style>
</head>
<body>
<div class="tri-bx">
<div class="tri"></div>
</div>
</body>
Resetting the transform origin, as you say is hard
However, you can keep adding transforms on the right side, with the previous ones unchanged, and you'll get what you want.
(As a side note, in a snippet you don't need the body element in the HTML, and the styles are better placed in the CSS editor.)
.tri-bx {
animation-name: start;
animation-duration: 5s;
animation-iteration-count: infinite;
}
#keyframes start {
0% {
transform: rotate( 0deg);
}
33% {
transform: rotate( 315deg);
}
66% {
transform: rotate( 315deg) translate( 0, -5rem) rotate(0deg);
}
100% {
transform: rotate( 315deg) translate( 0, -5rem) rotate( 405deg);
}
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #fdfdfd;
color: #aaa;
font-family: Arial, 'sans-serif';
font-size: 0.8rem;
letter-spacing: 0.1rem;
}
.tri {
width: 0;
height: 0;
border-left: 1rem solid transparent;
border-right: 1rem solid transparent;
border-bottom: 1rem solid #555;
transform: scaleY( 2);
border-radius: 50%;
}
.status,
.instr {
position: absolute;
}
.status {
top: 0;
}
.instr {
bottom: 0;
}
<div class="tri-bx">
<div class="tri"></div>
</div>
I'm trying to add a new hover effect to my menu, I'm mocking it up in HTML/CSS here:
https://codepen.io/anon/pen/dWOBNG
HTML
<ul>
<li class="cube" >
<a href="#">
<span class="flippety">
flip
</span>
<span class="flop">
flop
</span>
</a>
</li>
</ul>
CSS
/* Set-up */
body {
color: rgb(6, 106, 117);
text-transform: uppercase;
font-family: sans-serif;
font-size: 100%;
background: #e3e3e3;
padding: 3em 0 0 0;
line-height: 60px;
-webkit-perspective: 1000px; /* <-NB */
}
/* Container box to set the sides relative to */
.cube {
width: 30%;
text-align: center;
margin: 0 auto;
height: 60px;
display: block;
-webkit-transition: -webkit-transform .75s;
transition: transform .75s; /* Animate the transform properties */
background-color: red;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d; /* <-NB */
}
/* The two faces of the cube */
.flippety,.flop {
border: 1px solid rgba(147, 184, 189, .8);
display: block;
}
/* Position the faces */
.flippety {
-webkit-transform: translateZ(30px);
transform: translateZ(30px);
background-color: green;
}
.flop {
-webkit-transform: rotateX(-90deg) translateZ(-30px);
transform: rotateX(-90deg) translateZ(-30px);
background-color: yellow;
}
/* Rotate the cube */
.cube:hover {
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg); /* Text bleed at 90ยบ */
}
The issue is that it's transforming before I actually hover over the element itself as you can see here:
.gif of the problem
I'm struggling to work out why exactly...
I think it may be something to do with the 2 span tags wanting to "stack" on top of each other but I can't see another way round this.
Any help would be appreciated.
Thanks
I changed the cube class to the tag.
My bad, this solved it perfectly.
body {
color: rgb(6, 106, 117);
text-transform: uppercase;
font-family: sans-serif;
font-size: 100%;
background: #e3e3e3;
padding: 3em 0 0 0;
line-height: 60px;
-webkit-perspective: 1000px;
}
.cube {
width: 30%;
text-align: center;
margin: 0 auto;
height: 60px;
display: block;
-webkit-transition: -webkit-transform .75s;
transition: transform .75s;
background-color: red;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d; /* <-NB */
}
.cube a {
display: block;
text-decoration: none;
height: 60px;
}
.flippety,.flop {
display: block;
color: #FFF;
}
.flippety {
-webkit-transform: translateZ(30px);
transform: translateZ(30px);
background-color: green;
}
.flop {
-webkit-transform: rotateX(-90deg) translateZ(-30px);
transform: rotateX(-90deg) translateZ(-30px);
background-color: yellow;
color: #000;
}
.cube:hover {
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
}
<ul>
<li class="cube" >
<a href="#">
<span class="flippety">
flip
</span>
<span class="flop">
flop
</span>
</a>
</li>
</ul>
I'm attempting to make a div appear by having it hidden forced via rotate and backface-visibility. The issue is that it is flickering and then disappears after a second. This happens on Chrome. On IE11 it is not appearing at all...
http://jsfiddle.net/1xq96btg/
It's working fine on Firefox.
EDIT: I'm using just backface-visibilty on its own as when I included its variants it became even more unstable and strange behaving.
EDIT 2: z-index doesn't seem to be helping either.
HTML
<div class="one-third-box" onclick="location.href='#'">
<div class="overlay"></div>
<img src="http://www.example.com/image/jpg" />
<div class="box-description">this is a test description</div>
</div>
CSS
.one-third-box {
float: left;
margin-bottom: 2px;
margin-right: 0.2%;
width: 33.2%;
position:relative;
perspective: 1000;
cursor:pointer;
}
.one-third-box:hover {
transform: rotateY(180deg);
transition: 0.6s;
transform-style: preserve-3d;
}
.one-third-box:hover img {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter:"FlipH";
position:relative;
top:-1px;
}
.one-third-box:hover .overlay {
backface-visibility: hidden;
}
.box-description {
backface-visibility: hidden;
background: none repeat scroll 0 0 #2f5d70;
bottom: 0;
color: #fff;
font-size: 18px;
font-weight: lighter;
height: 38%;
padding-left: 10%;
padding-top: 6%;
position: absolute;
transform: rotateY(-180deg);
width: 100%;
padding-right: 10%;
}
.overlay {
position:absolute;
width:100%;
height:100%;
background:url('images/overlay.png');
}
.one-third-box > img {
width: 100%;
}
I got it to work by changing the CSS a bit...okay, a lot.
I'm assuming that this was being caused by inconsistent hardware acceleration between the overlapping elements and/or that transform-style: preserve-3d; line. Either way, I've created a snippet that seems to work for me. I also chose to go with a CSS animation instead of a transition because it just makes it that much more readable in this case.
* { margin: 0; padding: 0; } /* Simple CSS reset */
.one-third-box {
position: relative;
display: inline-block;
cursor: pointer;
width: 33.2%;
}
.one-third-box > img {
transform-style: flat;
width: 100%;
transform: translate3d(0,0,0); /* Fixes blur from scaling */
}
.box-description {
position: absolute;
box-sizing: border-box;
backface-visibility: hidden;
background: none repeat scroll 0 0 #2f5d70;
bottom: 0;
color: #fff;
font-size: 18px;
font-weight: lighter;
height: 38%;
padding-left: 10%;
padding-top: 6%;
width: 100%;
padding-right: 10%;
transform: rotateY(-180deg);
}
/* ---------------------- Hover effects ---------------------- */
.one-third-box:hover > img,
.one-third-box:hover > .box-description {
-webkit-animation: flip 0.6s;
animation: flip 0.6s;
transform: rotateY(0deg);
}
/* flip animation */
#-webkit-keyframes flip {
from { transform: rotateY(180deg); }
to { transform: rotateY(0deg); }
}
#keyframes flip {
from { transform: rotateY(180deg); }
to { transform: rotateY(0deg); }
}
<div class="one-third-box" onclick="location.href='#'">
<div class="overlay"></div>
<img src="http://www.surgemedia.ie/portfolio-images/alci-clear.png" />
<div class="box-description">this is a test description</div>
</div>