How do I create CSS scroll effects? - css

When the user scrolls the website downward and reaches a certain point, I want it to trigger a certain behavior. Example could be a change in text position.

Here's an example of what you are describing using javascript:
function winScroll() {
if (window.pageYOffset > 1000) {
window.alert('You have scrolled down the page more than 1000 pixels');
}
}
window.addEventListener('scroll',winScroll,false);
body {
height: 4000px;
}
<h1>Keep scrolling down...</h1>

Related

How to set a div to change its background and alpha levels upon scrolling

I am looking at websites for inspiration for my new start ups homepage. I saw https://www.pactcoffee.com/ and their home page features a full background image for the header and the nav bar is transparent then it becomes a solid color nav bar as you scroll down. I have only been able to set up the CSS for the site but I don't understand what to do to have the change in nav bar color.
You can do something like this...
http://jsfiddle.net/ojcqbLr2/
Check the Fiddle to see the rest of the code... like the CSS.
This JS will do this.
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 100) {
$('.topMenu').fadeIn();
} else {
$('.topMenu').fadeOut();
} });
By the way, I found this info by search.
Show div on scrollDown after 800px
I just made edits to the code so it was at the top and not bottom.
Best of luck.
I have found that you can set two divs. One of which will be display set to none.
$(document).scroll(function () {
var headerHeight = $('header').height(),
s = $('.nav'),
y = $(this).scrollTop();
if (y > headerHeight) {
$('.navLong').fadeIn();
$('.nav').fadeOut();
} else {
$('.navLong').fadeOut();
$('.nav').fadeIn();
}});
This allows one div to disappear when one appears and vice versa. A working example is can be found in the DEMO

JQuery Mobile 1.4.5 right panel animation

I'm using a JQuery Mobile 1.4.5 external panel on the right side of some pages, and the pages have also the class ui-responsive-panel, so that the main content is resized according to the panel width to show its whole content.
The panel has also data-dismissible="false" because in the main content are some form controls and user interaction while the panel is open.
The panel shows itself through the "reveal" animation, which causes the page main content first to swipe off to the leftmost side of the page, and then resize to the remaining page width.
<div data-role="panel" data-position="right" data-position-fixed="true" data-display="reveal" data-dismissible="false">
</div>
This is the CSS i'm use to customize the JQM right panel:
.ui-panel {
width: 25em;
}
.ui-responsive-panel .ui-panel-page-content-open.ui-panel-page-content-position-right {
margin-left: 25em;
}
.ui-panel-page-content-position-right,
.ui-panel-dismiss-open.ui-panel-dismiss-position-right {
left: 0;
right: -25em;
}
.ui-panel-animate.ui-panel-page-content-position-right.ui-panel-page-content-display-reveal {
left: 0;
right: 0;
-webkit-transform: translate3d(-25em,0,0);
-moz-transform: translate3d(-25em,0,0);
transform: translate3d(-25em,0,0);
}
Is there a simply way to avoid the initial left swipe-off of the leftmost main part of the page, and instead to have the main content smoothly decrease its size from the right side during the panel animation?
This below is a possible solution using the jQuery animate() method. Let say its enough to make only the page-content responsive, as the full-page animation (toolbars included) is not a requirement:
$(".ui-panel").on("panelbeforeopen", function (event, ui) {
$(".ui-page-active .ui-content").animate({
"margin-right": "50%"
}, 300,"swing");
});
$(".ui-panel").on("panelbeforeclose", function (event, ui) {
$(".ui-page-active .ui-content").animate({
"margin-right": "0%"
}, 300,"swing",function()
{
$(this).removeAttr("style");
});
});
Furthermore, when used with a Panel with data-display="overlay" the class "ui-responsive-panel" in the body is no longer necessary and can be dropped, because the Panel height can be easily adapted to fill only the page-content height (credits: jQuery mobile panel between header and footer) .
function scalePanelToContent() {
var screenH = $.mobile.getScreenHeight();
var headerH = $(".ui-header").outerHeight() - 1;
var footerH = $(".ui-footer").outerHeight() - 1;
var panelH = screenH - headerH - footerH;
$(".ui-panel").css({
"top": headerH,
"bottom": footerH,
"min-height": panelH
});
}
By adding "bottom": footerH the Panel is nicely filling the full page-content height also when the browser window is resized.
Panel: the CSS Panel animation is adapted with a minimum of changes, using the same criteria that jQuery actually uses for transitions and animations support:
.ui-panel-animate.ui-panel-position-right.ui-panel-display-overlay {
-webkit-transform: translate3d(100%,0,0);
transform: translate3d(100%,0,0);
-moz-transform: translate3d(100%,0,0);
}
The final result from user-experience point of view, is very closely as using a Panel with data-display="push" or data-display="reveal" in a Panel responsive page: a nice smooth animation - moreover without the overhead of the panel wrapper on each JQM page and with the header and footer toolbars always available at full width without shrinking.
Full demo: http://jsfiddle.net/e6Cnn/38/

DIV float with page

How can I get a DIV to float with my page? Currently I have it setup like this: http://g2n.us/Dev/TheHabbos_6975/
I can do this by using the following CSS:
Code:
.stayStill {
position: fixed;
width: 300px;
}
But how can I get it so when the header scrolls away, the right DIV moves up and stays 10 pixels away from the top and scrolls with the page, unless the header is there?
You need JavaScript to do this.
Your site is already using it, so there should be no problem with using JavaScript to do this.
A couple of tutorials:
http://jqueryfordesigners.com/fixed-floating-elements/
http://css-tricks.com/scrollfollow-sidebar/
This answer uses jQuery
You can put this in your $.ready() function
var int_header_height = 10; //put pixel value height of header here
if ($(document).scrollTop() <= int_header_height) {
$('div.stayStill').css('position','absolute').css('top','0px');
} else {
$('div.stayStill').css('position','fixed').css('top','10px');
}
This also assumes that the div is in a position: relative element below the header. Otherwise you should change the .css('top','0px') to .css('top',int_header_height + 'px')

how to fill div with full height of page in css? (page is taller than 100%) for ajax loading gif background

ok there are several similar questions but not quite anything that I want.
I have few ajax requests on page and I want to show the image in the center of the screen, and its all working OK.
Just to make it look more prominent, I wanted to place that image on a div with translucent background, so its more obvious for the end users. Now comes the tricky part.
I made the div with css like this:
.divLoadingBackground
{
filter: Alpha(Opacity=40); -moz-opacity:0.4; opacity: 0.4;
width: 100%;
height: 100%;
background-color: #333;
position: fixed;
top: 0px;
left: 0px;
}
This fills the page up alright, or, I should say, this fills the viewport. If I scroll the page down, the page is again normal. I want this div to span the ENTIRE LENGTH of the page, no matter how long the page is.
Here is an example mockup of the problem I made to quickly demonstrate:
As you can see, I took the example of SO for the mockup ;) image 1 shows that its okay when it appears. image 2 shows that it goes up with the page on scroll.
I'm a c# developer and css is as alien to me as ancient latin.
How to make this divLoadingBackground div to fill out the entire length of the page?
Many thanks for any help.
If you need any additional info, please comment!
One thing I dont see in your css is z-index. Fixed, although, fixes this problem, sometimes, based on how other divs are positioned, your divLoadingBackground div could end up in one of the divs.
try adding
z-index: 9999;
or something similar and see if it works.
Would have put this in a comment, but it seems I have too low rep to comment.
Where is the .divLoadingBackground div located in the DOM tree? Since it has fixed position, it shouldn't scroll with the page. This makes me belive that the element is too deeply nested. Try putting it right in the body level of the page and see if that helps.
Also, are you sure that some other css directive isn't changing the position attribute to absolute or something?
Also, make sure to use the right DOCTYPE. That has some impact on fixed position elements.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Oh, and ofcourse, fixed position isn't supported in IE6 and below.
I believe you will need JavaScript/jQuery to dynamically set the height of the div in question to the height of the page once rendered.
And if you're entering the world of web, it's time to learn that new language "CSS" as well as perpahs-not-quite-as-daunting JavaScript.
When I needed such a functionality some years ago, I examined how Google Calendar did it.
Basically, they use a timer-driven JavaScript file that checks for the height of the window and adjust the height of a contained DIV tag accordingly (or of an IFRAME tag, just any container tag that you like).
Here is a code snippet from a page I worked on:
<script type="text/javascript">
document.getElementsByTagName("body")[0].style.height = "100%";
document.getElementsByTagName("html")[0].style.height = "100%";
document.getElementsByTagName("body")[0].style.minHeight = "100%";
document.getElementsByTagName("html")[0].style.minHeight = "100%";
function height()
{
try
{
height_iframe();
}
catch(err)
{
}
}
window.onload=height;
// --
var ie6WorkaroundIFrameResize = 1;
function height_iframe()
{
var any = false;
var offset = 300;
var c = document.getElementById("iframecontent");
if ( c!=null )
{
c.style.height = (GetClientHeight()-offset)+"px";
any = true;
var d = document.getElementById("iframeie6");
if ( d!=null )
{
d.style.height = (GetClientHeight()-(offset+ie6WorkaroundIFrameResize))+"px";
any = true;
ie6WorkaroundIFrameResize = 0;
}
}
if ( any )
{
setTimeout( 'height_iframe()', 300 );
}
}
function GetClientHeight()
{
return document.documentElement.clientHeight;
}
</script>
Basically, the script regularly checks for the height of the window via the GetClientHeight() function and adjusts the element in concern ("iframecontent") accordingly.
I subtract some offsets of fixed-height headers and footers.
AFAIK you would need to set the size of this divthrough javascript. I would recommend using jQuery, in this way :
//$(document).height() gives the size of the document
//(as opposed to $(window).height() that would give the size of the viewport
$("div#overlay").css('height',$(document).height());

fixed vertical positioning of css within an iframe

I am trying to get my bottom header to stick to the bottom of the screen inside of my iframe application and have it always appear in view for the user even when the page is scrolling. I have no control over the outer iframe as it is on a different domain. The header itself must be inside of the iframe as I have no control outside the iframe. The iframe always expands to the height of its contents so that it has no scrollbars, but the bar still has to be visible in the viewport at all times.
Another thing to note: The iframe height should be the same height as its contents so their is no need for scroll bars
Chrome has a bug that doesn't fix elements with position:fixed if:
a) you use CSS3 transform in any element, and/or
b) you have a child element positioned outside the box of it's parent element
Oddly enough, the bug was reported back in 2009 and it's still open: https://code.google.com/p/chromium/issues/detail?id=20574
You might want to play around with position: fixed;
#element {
position: fixed;
z-index: 1000;
bottom: 0;
}
EDIT:
I'm sorry, I think I miss understood your post. If I'm reading it correctly you want to create a header bar similar to blogger but to keep it always in view of the user when he/she scrolls.
What you can do is create a container div, and then you can nest both your header and iframe inside that container. You can then play around with the positioning, although I'm not sure if the exact behavior that you're looking for is possible without some javascript.
EDIT 2:
After playing around a bit, I got something that I think might help (if I understand your problem correctly).
http://digitaldreamer.net/media/examples/iframe-site.html
http://digitaldreamer.net/media/examples/iframe.html
I had to look for a long time for a possible solution, and I think I have found one that is using the Intersection Observer API to detect the scrolled position of the iframe within the parent document without needing to access the parent document DOM.
I'm creating a bunch of hidden 100px high elements in the iframe. These are positioned absolutely underneath each other so that together they fill the height of the whole iframe document. An intersection observer then observes the intersection between the (top-level document) viewport and each of the hidden elements and calculates the scroll position of the iframe based on the values it returns. A ResizeObserver creates additional hidden elements if the height of the body increases.
This approach assumes that your iframe is always minimum 100px high. If you expect a smaller height, you need to adjust the hidden container height. The reason is that once a hidden container is 100% visible, the intersection observer does not emit the callback while the parent document is being scrolled (since the intersection ratio stays at 1). This is also the reason why I need a lot of small containers rather than observing the intersection with the iframe body itself.
const CONTAINER_HEIGHT = 100;
const threshold = [...Array(CONTAINER_HEIGHT + 1).keys()].map((i) => i / CONTAINER_HEIGHT);
/**
* Registers an intersection handler that detects the scrolled position of the current
* iframe within the browser viewport and calls a handler when it is first invoked and
* whenever the scrolled position changes. This allows to position elements within the
* iframe in a way that their position stays sticky in relation to the browser window.
* #param handler Is invoked when the function is first called and whenever the scroll
* position changes (for example due to the user scrolling the parent document). The
* "top" parameter is the number of pixels from the top of the browser viewport to the
* top of the iframe (if the top of the iframe is above the top of the browser viewport)
* or 0 (if the top of the iframe is below the top of the browser viewport). Positioning
* an element absolutely at this top position inside the iframe will simulate a sticky
* positioning at the top edge of the browser viewport.
* #returns Returns a callback that unregisters the handler.
*/
function registerScrollPositionHandler(handler: (top: number) => void): () => void {
const elementContainer = document.createElement('div');
Object.assign(elementContainer.style, {
position: 'absolute',
top: '0',
bottom: '0',
width: '1px',
pointerEvents: 'none',
overflow: 'hidden'
});
document.body.appendChild(elementContainer);
const elements: HTMLDivElement[] = [];
let intersectionObserver: IntersectionObserver | undefined = undefined;
const resizeObserver = new ResizeObserver(() => {
intersectionObserver = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.intersectionRatio > 0 && (entry.intersectionRect.top > entry.boundingClientRect.top || entry.target === elements[0])) {
handler(entry.intersectionRect.top);
}
}
}, { threshold });
const count = Math.ceil(document.documentElement.offsetHeight / CONTAINER_HEIGHT);
for (let i = 0; i < count; i++) {
if (!elements[i]) {
elements[i] = document.createElement('div');
Object.assign(elements[i].style, {
position: 'absolute',
top: `${i * CONTAINER_HEIGHT}px`,
height: `${CONTAINER_HEIGHT}px`,
width: '100%'
});
elementContainer.appendChild(elements[i]);
intersectionObserver.observe(elements[i]);
}
}
});
resizeObserver.observe(document.documentElement);
return () => {
resizeObserver.disconnect();
intersectionObserver?.disconnect();
elementContainer.remove();
};
}
This example code should create a toolbar that is sticky at the top of the browser viewport:
<div style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; overflow: hidden; pointer-events: none; z-index: 90">
<div id="toolbar" style="position: absolute; top: 0; left: 0; right: 0; pointer-events: auto; transition: top 0.3s">
Line 1<br/>Line 2<br/>Line 3<br/>Line 4<br/>Line 5<br/>Line 6<br/>Line 7<br/>Line 8<br/>Line 9<br/>Line 10
</div>
</div>
<script>
registerScrollPositionHandler((top) => {
document.querySelector('#toolbar').style.top = `${top}px`;
});
</script>
Note that other than what you asked for, this will position the toolbar at the top of the viewport rather than at the bottom. Positioning at the bottom should also be possible, but is slightly more complex. If anyone requires a solution for this, please let me know in the comments and I will invest the time to adjust my answer.

Resources