How to animate image from fixed size to fullscreen? - javascript

There is a website page which height and width are equal to 100% of the browser viewport (100vw and 100vh).
There is a high quality image (3000x2857px) inside of absolutely positioned wrapper in the center of the page. Image wrapper has max-width in pixels (e.g. 300px).
Also, the image has an overlay. I add .active class to the image wrapper by clicking on overlay. This class makes max-width of image wrapper equal to 100vw.
So, I want to animate this. I added transition to max-width, top, transform properties, but it's laggy. I know that it's due to top and max-width properties because of heavy calculations of the browser. But I don't know how to do it in other ways.
Any help would be welcome!
P.S. While I wrote this question, I found that this implementation is buggy in Safari. I think transform transition doesn't work in this browser, so it will be great if you suggest code that work in it :(
Demo: https://codepen.io/ghettojezuz/pen/ExvGwJB
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: max-width .8s ease, top .8s ease, transform .8s ease;
}
.image-wrapper.active {
max-width: 100vw;
left: 50%;
top: 0;
transform: translate(-50%, 0);
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>

One method which seems to react to transitioning well is to alter the scale rather than try to reposition and alter width etc.
This snippet keeps the image centered and calculates the scale needed to move from the initial width to 100vw.
Note: it removes margin on elements to ensure the full width of the viewport is covered.
const imageWrapper = document.querySelector('.image-wrapper');
const overlay = document.querySelector('.image-overlay');
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
function init() {
const w = window.innerWidth;
const scale = w / imageWrapper.offsetWidth;
imageWrapper.style.setProperty('--scale', scale);
}
window.onload = init;
window.onresize = init;
* {
padding: 0;
margin: 0;
}
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: .8s ease;
}
.image-wrapper.active {
transform: translate(-50%, -50%) scale(var(--scale));
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: scale .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>

So, I tried multiple things like different css properties, #keyframes animations etc. None of them worked. But I found out that when the image format is SVG, the freezing disappears. I know, not all images can be converted to SVG, but see what you can do about it.

I change the top and transform with flex, now when you click only width changes, but i guess the lag will happen sometime in transform animation case
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.img_container {
max-width:300px;
transition: .5s;
position:relative;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 0;
top: 0;
bottom:0;
right:0;
display:flex;
align-items:center;
justify-content:center;
width: 100%;
transition: .5s;
}
.image-wrapper.active .img_container {
max-width: 100vw;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<div class="img_container">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
</div>

Related

CSS Transition Direction - Can It Always Be The Same?

Here is an example: https://codepen.io/jon424/pen/XWzGNLe
I have a button here that lets you toggle the visibility of an image. When the button is clicked, the image disappears from the bottom to the top. When you click the button again, the image reappears from the top to the bottom.
I would like the transition to move in the same direction each time. So, when the user sees the image and clicks on the button, the image disappears from the bottom to the top. When the user clicks the button again, the image reappears from the bottom to the top.
Is there a way to use transitions without this kind of “alternating” activity?
HTML
<button>Toggle</button>
<div class="parent">
<img class="child1" src="https://picsum.photos/200/300">
<div class="child1 covering"></div>
</div>
CSS
.parent {
position: relative;
overflow: hidden;
width: 300px;
height: 300px;
margin: 10px;
}
.child {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.covering {
z-index: 1;
background: #fff;
transition: transform 1s ease-in-out;
transform: translateY(100%);
}
.covered {
transform: translateY(0%);
}
JS
const firstTarget = document.querySelector(".firstTarget");
const covering = document.querySelector(".covering");
document.querySelector('button').addEventListener('click', () => { document.querySelector('.covering').classList.toggle('covered');});
You can use keyframes for this, or listen to transitionend.
const btn = document.querySelector('button'),
cover = document.querySelector('.cover');
btn.addEventListener('click', ()=> {
if(cover.classList.contains('covered')){
cover.classList.add('remove_covered');
} else {
cover.classList.add('covered');
}
cover.ontransitionend = () => {
if(cover.classList.contains('remove_covered'))
cover.classList.remove('covered','remove_covered');
};
});
.child {
width: 300px;
height: 300px;
}
.parent {
position: relative;
width: 300px;
height: 300px;
}
.cover {
position: absolute;
bottom: 0;
left: 0;
height: 0;
width: 100%;
background: #fff;
transition: height 1s ease-in-out;
}
.covered {
height: 100%;
}
.remove_covered {
top: 0;
bottom: auto;
height: 0;
}
<button>Toggle</button>
<div class="parent">
<img class="child" src="https://picsum.photos/200/300">
<div class="cover"></div>
</div>
Is that what you want?
const targetClassList = document.querySelector(".image-item").classList;
document.querySelector("button").addEventListener("click", () => {
if (targetClassList.contains("open")) {
targetClassList.remove("open");
targetClassList.add("close");
} else {
targetClassList.add("open");
targetClassList.remove("close");
}
});
.parent {
position: relative;
overflow: hidden;
width: 300px;
height: 300px;
margin: 10px;
}
.child {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.image-item {
z-index: 1;
background: #fff;
}
.close {
animation: closeAni 1s forwards;
}
.open {
animation: openAni 1s forwards;
}
#keyframes openAni {
from {
transform: translateY(0);
}
to {
transform: translateY(-100%);
}
}
#keyframes closeAni {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
<button>Toggle</button>
<div class="parent">
<img class="child" src="https://picsum.photos/200/300">
<div class="child image-item"></div>
</div>

How would I mask an element with an animated overlay?

I'm trying to do some page transitions for a project I'm working on, I have an animated overlay that comes onto the screen when the user is navigating the site using Barba but I'm having an issue.
I want a logo centered on the page that rolls in with the overlay but I need it to be positioned separately from the overlay since any transform on the overlay would affect the logo as well. (I want the logo to mask with the overlay element)
What I've tried :
Switching around the Element hierarchy/Z-index (I'm sure the problem lies somewhere in here)
Trying different transforms
Messing with Max Width (Had some success but I need the transform origin property)
Example -
let transitionOpen = false;
$('.transition-cta').on("click", function() {
if (transitionOpen === false) {
$('.transition-background').css("transform", "scaleX(1)");
$(this).css("color", "white");
transitionOpen = true;
} else {
$('.transition-background').css("transform", "scaleX(0)");
$(this).css("color", "black");
transitionOpen = false;
}
});
body {
background-color: lightblue;
}
.someContent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.transition-wrapper {
overflow: hidden;
}
.transition-background {
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
transform-origin: left;
transition: 0.7s ease-in-out;
background-color: #1f1f1f;
transform: scaleX(0);
z-index: 2;
}
.transition-center {
background-image: url('https://i.imgur.com/6um9G9h.png');
z-index: 2;
width: 150px;
height: 150px;
position: absolute;
background-repeat: no-repeat;
background-size: cover;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.transition-cta {
text-decoration: underline;
cursor: pointer;
z-index: 3;
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="transition-wrapper">
<div class="transition-background"></div>
<!-- I want to clip this with the transition background -->
<div title="I only want this to show with the transition overlay" class="transition-center"></div>
</div>
<div class="transition-cta">Trigger Transition</div>
<div class="someContent">
<h1>Some Content</h1>
</div>
(The globe should roll in with the overlay)
This feels like an extremely simple problem but I'm really struggling to solve it. I can't tell if I'm burned out or this is actually as complicated as my brain is making it.
Thanks!
Use a clip-path animation instead and you can simplify your code by having the logo as background of the transition-wrapper
let transitionOpen = false;
$('.transition-cta').on("click", function() {
$('.transition-wrapper').toggleClass('show');
if (transitionOpen === false) {
$(this).css("color", "white");
transitionOpen = true;
} else {
$(this).css("color", "black");
transitionOpen = false;
}
});
body {
background-color: lightblue;
}
.someContent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.transition-wrapper {
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
transition: 0.7s ease-in-out;
background: url('https://i.imgur.com/6um9G9h.png') center/150px 150px no-repeat;
background-color: #1f1f1f;
clip-path: polygon(0 0, 0% 0, 0% 100%, 0 100%);
z-index: 3;
}
.transition-wrapper.show {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
.transition-cta {
text-decoration: underline;
cursor: pointer;
z-index: 3;
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="transition-wrapper">
</div>
<div class="transition-cta">Trigger Transition</div>
<div class="someContent">
<h1>Some Content</h1>
</div>
I would do something like:
$('.transition-cta').on("click", function() {
$('.transition-wrapper').toggleClass('opened');
$('.transition-content').animate({ width: 'toggle' }, 800);
});
body {
background: lightblue;
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.transition-content {
background-color: #1f1f1f;
display: none;
overflow: hidden;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
width: 100%;
}
.transition-cta {
position: relative;
text-decoration: underline;
z-index: 999;
}
.transition-wrapper.opened .transition-cta {
color: #fff;
}
.transition-content__inner {
width: 100vw;
}
.transition-content__inner img {
width: 150px;
height: 150px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="transition-wrapper">
<div class="transition-cta">Trigger Transition</div>
<div class="content">
<h1>Some Content</h1>
</div>
<div class="transition-content">
<div class="transition-content__inner">
<img src="https://i.imgur.com/6um9G9h.png"/>
</div>
</div>
</div>

hide nav based on scroll removing adding classes

I found a nav layout I would like to use but I seem to have run into 2 problems.
problem #1 the transitions in the css do not seem to be transitioning smooth when scrolling up or down.
problem #2 if the scroll position is not zero I do not want mainnav to shrink and i want the top nav to show or hide when i scroll up or down.. thats hard to word so what I am trying to accomplish exactly is the following
https://www.battlefield.com/games/battlefield-4/classes
now when you scroll down it hides the top nav but if you scroll just a little each way it will show or hide thats what I am trying to do.. but I dont want the 2nd nav to scale down unless the top is 0
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
$('.netnav').addClass('hide-nav');
$('.netnav').removeClass('show-nav');
$('.mainnav').addClass('scrolled');
}
else {
$('.netnav').addClass('show-nav');
$('.netnav').removeClass('hide-nav');
$('.mainnav').removeClass('scrolled');
}
});
body {
margin: 0px;
}
.hwrap {
display: block;
position: fixed;
width: 100%;
}
.netnav {
position: fixed;
height: 40px;
width: 100%;
margin: 0;
padding: 0;
background-color: blue;
z-index: 1;
}
.netnav.show-nav {
top: 0;
transition-duration: .4s;
}
.netnav.hide-nav {
transform: translate3d(0, -40px, 0);
transition-duration: .4s;
}
.mainnav {
position: fixed;
height: 68px;
z-index: 3;
background: blue;
}
.mainnav {
border-radius: 4px;
left: auto;
margin: 0 auto;
top: 50px;
position: relative;
transform: translateY(15px);
transition: transform .3s, width .3s;
width: calc(100% - 60px);
}
.mainnav.scrolled {
top: 0;
height: 60px;
border-radius: 0;
transform: translateY(0);
width: 100%;
transition: transform .3s, width .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="hwrap">
<div class="netnav">net nav</div>
<div class="mainnav">main nav</div>
</header>
<div style="height: 100vh; display: block; background-color: gold">about</div>
<div style="height: 100vh; display: block; background-color: green">about</div>
Demo
http://jsfiddle.net/gos4hwp9/52/
Explanation
Added transition: all ease-in-out .4s for smooth transitions of all properties
If scrollTop > 0 added margin: 0px and border-radius: 0px to bottom (primary) nav, Else made margin and border-radius same as initial state
If scrollDir == "down" added translateY(-50px) to header, Else removed translateY
Moving the whole header will move both navs which is nice as compared to moving them individually
I've slightly changed your transitions and added transitions to the classes which you toggle.
body {
margin: 0px;
}
.hwrap {
display: block;
position: fixed;
width: 100%;
}
.netnav {
position: fixed;
height: 40px;
width: 100%;
margin: 0;
padding: 0;
background-color: blue;
z-index: 1;
transition: .3s all;
}
.netnav.show-nav {
top: 0;
transition: .3s all;
}
.netnav.hide-nav {
transform: translate3d(0, -40px, 0);
transition: .3s all;
}
.mainnav {
position: fixed;
height: 68px;
z-index: 3;
background: blue;
}
.mainnav {
border-radius: 4px;
left: auto;
margin: 0 auto;
top: 50px;
position: relative;
transform: translateY(15px);
transition: .3s all;
width: calc(100% - 60px);
}
.mainnav.scrolled {
top: 0;
height: 60px;
border-radius: 0;
transform: translateY(0);
width: 100%;
transition: .3s all;
}
I followed the link you provided and edit the JavaScript and CSS.
Fixed the transitions in the CSS that does not seem smooth in transitioning when scrolling up or down using JavaScript.
You may visit this pen that I edited based on your snippet, and play around with it.
$(window).scroll(function(){
if ($(this).scrollTop() > 15) {
$('.netnav').addClass('hide-nav');
$('.netnav').removeClass('show-nav');
$('.mainnav').addClass('RemoveTop');
}
else {
$('.netnav').addClass('show-nav');
$('.netnav').removeClass('hide-nav');
$('.mainnav').removeClass('RemoveTop');
$('.mainnav').removeClass('scrolled');
}
});
$(window).scroll(function(){
if ($(this).scrollTop() > 50) {
$('.mainnav').addClass('scrolled');
}
else {
$('.netnav').removeClass('scrolled');
}
});
body {
margin: 0px;
}
.hwrap{
display:block;
position: fixed;
width: 100%;
}
.netnav{
position: fixed;
height: 40px;
width: 100%;
margin: 0;
padding: 0;
background-color: blue;
transition: all .3s;
z-index: 1;
}
.netnav.show-nav {
top: 0;
transition-duration: .4s;
}
.netnav.hide-nav {
transform: translate3d(0,-40px,0);
transition-duration: .4s;
}
.mainnav{
position: fixed;
height: 68px;
z-index: 3;
background: blue;
}
.mainnav {
border-radius: 4px;
left: auto;
margin: 0 auto;
top: 50px;
position: relative;
transform: translateY(15px);
transition: all .3s,width .3s;
width: calc(100% - 60px);
}
.mainnav.RemoveTop {
top: 0px;
}
.mainnav.scrolled {
height: 60px;
border-radius: 0;
transform: translateY(0);
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="hwrap">
<div class="netnav">net nav</div>
<div class="mainnav">main nav</div>
</header>
<div style="height: 100vh; display: block; background-color: gold">about</div>
<div style="height: 100vh; display: block; background-color: green">about</div>

CSS Transition Width Right to Left

I am have made a heading (the word Welcome) that reveals itself once the page has loaded (onload="").
Fiddle in case the code below doesn't work.
function animate() {
document.getElementById("mainText").style.width = "100%";
}
#mainText {
margin: 0px;
display: inline-block;
font-size: 100px;
width: 0%;
transition: width 2s;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
The CSS and Plain JS work fine but I want the word "Welcome" to be revealed right side first and then moving along, so from the e to the W, instead of how it currently is, which opens left to right.
I have tried text align: right;, but this doesn't change anything.
I preferably don't want to use any jQuery, if the solution is a JS one.
An example of what the desired look should be, half way though the transition:
You can use the clip-path property to clip parts of the element so they are not visible. This property can also be animated to reveal the element again, using the forwards keyword in the animation so it stays in it's 'revealed' end state.
The inset takes values that are in order: from-top, from-right, from-bottom, from-left.
#text {
margin: 0;
font-size: 100px;
animation: reveal 2s forwards;
}
#keyframes reveal {
from {
clip-path: inset(0 0 0 100%);
}
to {
clip-path: inset(0 0 0 0);
}
}
<h1 id="text">Welcome</h1>
Yes, it is possible using Transitions and Positions:
window.onload = function () {
document.querySelector("h1").classList.add("active");
};
h1 {
overflow: hidden;
display: inline-block;
position: relative;
}
h1 .mask {
position: absolute;
transition: all 0.5s linear;
left: 0;
top: 0;
bottom: 0;
right: 0;
background-color: #fff;
}
h1.active .mask {
right: 100%;
}
<h1><span class="mask"></span>Welcome</h1>
I just wrote an article about this - CSS Transitions & JavaScript for Animated Entry Effects. Hope it is useful... :)
One option is transform: translate with a pseudo element, and no extra element needed.
function animate() {
document.getElementById("mainText").classList.add('show');
}
#mainText {
position: relative;
margin: 0px;
display: inline-block;
font-size: 100px;
white-space: nowrap;
text-overflow: clip;
overflow: hidden;
}
#mainText::after {
content: '';
position: absolute;
left: 0; top: 0;
width: 100%; height: 100%;
background: white;
transition: transform 2s;
}
#mainText.show::after {
transform: translateX(-100%);
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
Another option, an even better solution, using the pseudo with direction and left/width.
This one work in the same way clip-path does, completely transparent against its background, as opposite to having a mask that revels the text, and with much better browser support.
function animate() {
document.getElementById("mainText").classList.add('show');
}
body {
background: black;
}
#mainText {
position: relative;
margin: 0px;
display: inline-block;
font-size: 100px;
white-space: nowrap;
color: rgba(0, 0, 0, 0);
}
#mainText::before {
content: attr(data-text);
position: absolute;
left: 100%;
top: 0;
width: 0;
height: 100%;
color: white;
direction: rtl;
overflow: hidden;
transition: left 2s, width 2s;
}
#mainText.show::before {
left: 0;
width: 100%;
}
<body onload="animate()">
<h1 id="mainText" data-text="Welcome">Welcome</h1>
</body>
Something like this
function animate() {
document.getElementById("overlay").style.width = "0%";
}
#mainText {
margin: 0px;
display: inline-block;
font-size: 100px;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
#overlay{
width: 100%;
position:absolute;
top:0;
left:0;
background:#fff;
transition: width 2s;
height:100%;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
<div id="overlay"></div>
</body>
This will require a pseudo-element with a background on top of your heading serving as a mask. Instead of altering the inline styles I will simply add a class is-active. So everything style related can be styled via CSS.
function animate() {
document.getElementById("mainText").className = "is-active";
}
#mainText {
margin: 0px;
display: inline-block;
position: relative;
font-size: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
#mainText:before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
background: #FFF;
transition: width 2s;
}
#mainText.is-active:before {
width: 0%;
}
<body onload="animate()">
<h1 id="mainText">Welcome</h1>
</body>
I use Transform: translateX to achieve the desired effect.
It slides the text sideways or horizontally on the X axis.
.message {
color: darkred;
font-size: 30px;
display: inline-block;
font-weight: 100;
font-family: sans-serif;
}
.sliding-text-1,
.sliding-text-2,
.sliding-text-3 {
animation-name: slide;
animation-duration: 1s;
animation-timing-function: ease-out;
animation-iteration-count: 1;
animation-fill-mode: forwards;
opacity: 0;
}
.sliding-text-2 {
animation-delay: 2s;
color: darkblue;
}
.sliding-text-3 {
animation-delay: 4s;
color: darkgreen;
}
#keyframes slide {
from {
transform: translateX(200px);
}
to {
transform: translateX(0px);
opacity: 1;
}
}
<h1 class="message sliding-text-1">Hello!</h1>
<h1 class="message sliding-text-2">Thanks for visiting!</h1>
<h1 class="message sliding-text-3">Have a nice day!</h1>

Hover dependant behavior of two elements : when A or B are hovered show A

here is my CodePen demo or you can run the snippet below.
In the original script, the front face of the cube is a slider, and when I hover my 'info-box' it shows the right side of it with some description (<p> an <a>).
The expected behavior is that as long as the user stays on the description, the element keeps having the .hover class given in the $('#info-box').hover() function
All was working fine until i tested it on chrome :(...
From what I understand, it seems to fires multiples mouseOver/mouseOut events when hovering and it messes and flicker everything up.
Should I use a setTimeout ?
$('.slide-info').click(function() {
$(this).parent().toggleClass('hover');
})
.hover(function() {
$(this).parent().addClass('hover');
},
function() {
$(this).parent().removeClass('hover');
});
$('.right').hover(function() {
$(this).parent().parent().addClass('hover');
},
function() {
$(this).parent().parent().removeClass('hover');
});
h1 {
text-align: center;
}
body {
background-color: #333;
}
.Cube-container {
width: 500px;
top: 20px;
height: 150px;
perspective: 1000px;
position: relative;
margin-right: auto;
margin-left: auto;
transform-origin: 50% 50% -250px;
}
.Cube {
transition: all .5s ease-out;
transform-style: preserve-3d;
backface-visibility:hidden;
}
.front,
.right {
height: 150%;
text-align: center;
padding-top: 10px;
backface-visibility: hidden;
}
.Cube-container.hover .Cube {
transform: rotateY(90deg);
transform-origin: 50% 50% -250px;
}
.front {
transform-style: preserve-3d;
transition: all .5s ease-out;
background-color: #fc8;
position: relative;
}
.right {
background-color: #8cf;
position: absolute;
top: 0px;
left: 0px;
height: calc(100% - 10px);
/* because it takes in account the padding, i guess we can do some box-sizing: border box to avoid that...*/
width: 100%;
transform: rotateY(-90deg) translateX(-100%);
transform-origin: 0 0;
}
.ol
/* OverLay */
{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.slide-info {
width: auto;
height: auto;
background-color: rgba(0, 0, 0, 0.5);
padding: 0 15px;
cursor: pointer;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Cube-container">
<div class="ol Cube">
<div class="ol right">
<h2>Right side</h2>
<p>While we hover that side, parent element keeps having the .hover class, making it visible</p>
</div>
<div class="ol front">
<h2>Front</h2>
<p>Hover the info box please :)</p>
</div>
</div>
<div class="ol slide-info">
<h3>INFO</h3>
</div>
</div>http://stackoverflow.com/questions/ask#
The problem was that I used backface-visibility: hidden on parent element. (see commented line in snippet)
Crazy but that solved my problem on Chrome browser, now everything works fine.
$('.slide-info').click(function() {
$(this).parent().toggleClass('hover');
})
.hover(function() {
$(this).parent().addClass('hover');
},
function() {
$(this).parent().removeClass('hover');
});
$('.right').hover(function() {
$(this).parent().parent().addClass('hover');
},
function() {
$(this).parent().parent().removeClass('hover');
});
h1 {
text-align: center;
}
body {
background-color: #333;
}
.Cube-container {
width: 500px;
top: 20px;
height: 150px;
perspective: 1000px;
position: relative;
margin-right: auto;
margin-left: auto;
transform-origin: 50% 50% -250px;
}
.Cube {
transition: all .5s ease-out;
transform-style: preserve-3d;
/*backface-visibility:hidden; <-- Causing the problem */
}
.front,
.right {
height: 150%;
text-align: center;
padding-top: 10px;
backface-visibility: hidden;
}
.Cube-container.hover .Cube {
transform: rotateY(90deg);
transform-origin: 50% 50% -250px;
}
.front {
transform-style: preserve-3d;
transition: all .5s ease-out;
background-color: #fc8;
position: relative;
}
.right {
background-color: #8cf;
position: absolute;
top: 0px;
left: 0px;
height: calc(100% - 10px);
/* because it takes in account the padding, i guess we can do some box-sizing: border box to avoid that...*/
width: 100%;
transform: rotateY(-90deg) translateX(-100%);
transform-origin: 0 0;
}
.ol
/* OverLay */
{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.slide-info {
width: auto;
height: auto;
background-color: rgba(0, 0, 0, 0.5);
padding: 0 15px;
cursor: pointer;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Cube-container">
<div class="ol Cube">
<div class="ol right">
<h2>Right side</h2>
<p>While we hover that side, parent element keeps having the .hover class, making it visible</p>
</div>
<div class="ol front">
<h2>Front</h2>
<p>Hover the info box please :)</p>
</div>
</div>
<div class="ol slide-info">
<h3>INFO</h3>
</div>
</div>http://stackoverflow.com/questions/ask#

Categories