Fade a Pseudo Element on scroll - JS or jQuery - javascript

I have a pseudo element I'd like to fade to opacity:0 on scroll. I can't seem to make head nor tale of how to do it. I've set up a codepen here. http://codepen.io/emilychews/pen/JWyaKr
Normally I'd use Greensock, but I can't on this project. I also have to use a pseudo element, not an absolutely positioned div. The fade needs to happen after 10px scroll from the top and then come back when the user scrolls back to the top (its part of a nav element)
HTML
<div id="mydiv">My Div</div>
CSS
#mydiv {
background: red;
width: 10%;
}
#mydiv:after {
content: '';
position: absolute;
height: 10%;
width: 10%;
top: 30px;
background: black;
}
Any ideas would be awesome. I feel as though I'm either about to cry or eat a bucket of fried chicken in frustration.
Emily

Set a transition for opacity on the pseudo element, and add a class to the main element on scroll that you use in the selector to change opacity on your pseudo element.
var $mydiv = $('#mydiv');
$(window).scroll(function() {
if ($(this).scrollTop() > 10) {
$mydiv.addClass('fade');
} else {
$mydiv.removeClass('fade');
}
})
body {
height: 200vh;
}
#mydiv {
background: red;
width: 10%;
}
#mydiv:after {
content: '';
position: absolute;
height: 10%;
width: 10%;
top: 30px;
background: black;
transition: opacity .25s;
}
#mydiv.fade:after {
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mydiv">My Div</div>

Related

jquery: Remove a <div> stacked above another <div> on mouseenter and restore that <div> on mouseleave

Here's the challenge:
I have two divs layered on top of one another in an HTML file. The top div is mostly transparent using CSS the bottom div has an image as its background. On mouseenter, I want the top div to disappear and on mouseleave I want the top div to come back.
$(document).ready(function() {
$('.dimmer').on('mouseenter', event => {
$(this).hide();
}).on('mouseleave', event => {
$(this).show();
});
});
.experience {
background: url("cmu-110.png") no-repeat center;
height: 110px;
width: 110px;
z-index: 2;
}
.dimmer {
background: rgba(238, 238, 238, .25);
position: relative;
top: -128px;
z-index: 3;
}
<div>
<div class="experience"></div>
<div class="dimmer"></div>
</div>
The jquery code snippet above is in a separate file and called in the html's head.
<head>
<!--- Some head stuff like title, meta, calling css in separate file, etc --->
<!--jquery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="interaction.js"></script>
</head>
Full transparency: I am new to jquery and trying to use it for the first time. Despite working through the full codecademy jquery tutorial, reading w3C school tutorial, searching other stackoverflow posts, and spending more than a reasonable amount of time, I can't seem to get this to work--probably due to a dumb mistake.
Thank you for your help!
I believe a jquery '.on( "mouseout", handler )' on the bottom div should be sufficient to make the top div visible/fade in.
This post should help you: jquery .mouseover() and .mouseout() with fade
If not (if that does not work) what I would do/suggest is:
When mouse enters the top div activate a setTimeout polling functiion or .mouseMove that runs every 1 second or so which checks the mouse position and hide the top div.
If the mouse is not on the bottom div (mousemove) , then display the top div and disable the polling.
You can seach this forum for how to write a setTimeout polling function, etc. If I have some time over the weekend I will give it a whirl...
Trust this helps.
You can set the css visibility property to hidden and visible on mouseenter and mouseleave. I put some space between two divs to make the effect visible clearly.
$(document).ready(function() {
$('.dimmer').on('mouseenter', () => {
$('.dimmer').css("visibility","hidden");
}).on('mouseleave', () => {
$('.dimmer').css("visibility","visible");
});
});
.experience {
background: red;
height: 110px;
width: 110px;
z-index: 0;
}
.dimmer {
background: blue;
position: absolute;
top: -10px;
height: 110px;
width: 110px;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="experience"></div>
<div class="dimmer"></div>
</div>
jQuery(document).ready(function(){
jQuery(".dimmer").on({
mouseenter: function () {
jQuery(this).css('opacity', '0');
},
mouseleave: function () {
jQuery(this).css('opacity', '1');
}
});
});
.experience {
background: url("http://lorempixel.com/400/200/") no-repeat center;
height: 110px;
width: 110px;
z-index: 2;
}
.imparant{
position:relative;
height: 110px;
width: 110px;
}
.dimmer {
background: rgba(238, 238, 238, .25);
position: absolute;
top: 0;
left:0;
right:0;
bottom:0;
z-index: 3;
transition:opacity 320ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="imparant">
<div class="experience"></div>
<div class="dimmer"></div>
</div>
You don't really need to use jQuery or javascript at all for this. You can do it with a single div, a pseudo-element, and a hover style:
.container{
position:relative;
height: 110px;
width: 110px;
background-image: url("https://randomuser.me/api/portraits/men/41.jpg");
}
.container::before{
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.5);
transition: opacity 0.4s;
}
.container:hover::before{
opacity: 0;
}
<div class="container"></div>
If for some reason you wanted to keep the extra divs you could still do it but you'd want to change the CSS hover rule slightly. If you were ok moving the .dimmer before .experience you could just do the hover directly on the .dimmer element:
.dimmer:hover { opacity: 0 }
Otherwise you'd need to use a descendant selector:
.outerDiv:hover .dimmer { opacity: 0 }

Change position top/left of children independently of the parent scrollTop position

I have several divs positioned absolutely within its parent.
The parent overflows the screen and can be scrolled.
On click those divs are supposed to be positioned occupying the height of the screen (as if they had position fixed). So each div is assigned a certain width and height and a top value. The problem is this only works as expected if the parent is not scrolled (scrollTop = 0).
I want this to be done smoothly with CSS transitions. I could assign a top value related to the scroll position of the parent in the click moment. But I am looking for a CSS way to do this. I thought of changing position fixed to the divs but this doesn't transition.
Is there any way I could make it work using CSS?
Edit: I am asking if anyone has some suggestion on how to achieve this using CSS, or some thought on how to approach it differently.
Edit2: This GIF includes just the position change (the width or height is no changing) as it is where I am having the issue. This is the desired solution:
JSFiddle.
var $container = $('#container');
var $elements = $container.find('.element');
$container
.height(function() {
return ($elements.eq(-1).position().top - $elements.eq(0).position().top + $elements.eq(0).outerHeight());
})
.on('click', function() {
$elements.add($container).toggleClass('on');
});
#container {
width: 100%;
background: grey;
position: absolute;
}
.element {
border: 1px solid black;
position: absolute;
width: 100px;
height: 100px;
background: white;
left: 100px;
transition: all 1s ease;
}
.element:nth-child(2) {
top: 130px;
}
.element:nth-child(3) {
top: 340px;
}
.element:nth-child(4) {
top: 550px;
}
.element:nth-child(5) {
top: 660px;
}
.on.element {
left: 0;
height: 20vh;
width: 20vh;
}
.on.element:nth-child(2) {
top: 20vh;
}
.on.element:nth-child(3) {
top: 40vh;
}
.on.element:nth-child(4) {
top: 60vh;
}
.on.element:nth-child(5) {
top: 80vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
As you've already mentioned changing position doesn't transition. This is because position is a non-animatable property, i.e. animations/transitions don't work for it and so changing position from absolute to relative or vice-versa will appear jumpy. Check here for a list of animatable properties.
You may also remove the position: absolute on .element from the beginning.
Either way, here's what you can do:
On clicking div, add class on on #container only and modify css with position: relative and top: 0 and remove the extra rules for top positions
Add a padding of scrollY on #container, so that Div#1 comes into current viewport if page is scrolled.
Checkout the below fiddles:
Using relative from beginning:
https://jsfiddle.net/4utdxr0t/2/
Switching b/w relative and position:
https://jsfiddle.net/4utdxr0t/1/
Adding a margin-top value equivalent to the scrollTop position, and transitioning it with the same duration and ease as the children did the trick:
JSFiddle
var $container = $('#container');
var $elements = $container.find('.element');
$container
.height(function() {
return ($elements.eq(-1).position().top - $elements.eq(0).position().top + $elements.eq(0).outerHeight());
})
.on('click', function() {
$elements.add($container).toggleClass('on');
$container.css('margin-top', $('body').scrollTop());
});
#container {
width: 100%;
background: grey;
position: absolute;
transition: all 1s ease;
}
.element {
border: 1px solid black;
position: absolute;
width: 100px;
height: 100px;
background: white;
left: 100px;
transition: all 1s ease;
}
.element:nth-child(2) {
top: 130px;
}
.element:nth-child(3) {
top: 340px;
}
.element:nth-child(4) {
top: 550px;
}
.element:nth-child(5) {
top: 660px;
}
.on.element {
left: 0;
height: 20vh;
width: 20vh;
}
.on.element:nth-child(2) {
top: 20vh;
}
.on.element:nth-child(3) {
top: 40vh;
}
.on.element:nth-child(4) {
top: 60vh;
}
.on.element:nth-child(5) {
top: 80vh;
}
.on.element:nth-child(6) {
top: 25vh;
}
body {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="container">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>

Make a child of a div's position fixed to the top of the div on scroll and also animate height of child

I have div called box with a header div as a child. when the div scrolls I want that header div to be sticked(fixed) to the top so the users can always see the header. when the user scrolls down,the header's height should decrease to take up less space but to still allow users to see the header content. When the user scrolls back up the header should be unstuck and the height should be like the way it was before any scrolling took place when it was at the top.
I don't like my attempt I'm about to show you because I get the offset of the box relative to the document. I feel like that might not be necessary because there might be a css solution. this one is for the scroll of the whole document. That demo shows using position fixed and it fixes to the top of the page. I cant use position fixed because I believe that is meant for the window and not for divs so what the next best thing?
I dont like how the header's width is over the scrollbars. and the animation is jumpy and it doesn't work.
$(function(){
var btop = $(".box").offset().top;
bwidth = $(".box").innerWidth();
$(".box").on("scroll", function(e){
if($(this).scrollTop() > 50){
$(this).find(".header").css({
"position" : "absolute",
"top" : btop,
"max-width" : bwidth,
}).animate({
"height" :"2em"
})
}else{
$(this).find(".header").css({
"position" : "static",
"top" : btop,
"max-width" : bwidth
}).animate({
"height" :"3em"
})
}
})
})
.box{
margin: 4em auto;
height: 12em;
width: 20em;
background: blue;
overflow-y: scroll;
/*overflow-x: hidden;*/
/*position: relative;*/
}
.header{
background: orange;
width: 100%;
height: 3em;
font-size: 1.3em;
}
.content{
width: 90%;
margin: 0 auto;
background: powderblue;
height: 12em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="box">
<div class="header">This will stick</div>
<div class="content">Other content</div>
<div class="content">Somemore content</div>
</div>
It's just an idea, but in your situation, you can fake a sticky header with a simple trick.
Remove the overflow-y: scroll property of your .box div.
Set a position: absolute property to your .header.
Add a div .content-container who contains your .content div and
set it a position: absolute property too and an overflow-y: scroll.
This way your header is always on top of your .box div and you can scroll your content. Then with your JS code you can change the height of your header on scroll event.
$(document).ready(function(){
$('.content').scroll(function(){
if ($('.content').scrollTop() >= 60){
$('.header').addClass('sticky');
} else {
$('.header').removeClass('sticky');
}
});
});
.box{
margin: 4em auto;
height: 360px;
width: 20em;
background: blue;
position: relative;
}
.header{
position: absolute;
top: 0;
background: orange;
width: 100%;
height: 60px;
font-size: 1.3em;
z-index: 9999;
transition: height 0.3s ease 0s;
-webkit-transition: height 0.3s ease 0s;
-moz-transition: height 0.3s ease 0s;
}
.header.sticky{
height: 30px;
}
.content{
position: absolute;
top: 0;
width: 100%;
height: 300px;
padding-top: 60px;
background: powderblue;
overflow-y: scroll;
}
.content > div{
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="box">
<div class="header">This will stick</div>
<div class="content">
<div>Content</div>
<div>Somemore content</div>
</div>
</div>

Moving the whole page to left and then right

i am looking for this kind of template . Moving the page to left and then page to right. Can anyone tell me how can i make this or is there any javascript example similar to this.
Create two <div>s, put them next to each other, make them take up the whole window, and change them as needed.
HTML:
<div class="left">left</div>
<div class="right">right</div>
CSS:
body {
margin: 0;
}
.left {
background-color: green;
bottom: 0;
left: 0;
position: fixed;
top: 0;
transition: width 1s;
width: 0;
}
.left.active {
width: 200px;
}
.right {
background-color: red;
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
transition: left 1s;
}
.right.active {
left: 200px;
}
JS (width jQuery):
$('.right').on('click', function() {
$('.left').toggleClass('active');
$('.right').toggleClass('active');
});
And here's a fiddle.
Using .toggle(effect,options,duration) method to moving the page to left to right.
// Set the effect type
var effect = 'slide';
// Set the options for the effect type chosen
var options = { direction: 'right' };
// Set the duration (default: 400 milliseconds)
var duration = 700;
$('#Id').toggle(effect, options, duration);
Taken via this link
If you want it to animate smooth on all devices you should use css transitions and transforms. Hiding and showing would be as basic as toggling a class then.
The example in jsfiddle
<style media="screen">
.wrapper {
width: 100%;
overflow: hidden;
}
.menu {
height: 100vh;
width: 100px;
background: #ABC;
color: white;
position: absolute;
left:0;
transition: transform 0.3s;
transform: translateX(-100px);
}
.content {
transition: transform 0.3s;
}
.active .menu {
transform: translateX(0);
}
.active .content {
transform: translateX(100px);
}
</style>
<button class="toggle">Toggle</button>
<div class="wrapper">
<div class="menu">
My menu
</div>
<div class="content">
My content
</div>
</div>
<script type="text/javascript">
document.querySelector('.toggle').addEventListener('click', function(event) {
event.preventDefault();
document.querySelector('.wrapper').classList.toggle("active");
});
</script>
NB! Supported from IE10. IE 9 will support without the animation and you probably should add the needed -ms-, -webkit-, -moz-, etc prefixes to support the older browsers if needed for transition and transform properties.
Also I advise not animating body or html with this method and put the content of page in the wrapper (in .content in the examples case). Moving body and html directly may lead to unpleasant surprises later.

Scroll to top script - div won't hide when on top

I'm working on this website called http://martindue.dk/mmd3x9x/ and I have this scroll to top script that just won't coorporate. I've used the script on many other sites, and it works fine, but on this particular website the div#to-top keeps on re-appearing, even though I'm at the very top of the website, why won't it fade out correctly when at the top?
My code looks like this (the #to-top is insertted after the body-tag in my html):
Javascript
jQuery(document).ready(function() {
$toTop = jQuery("#to-top");
$toTop.hide();
jQuery(window).scroll(function() {
if(jQuery(this).scrollTop() != 0) {
$toTop.fadeIn();
} else {
$toTop.fadeOut();
}
});
$toTop.click(function() {
jQuery("body, html").animate({ scrollTop : 0 }, 500);
return false;
});
});
CSS
#to-top {
background: url("img/to-top.png") center top no-repeat;
background-size: 100%;
width: 50px;
height: 50px;
position: fixed;
bottom: 60px;
right: 60px;
cursor: pointer;
/*display:none;*/
/*opacity: 0.0;*/
}
I created this fiddle, and here it works fine: http://jsfiddle.net/2Rubp/
I know it is not js but in this case you are only using fading so css can do the trick:
#to-top {
background: url("img/to-top.png") center top no-repeat;
background-size: 100%;
width: 50px;
height: 50px;
position: fixed;
bottom: 60px;
right: 60px;
cursor: pointer;
**-webkit-transition: all 0.5s linear;**
display: none;
opacity: 0.0;
}
NB: this is for chrome see this for cross browser compatibility
http://www.w3schools.com/css/css3_transitions.asp

Categories