I am struggling to get direction-aware hover and css transitions to work properly. Basically I am trying to have a grid of elements with a front and back face, and when on hover have a css transition to flip that element to show the back face.
Transition example (without direction-aware): fiddle
As you can see, no matter which way your mouse enters an element it always flips up. I want it to flip whichever way the mouse enters in/out.
Example:
And here is my attempt with direction-aware: fiddle
I am using jQuery to add classes relevant to the mouse in/out direction.
.hover-in-top {}
.hover-in-right {}
.hover-in-bottom {}
.hover-in-left {}
.hover-out-top {}
.hover-out-right {}
.hover-out-bottom {}
.hover-out-left {}
As you can see from the direction-aware example it kind of works but there are major glitches which I can't get my head round. (I've been overthinking this and my brain has just imploded.)
Anyway I hope this makes sense. Thanks.
I have a partial solution to your question.
But I needed to change some of the transitions to animations
$('.box-container .box').each(function() {
$(this).on('mouseenter mouseleave', function(e) {
var $this = $(this),
width = $this.width(),
height = $this.height();
var x = (e.pageX - $this.offset().left - (width / 2)) * (width > height ? (height / width) : 1),
y = (e.pageY - $this.offset().top - (height / 2)) * (height > width ? (width / height) : 1);
// top = 0, right = 1, bottom = 2, left = 3
var dir_num = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4,
directions = ['top', 'right', 'bottom', 'left'];
// If mouse enter
if (e.type === 'mouseenter') {
// Remove all hover out classes
$this.removeClass(function(index, css) {
return (css.match(/(^|\s)hover-out-\S+/g) || []).join(' ');
});
// Add in direction class
$this.addClass('hover-in-' + directions[dir_num]);
}
// If mouse leave
if (e.type === 'mouseleave') {
// Remove all hover in classes
$this.removeClass(function(index, css) {
return (css.match(/(^|\s)hover-in-\S+/g) || []).join(' ');
});
// Add out direction class
$this.addClass('hover-out-' + directions[dir_num]);
}
});
});
* {
box-sizing: border-box;
}
.box-container {
padding: 20px;
width: 600px;
}
.box-container:after {
content: '';
display: block;
clear: both;
}
.box-container .box {
float: left;
width: 50%;
height: 200px;
position: relative;
perspective: 600px;
border: 1px solid transparent;
}
.box-container .box .front, .box-container .box .back {
float: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
backface-visibility: hidden;
transition: all 1s ease-in-out;
color: white;
font-size: 60px;
}
.box-container .box .front {
background: blue;
transform: rotateX(0) rotateY(0);
z-index: 900;
}
.box-container .box .back {
background: red;
z-index: 800;
}
.box-container .box:hover .front {
z-index: 900;
}
.box-container .box:hover .back {
z-index: 1000;
transform: rotateX(180) rotateY(0);
}
.box-container .box.hover-in-top .front,
.box-container .box.hover-out-bottom .back {
transform: rotateX(-179deg) rotateY(0);
}
.box-container .box.hover-in-top .back,
.box-container .box.hover-out-bottom .front {
animation: Xminus 1s ease-in-out;
}
#keyframes Xminus {
from {transform: rotateX(179deg) rotateY(0);}
to {transform: rotateX( 0deg) rotateY(0);}
}
.box-container .box.hover-in-bottom .front,
.box-container .box.hover-out-top .back {
transform: rotateX(179deg);
}
.box-container .box.hover-in-bottom .back,
.box-container .box.hover-out-top .front {
animation: Xplus 1s ease-in-out;
}
#keyframes Xplus {
from {transform: rotateX(-179deg) rotateY(0);}
to {transform: rotateX( 0deg) rotateY(0);}
}
.box-container .box.hover-in-right .front,
.box-container .box.hover-out-left .back {
transform: rotateY(-179deg);
}
.box-container .box.hover-in-right .back,
.box-container .box.hover-out-left .front {
animation: Yminus 1s ease-in-out;
}
#keyframes Yminus {
from {transform: rotateX(0deg) rotateY(179deg);}
to {transform: rotateX(0deg) rotateY( 0deg);}
}
.box-container .box.hover-in-left .front,
.box-container .box.hover-out-right .back {
transform: rotateY(179deg);
}
.box-container .box.hover-in-left .back,
.box-container .box.hover-out-right .front {
animation: Yplus 1s ease-in-out;
}
#keyframes Yplus {
from {transform: rotateX(0deg) rotateY(-179deg);}
to {transform: rotateX(0deg) rotateY( 0deg);}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-container">
<div class="box">
<div class="front">FRONT</div>
<div class="back">BACK</div>
</div>
<div class="box">
<div class="front">FRONT</div>
<div class="back">BACK</div>
</div>
<div class="box">
<div class="front">FRONT</div>
<div class="back">BACK</div>
</div>
<div class="box">
<div class="front">FRONT</div>
<div class="back">BACK</div>
</div>
</div>
The problem with animations if that if you leave the div before the animation has ended, the animation will break
But if move slowly, and stay on the divs until the animation ends, this will work ok.
I hope that somebody finds a better solution
I believe that the best way to approach the problem is not to use CSS transitions.
You can easily implement it using jQuery's animate, utilizing jQuery animations queue to keep all of your animations synced.
I modified your example to animate the transition in JavaScript.
Code example
Related
Hello and thank you in advance for reading my question.
GOAL: Set image so that once it's scrolled into view it transitions smoothly into a set position - but still reacts to :hover. Using #keyframes and a little JavaScript, I set the image to opacity: 0 and it's final opacity to opacity: .85. Then I added a hover effect in CSS to make it's opacity: 1
The issue is once it's finished with it's transition - it disappears - reverting to it's original opacity which is zero. I managed to make it freeze at .85 with animation-fill-mode: forwards, rather than animation-fill-mode: none, but then it won't respond to :hover
And here's a test snippet of the problem in action:
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
animation: center_img 1s 0.5s none;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1;
transform: scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem);
}
100% {
transform: translateY(0);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
If I could get a hand with this that would be wonderful, I'm a bit of a beginner and have already spent a few hours on this, all feedback welcome. Thank you very much.
Solution 1
To understand why the hover effect was not working with the animation-fill-mode: forwards, read this answer.
You can fix that by adding !important property to the hover styles:
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
The problem, in this case, is that the transition will not work for hover.
Solution 2
You could remove the animation entirely and add the final state styles to the shift_frame_center_img class.
But you would still need to use the !important property because of the CSS Specificity.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
transform: translateY(20rem);
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
transform: none !important;
opacity: .85 !important;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
This snippet removes the need for fill-mode forwards by setting the img to have opacity 1 as its initial state so it will revert to that at the end of the animation.
The animation itself is altered to take 1.5s rather than 1s with the first third simply setting the img opacity to 0 so it can't be seen. This gives the delay effect.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
opacity: 1;
}
/* APPEND-CHILD */
.features-img-wrapper img {
animation: center_img 1.5s 0s none;
}
/* CHILD ON HOVER */
.shift_frame_center_img:hover {
opacity: 1;
transform: translateY(0) scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
33.33% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
100% {
transform: translateY(0) scale(1);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
Note: as each transform setting will reset anything that isn't included both tranlateY and scale are included in each setting.
Outside the SO snippet system it was possible to leave the animation settings untouched by chaining another animation to the front which ran for 0.5s and just set the img to opacity: 0. This did not work in the snippet system (it got into a loop of flashing on and off) hence the introduction of one but extended animation.
I'm trying to make my marquee text continuous, but can't figure out how too. This is what I've right now in my HTML:
.marquee2 {
position: relative;
overflow: hidden;
--offset: 20vw;
--move-initial: calc(-20% + var(--offset));
--move-final: calc(-40% + var(--offset));
}
.marquee__inner2 {
width: fit-content;
display: flex;
position: relative;
transform: translate3d(var(--move-initial), 0, 0);
animation: marquee 12s linear infinite;
animation-play-state: play;
color: #1a1a1a;
font-family: 'Noctis Bold';
}
.marquee2 span {
font-size: 5vh;
padding: 0 2vw;
}
.marquee2:hover .marquee__inner2 {
animation-play-state: paused;
}
#keyframes marquee2 {
0% {
transform: translate3d(var(--move-initial), 0, 0);
}
100% {
transform: translate3d(var(--move-final), 0, 0);
}
}
<div class="bg33">
<div class="marquee2" id="showScroll2">
<div class="marquee__inner2" aria-hidden="true">
<span>HTML</span>
<span>CSS</span>
<span>SASS</span>
<span>JAVASCRIPT</span>
<span>JQUERY</span>
<span>VUE.JS</span>
<span>PYTHON</span>
<span>JAVA</span>
<span>REACT</span>
<span>GIT</span>
<span>NPM</span>
<span>RSTUDIO</span>
<span>JIRA</span>
<span>AGILE</span>
<span>FIGMA</span>
<span>PS</span>
<span>ILLUSTRATOR</span>
<span>BALSAMIQ</span>
</div>
</div>
</div>
The text doesn't seem to be continuous and it break and starts off again, which is annoying and doesn't show all the text. I want this text to loop over to see appears continuous and full for viewing by the audience. Can anyone help me with this?
A simple way of doing this - if you know the text will at least cover the viewport width - is to have a second copy. Then you animate by moving the whole thing left by half its width and starting again.
Here's the altered snippet, note you don't need initial setup conditions to center anything.
.marquee2 {
position: relative;
overflow: hidden;
--offset: 20vw;
--move-initial: calc(-20% + var(--offset));
--move-final: calc(-40% + var(--offset));
}
.marquee__inner2 {
width: fit-content;
display: flex;
position: relative;
transform: translate3d(0, 0, 0);
animation: marquee2 12s linear infinite;
animation-play-state: play;
color: #1a1a1a;
font-family: 'Noctis Bold';
}
.marquee2 span {
font-size: 5vh;
padding: 0 2vw;
}
.marquee2:hover .marquee__inner2 {
animation-play-state: paused;
}
#keyframes marquee2 {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-50%, 0, 0);
}
<div class="bg33">
<div class="marquee2" id="showScroll2">
<div class="marquee__inner2" aria-hidden="true">
<span>HTML</span>
<span>CSS</span>
<span>SASS</span>
<span>JAVASCRIPT</span>
<span>JQUERY</span>
<span>VUE.JS</span>
<span>PYTHON</span>
<span>JAVA</span>
<span>REACT</span>
<span>GIT</span>
<span>NPM</span>
<span>RSTUDIO</span>
<span>JIRA</span>
<span>AGILE</span>
<span>FIGMA</span>
<span>PS</span>
<span>ILLUSTRATOR</span>
<span>BALSAMIQ</span>
<span>HTML</span>
<span>CSS</span>
<span>SASS</span>
<span>JAVASCRIPT</span>
<span>JQUERY</span>
<span>VUE.JS</span>
<span>PYTHON</span>
<span>JAVA</span>
<span>REACT</span>
<span>GIT</span>
<span>NPM</span>
<span>RSTUDIO</span>
<span>JIRA</span>
<span>AGILE</span>
<span>FIGMA</span>
<span>PS</span>
<span>ILLUSTRATOR</span>
<span>BALSAMIQ</span>
</div>
</div>
</div>
Looking to use just Javascript without any libraries to start and stop audio on mouse enter and mouse leave. Also want the audio to loop while the div is being hovered. Right now I have two divs because I'm unsure of how to add multiple onmouseenter events and if this is even possible. Is all of this possible? Dropping my code snippet below.
document.addEventListener("mousemove", function(){
myFunction(event);
});
var mouse;
var cursor = document.getElementById("cursor");
function myFunction(e){
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX-55) + "px";
cursor.style.top = (mouseY-55) + "px";
}
function play() {
var audio = new Audio('https://www.figurefoundry.xyz/metal/metaldrums.mp3');
audio.play();
}
body {
background: #fffdfa;
}
#cursor {
height: 100px;
width: 100px;
position: absolute;
backface-visibility: hidden;
z-index: 9999999;
pointer-events: none; /* pointer-events: none is needed */
cursor: none;
animation: spincursor infinite 1.5s steps(1, end);
}
div {
background: black;
width: 200px;
height: 100px;
margin: 30px;
cursor: none;
}
#keyframes spincursor {
0% {
transform: rotate(0deg);
}
12.5% {
transform: rotate(45deg);
}
25% {
transform: rotate(90deg);
}
37.5% {
transform: rotate(135deg);
}
50% {
transform: rotate(180deg);
}
62.5% {
transform: rotate(225deg);
}
75% {
transform: rotate(270deg);
}
87.5% {
transform: rotate(315deg);
}
100% {
transform: rotate(360deg);
}
}
<img src="https://www.figurefoundry.xyz/metal-cursor.svg" id="cursor" hidden></img>
<div onmouseenter="play()">
<div onmouseenter="cursor.hidden = false" onmouseleave="cursor.hidden=true">
</div> <!--make cursor invisible on leave and visible on enter-->
</div>
I think you're going to get an error in console if you do this in Chrome: Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first You need to interact ( click) something for audio to be played .
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
I face quite big stuck while studying CSS animation.
I'm going to make a "transform: translate" animation which shows text that overflow content width like below situation.
How it works?: (Youtube video link)
var div1 = document.getElementById("div1");
var cont = document.getElementById("content");
var inf = document.getElementById("inf");
inf.innerHTML = "<p> Does the text inside h1 cut off? : " + (cont.offsetWidth < cont.scrollWidth) +
"<br><b>Length of text overflow</b>: " + (cont.offsetWidth - cont.scrollWidth) +
"<br> h1 width: " + (cont.offsetWidth) + ", h1's text length: " + (cont.scrollWidth) + "</p>";
div1.style.backgroundColor = "#A13DAF";
cont.style.webkitAnimationName = "moving";
cont.style.animationName = "moving";
cont.style.animationDuration = "3s";
cont.style.webkitAnimationDuration = "3s";
cont.style.animationTimingFunction = "linear";
cont.style.webkitAnimationTimingFunction = "linear";
#div1 {
margin: 10px;
width: 300px;
background: rgb(40, 40, 40);
white-space: nowrap;
overflow: hidden;
}
#content {
color: white;
width: 100%;
/* animation-name: moving;
animation-duration: 3s;
animation-timing-function: linear;
-webkit-animation-name: moving;
-webkit-animation-duration: 3s;
-webkit-animation-timing-function: linear; */
}
#keyframes moving {
0% {
transform: none;
-webkit-transform: none;
}
65% {
/*below code is pseudo code, It doesn't work,
It is an explanation of the direction I want but.. I can't find way to ...ㅠㅠ*/
transform: translate( calc(#content.scrollWidth - #content.offsetWidth), 0);
-webkit-transform: translate( calc(#content.scrollWidth - #content.offsetWidth), 0);
/*below value is caculated value of fixed text length and content width,
but if either of these changes, this code will not be available for my purpose.
Is there any way to specific values of CSS elements?*/
transform: translate( -668px, 0);
-webkit-transform: translate( -668px, 0);
}
100% {
transform: translate( -668px, 0);
-webkit-transform: translate( -668px, 0);
}
}
<div id="div1">
<h1 id="content">
The only thing that matters now is everything You think of me
</h1>
</div>
<div id="inf"></div>
Like Above code,
I want to make the text to move left in the content (h1), as much as the amount of the cut off cause of its overflow.
But, I can't find a way to refer values of content in CSS.
Is there any way to modify a CSS value by referring to a specific value of another element in the CSS without JavaScript?
I try to avoid the method of changing the keyframe using Javascript as much as possible, though it can be quite heavy.
Thank you very much.
You could animate both transform and simultaneously the margin-left so that the animation will end exactly at the text-end:
.marquee {
position: relative;
overflow: hidden;
background: rgb(161, 61, 175);
color: #fff;
}
.marquee span {
display: inline-block;
min-width: 100%; /* this is to prevent shorter text animate to right */
white-space: nowrap;
font-size: 2.5em;
animation: marquee 4s ease-in-out forwards;
}
#keyframes marquee {
from {transform: translateX(0); margin-left: 0;}
to {transform: translateX(-100%); margin-left: 100%; }
}
<h1 class="marquee">
<span>The only thing that matters now is everything You think of me</span>
</h1>
<p class="marquee">
<span>Beware of short texts!</span>
</p>
Here is another idea with only transform used as animation:
.marquee {
overflow: hidden;
background: rgb(161, 61, 175);
color: #fff;
}
.marquee > span {
display:block;
animation: marquee 4s ease-in-out;
transform: translateX(100%);
}
.marquee > * > span {
display: inline-block;
min-width: 100%;
white-space: nowrap;
font-size: 2.5em;
animation:inherit;
transform: translateX(-100%);
}
#keyframes marquee {
from {
transform: translateX(0);
}
}
<h1 class="marquee">
<span>
<span>The only thing that matters now is everything You think of me</span>
</span>
</h1>
<h1 class="marquee">
<span>
<span>The only thing that matters now is everything</span>
</span>
</h1>
<p class="marquee">
<span>
<span>Beware of short texts!</span>
</span>
</p>
I found this neat smooth scrolling background snippet and I tweeked it a bit.
What I'm trying to accomplish is have these three scrolling backgrounds in the beginning and then after the last one is done, my other div's on the page will show. In my example, no matter what information you put at the bottom of the div or above it, the background hides it all.
If there's an easier way to accomplish this type of smooth scrolling, that'd be great, but I haven't found one quite like this one.
https://jsfiddle.net/jzhang172/xwqsxeff/
$(function(){
// ------------- VARIABLES ------------- //
var ticking = false;
var isFirefox = (/Firefox/i.test(navigator.userAgent));
var isIe = (/MSIE/i.test(navigator.userAgent)) || (/Trident.*rv\:11\./i.test(navigator.userAgent));
var scrollSensitivitySetting = 30; //Increase/decrease this number to change sensitivity to trackpad gestures (up = less sensitive; down = more sensitive)
var slideDurationSetting = 600; //Amount of time for which slide is "locked"
var currentSlideNumber = 0;
var totalSlideNumber = $(".background").length;
// ------------- DETERMINE DELTA/SCROLL DIRECTION ------------- //
function parallaxScroll(evt) {
if (isFirefox) {
//Set delta for Firefox
delta = evt.detail * (-120);
} else if (isIe) {
//Set delta for IE
delta = -evt.deltaY;
} else {
//Set delta for all other browsers
delta = evt.wheelDelta;
}
if (ticking != true) {
if (delta <= -scrollSensitivitySetting) {
//Down scroll
ticking = true;
if (currentSlideNumber !== totalSlideNumber - 1) {
currentSlideNumber++;
nextItem();
}
slideDurationTimeout(slideDurationSetting);
}
if (delta >= scrollSensitivitySetting) {
//Up scroll
ticking = true;
if (currentSlideNumber !== 0) {
currentSlideNumber--;
}
previousItem();
slideDurationTimeout(slideDurationSetting);
}
}
}
// ------------- SET TIMEOUT TO TEMPORARILY "LOCK" SLIDES ------------- //
function slideDurationTimeout(slideDuration) {
setTimeout(function() {
ticking = false;
}, slideDuration);
}
// ------------- ADD EVENT LISTENER ------------- //
var mousewheelEvent = isFirefox ? "DOMMouseScroll" : "wheel";
window.addEventListener(mousewheelEvent, _.throttle(parallaxScroll, 60), false);
// ------------- SLIDE MOTION ------------- //
function nextItem() {
var $previousSlide = $(".background").eq(currentSlideNumber - 1);
$previousSlide.removeClass("up-scroll").addClass("down-scroll");
}
function previousItem() {
var $currentSlide = $(".background").eq(currentSlideNumber);
$currentSlide.removeClass("down-scroll").addClass("up-scroll");
}
});
html, body {
overflow: hidden;
}
.background {
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
overflow: hidden;
will-change: transform;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
height: 130vh;
position: fixed;
width: 100%;
-webkit-transform: translateY(30vh);
-ms-transform: translateY(30vh);
transform: translateY(30vh);
-webkit-transition: all 1.2s cubic-bezier(0.22, 0.44, 0, 1);
transition: all 1.2s cubic-bezier(0.22, 0.44, 0, 1);
}
.background:before {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(15, 23, 84, 0.32);
}
.background:first-child {
background-image: url(http://s8.postimg.org/lf2udl5np/4_Aihmii.jpg);
-webkit-transform: translateY(-15vh);
-ms-transform: translateY(-15vh);
transform: translateY(-15vh);
}
.background:first-child .content-wrapper {
-webkit-transform: translateY(15vh);
-ms-transform: translateY(15vh);
transform: translateY(15vh);
}
.background:nth-child(2) {
background-image: url(http://s8.postimg.org/ow4wgk4px/ugqti_Lg.jpg);
}
.background:nth-child(3) {
background-image: url(http://s8.postimg.org/grwsbtiat/x_ZMOBTj.jpg);
}
/* Set stacking context of slides */
.background:nth-child(1) {
z-index: 3;
}
.background:nth-child(2) {
z-index: 2;
}
.background:nth-child(3) {
z-index: 1;
}
.content-wrapper {
height: 100vh;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
-webkit-flex-flow: column nowrap;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
color: #fff;
font-family: Montserrat;
font-family: 'Libre Baskerville', serif;
text-transform: uppercase;
-webkit-transform: translateY(40vh);
-ms-transform: translateY(40vh);
transform: translateY(40vh);
will-change: transform;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: all 1.7s cubic-bezier(0.22, 0.44, 0, 1);
transition: all 1.7s cubic-bezier(0.22, 0.44, 0, 1);
}
.content-title {
font-size: 12vh;
line-height: 1.4;
}
.background.up-scroll {
-webkit-transform: translate3d(0, -15vh, 0);
transform: translate3d(0, -15vh, 0);
}
.background.up-scroll .content-wrapper {
-webkit-transform: translateY(15vh);
-ms-transform: translateY(15vh);
transform: translateY(15vh);
}
.background.up-scroll + .background {
-webkit-transform: translate3d(0, 30vh, 0);
transform: translate3d(0, 30vh, 0);
}
.background.up-scroll + .background .content-wrapper {
-webkit-transform: translateY(30vh);
-ms-transform: translateY(30vh);
transform: translateY(30vh);
}
.background.down-scroll {
-webkit-transform: translate3d(0, -130vh, 0);
transform: translate3d(0, -130vh, 0);
}
.background.down-scroll .content-wrapper {
-webkit-transform: translateY(40vh);
-ms-transform: translateY(40vh);
transform: translateY(40vh);
}
.background.down-scroll + .background:not(.down-scroll) {
-webkit-transform: translate3d(0, -15vh, 0);
transform: translate3d(0, -15vh, 0);
}
.background.down-scroll + .background:not(.down-scroll) .content-wrapper {
-webkit-transform: translateY(15vh);
-ms-transform: translateY(15vh);
transform: translateY(15vh);
}
#one{
background:url(http://s8.postimg.org/lf2udl5np/4_Aihmii.jpg);
background-repeat: no-repeat;
background-size: cover;
}
#two{
background:red;
background:url(http://s8.postimg.org/ow4wgk4px/ugqti_Lg.jpg);
background-repeat: no-repeat;
background-size: cover;
}
#three{
background:url(http://s8.postimg.org/lf2udl5np/4_Aihmii.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.content-subtitle{
text-transform:none;
}
#first{
color:black;
}
#second{
color:#0058FF;
}
#third{
color:rgb(236, 230, 216);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<div class="container">
<section class="background" id="one">
<div class="content-wrapper">
<p class="content-title" id="first">Promise</p>
<p class="content-subtitle">Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras ut massa mattis nibh semper pretium.<br />Nullam tristique urna sed tellus ornare congue. Etiam vitae erat at nibh aliquam dapibus. </p>
</div>
</section>
<section class="background" id="two">
<div class="content-wrapper">
<p class="content-title" id="second">Our Goal</p>
<p class="content-subtitle">Blha blah</p>
</div>
</section>
<section class="background" id="three">
<div class="content-wrapper">
<p class="content-title" id="third">Global</p>
<p class="content-subtitle">blah blah</p>
</div>
</section>
</div>
<div>
Show me too and everything after the backgrounds please
</div>
Side Note: If you scroll to somewhere on the page and then reload the page, the scroll stays at current location but so does the initial background. Any idea why? I'm assuming it has to do with the JS.
There are 2 things blocking your div. First is .background with position fixed and .background:before with position absolute. (:before tag basically putting an element before the actual class.)
If you just want to show the div after you've done scrolling the background, follow CH's answer and manipulate it with your js.
But I assume your other div will continue to scroll like usual below the background div. In order to do that, you must
disable overflow:hidden at html, body tag
disable position:fixed at .background
Do some positioning in js for smoother transition.
Side note: I've tried your reload problem in my local and everything works fine
The simple answer is that the 3 sections are all being manipulated to be position:absolute and zpositioned in the DOM, and the simple div you list at the end has not. So it will forever live in the top left corner, at 0,0, and z-position: 0.
set your div to be something that will be able to compete:
#my-lonely-div{
z-index: 10;
position: absolute;
}