I'm trying to implement Stellar.js (http://markdalgleish.com/projects/stellar.js/) to a site that I'm developing. I realised that I need to enclose the parallax scrolling inside a container instead of using window/body in order for it to work on an iPad (considering the viewport) and that's where I run into a problem; the script doesn't seem to initiate correctly.
Here's the structure I've setup on the site -
HTML
<header></header>
<!-- keeping this content outside of #content because of a prefixed alignment -->
<div id="content">
<section id="example" data-stellar-background-ratio="1">
<img src="example-1.png" data-stellar-ratio="2" data-stellar-offset="-25">
<img src="example-2.png" data-stellar-ratio="3" data-stellar-offset="-50">
<img src="example-3.png" data-stellar-ratio="4" data-stellar-offset="0">
</section>
</div>
CSS
#content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
section {
background-attachment: fixed;
width: 100%;
height: 100%;
position: relative;
}
img:first-child {
position: absolute;
top: 0;
left: 300px;
}
img:nth-child(2) {
position: absolute;
z-index: 99;
top: 0;
right: 150px;
}
img:nth-child(3) {
position: absolute;
z-index: 99;
top: 0;
left: 100px;
}
JavaScript
$('#content').stellar({
horizontalScrolling: false
});
I can see that the parallax images inside the section get display: none, but other than that the script doesn't seem to be running. I get no JS errors.
I'm thinking it might have something to do with you using position: absolute and not giving the div any with.
Did you check the size of your #content div? Or does stellar handle this too?
Related
I have this HTML structure:
<div class="container">
<img class="image" />
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
and this CSS code:
.container {
position: relative;
height: 88vh;
margin: 0;
}
.image {
height: 100%;
position: absolute;
margin-right: auto;
margin-left: auto;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
.overlay {
position: absolute;
}
My requirements are as follows:
Make image fill the available vertical space and center it horizontally. (Works)
Make image overlay of the same size as the image - without using an absolute width attribute. (Does not work - problem)
Fix icons to specific spots on the image. (Using percentages for top and left attributes ... Not sure if this is going to be as easy as I currently think.)
How can I have it all - a horizontally centered image expanded to fill the vertical space, an exact overlay and elements fixed to specific spot of the image?
While I would prefer a CSS hack, a Javascript solution will be considered, too, in case the width of the image needs to be transferred to the overlay programmatically.
One way of doing it would be to wrap the Image and the Overlay in a div and center that.
.container {
position: relative;
height: 88vh;
margin: 0;
text-align: center;
}
.imagecontainer
{
position: relative;
display: inline-block;
height: 100%;
}
.image {
height: 100%;
}
.overlay {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
<div class="container">
<div class='imagecontainer'>
<img class="image" src='imageurlhere'/>
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
</div>
Like this, the Image will set the width of its parent and in doing so also the width of the Overlay.
I'm trying to use the normal approach to create an element and hide it using jQuery once the page finished loading.
You can see this basic approach in many places but here's the code anyway:
DIV for the image I'd like to display while the page loads, right after the <body> tag:
<div class="pleasewait"></div>
To remove the icon from the screen after the page loads, in the HEAD section of the HTML page:
$(window).bind("load", function() {
$(".pleasewait").fadeOut("slow");;
});
CSS to style the image in the center of the page:
.no-js #loader { display: none; }
.js #loader { display: block; position: absolute; left: 100px; top: 0; }
.pleasewait {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url(img/ajax-loader.gif) center no-repeat #fff;
}
I get the nav bar on my PHP page to load ok but nothing on the <body> section is displayed until the page fully loads (including waiting for the server call to complete and form the remainder of the page).
While there are other fancier methods of achieving my goals, I would really like to understand what I'm doing wrong here.
From the comments I saw you are using jQuery 3.1.1.
.bind() is deprecated since jQuery 3.0
Instead use
$(window).on('load', function(e){
....
})
Also make sure (from this answer and the jQuery API document):
When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.
HTML
<div id="preloader">
<div id="status">
</div>
</div>
<div id="wrappers">
Welcome to page
</div>
CSS
#preloader {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #fff;
z-index: 999999;
}
#preloader #status {
width: 70px;
height: 70px;
position: absolute;
left: 50%;
top: 50%;
background-image: url(images/loader.gif);
background-repeat: no-repeat;
background-position: center;
}
jQuery
$(document).ready(function(){
$(window).load(function() {
$('#status').fadeOut();
$('#preloader').delay(100).fadeOut('fast');
$('#wrappers').delay(250).css({'overflow':'visible'});
});
});
My fixed footer has an arrow icon on top of it. Clicking the arrow should "lower" the footer below the page until only the arrow is visible. Clicking it again should bring back the footer.
I tried playing with the bottom value but it doesn't hide the footer, only pushes it below while the page becomes taller to make room for it:
$('#footer_arrow').toggle(function() {
$('#footer_wrap').css('bottom', '-84px');
}, function() {
$('#footer_wrap').css('bottom', '0');
});
I want the same but with the footer actually disappearing below the page with just the arrow visible on top of it.
MARKUP:
<div id='footer_wrap'>
<footer>
<div id='footer_arrow'></div>
<div>
content
</div>
</footer>
</div>
CSS:
#footer_wrap {
position: absolute;
bottom: 0;
height: 84px;
}
footer {
position: absolute;
bottom: 0;
z-index: 9999;
position: relative;
}
#footer_arrow {
position: absolute;
width: 61px;
height: 23px;
top: -23px;
left: 50%;
background: url(images/footer_arrow.jpg) 0 0 no-repeat;
z-index: 9999;
cursor: pointer;
}
A couple things. First off, I recommend using toggleClass() instead of toggle(). That way, you can just add a class with the required CSS, and toggle it using toggleClass(). This way, you can change any styles necessary from pure CSS, instead of making the modifications in the JavaScript code. However, the toggle() from jQuery's event handling suite that you are currently using will work just fine nonetheless.
Secondly, to move the footer off screen, you'll need to use fixed positioning instead of absolute on #footer_wrap. Otherwise, the bottom is moving relative to the page, which means it just extends it. However, with fixed, the element is positioned at a fixed point in the viewport, which can be moved off screen without extending the page.
$('#footer_arrow').click(function() {
$('#footer_wrap').toggleClass('down');
});
#footer_wrap {
position: fixed;
bottom: 0;
height: 84px;
}
footer {
position: absolute;
bottom: 0;
z-index: 9999;
position: relative;
}
#footer_arrow {
position: absolute;
width: 61px;
height: 23px;
top: -23px;
left: 50%;
background: url(http://www.placehold.it/61x23) 0 0 no-repeat;
z-index: 9999;
cursor: pointer;
}
.down {
bottom: -84px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='footer_wrap'>
<footer>
<div id='footer_arrow'></div>
<div>
content
</div>
</footer>
</div>
What You have to do imho is not .toggle() a #footer_arrow element. You need to .toggle() a #footer_wrap element after clicking on #footer_arrow
Look into this fiddle: http://jsfiddle.net/tdcrsn2j/
I've changed Your HTML & CSS a little, but You can bring it back. It was done just to show case.
go with this
when you want to show
$('#footer_wrap').css({"display":"block"});
when you want to hide
$('#footer_wrap').css({"display":"none"});
So I have a page on my website that has some navigation elements that stick on the page when the user scrolls past a certain point. There are three of them, one on the top, one on the left, and one on the right. HTML and CSS is as follows:
<div id="nav" class="nav">
<!--STUFF CONTAINED IN TOP NAV BAR-->
</div>
<div class="right" id="right">
<!--STUFF CONTAINED IN RIGHT NAV-->
</div>
<div class="left" id="left">
<!--STUFF CONTAINED IN LEFT NAV BAR-->
</div>
.nav {
position: absolute;
top: 108px;
height: 45px;
width: 100%;
left: 0;
right: 0;
}
.nav_sticky {
position: fixed;
top: 0;
height: 45px;
left: 0;
right: 0;
background-image: url(images/backgrounds/stardust_#2X.png);
z-index: 10;
}
.right {
width: 200px;
height: 900px;
position: absolute;
right: 50%;
margin-right: -538px;
top: 153px;
}
.right_sticky {
width: 200px;
height: 900px;
position: fixed;
right: 50%;
margin-right: -538px;
top: 45px;
}
.left {
width: 200px;
height: 900px;
position: absolute;
left: 50%;
margin-left: -538px;
top: 153px;
}
.left_stick {
width: 200px;
height: 900px;
position: fixed;
left: 50%;
margin-left: -538px;
top: 45px;
}
I then use the follow JQuery to cause these elements to stick.
<script>
$(document).ready(function(){
var navPos = $('#nav').offset().top;
$(window).scroll(function () {
var scrollTop = $(this).scrollTop();
if (scrollTop >= navPos) {
var classNamee = $('#nav').attr('class');
console.log(classNamee);
if (classNamee === "nav") {
$("#nav").toggleClass('nav nav_sticky');
$("#right").toggleClass('right right_sticky');
$("#left").toggleClass('left left_stick');
}
}
if (scrollTop <= navPos) {
var className = $('#nav').attr('class');
console.log(className);
if (className === "nav_sticky") {
$("#nav").toggleClass('nav_sticky nav');
$("#right").toggleClass('right_sticky right');
$("#left").toggleClass('left left_stick');
}
}
});
});
</script>
Here's my problem. This works perfectly for the top and right navs, however no matter what I try, the left nav continues to scroll when the others have stopped. I thought it may have been a typo in the css class, but when I looked in the inspector, the .toggleClass function doesn't even change the class on the #left element when it does on the other two. Any ideas as to what could be causing this?
If I copy/paste your sample code as-is to jsFiddle and run it, when you scroll down far enough, it does correctly toggle everything to *_sticky classes, but something about the negative margin-right on the right class element seems to reset the scroll to the top (at least in Chrome) when it flips between .right and .right-stick. When the scroll gets reset, it also reruns your event handeler and changes all the classes back.
Try removing these lines from your CSS and see if the behavior works right (it does in Chrome in a jsFiddle)
.right {
...
/*margin-right: -538px;*/
.right-stick {
...
/*margin-right: -538px;*/
After doing
$view.offset({
left : X, //X is the same each time
top : this.y
});
console.log($view.offset()); //outputs what it should
for several objects. I saw (in firebug) the following html code
<div id="4017" class="text-block" style="position: relative; top: 2px; left: 22px;">
<div id="4043" class="text-block" style="position: relative; top: 41px; left: -64px;">
<div id="4053" class="text-block" style="position: relative; top: 80px; left: -95px;">
<div id="4081" class="text-block" style="position: relative; top: 119px; left: -135px;">
left should be the same for all divs (and it's displayed so if left is equal for each div). Why left is not the same for each div despite it's shown so that left is the same for all divs?
In CSS I have:
div.text-block {
display: inline-block;
}
Thank you in advance!
UPD: divs are located iside three other divs:
<div id="app-container">
<div id="canvas-container">
<div id="canvas">
<!-- divs are located here -->
</div>
</div>
</div>
In respective CSS I have:
#canvas {
position: absolute;
background-color: white;
width: 100%;
height: 100%;
}
#app-container {
height: auto !important;
min-height: 100%;
}
#canvas-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
As said in jQuery documentation,
.offset( coordinates )
Description: Set the current coordinates of every element in the set of matched elements, relative to the document.
So if your elements are in other elements not positioned on position (0, 0) relative to the document, there is an offset applied.
EDIT
Relatively positioned inline elements with same left value :