I want to make the menu fixed on top when window scroll down over 160 pixel, but if the body content is too short, it will become an infinite loop, because if I scroll down over 160 pixel, menu will become fixed which means scroll height will turn to under 160 pixel, so script will make the menu relative back, how to solve this.
Demo
HTML
<div id="header">header</div>
<div id="content">content</div>
JavaScript
$(window).on('scroll', function() {
var scroll = $(window).scrollTop();
if (scroll > 160) {
$('#header').css('position', 'fixed');
} else {
$('#header').css('position', 'relative');
}
});
CSS
body {
margin: 0;
padding: 0;
}
#header {
width: 100%;
height: 60px;
background: black;
color: yellow;
position: relative;
padding: 6px;
}
#content {
width: 100%;
height: 780px;
background: gray;
}
when adding position fixed to menu, add also paddin-top for content (padding-top value equals header height + header top and bottom padding)
JS:
$(window).on('scroll', function() {
var scroll = $(window).scrollTop();
if (scroll > 160) {
$('#content').css('padding-top', '72px');
$('#header').css('position', 'fixed');
} else {
$('#content').css('padding-top', '0');
$('#header').css('position', 'relative');
}
});
fiddle
you do not need any javascript here...so remove all js... and edit your css:
#header {
width: 100%;
height: 60px;
background: black;
color: yellow;
position: fixed; /* make menu header always fixed */
padding: 6px;
top:0px;
}
#content {
width: 100%;
height: 780px;
margin-top:72px; /* margin top 72px because of header height is 60px + pedding 6px*2 */
background: gray;
}
Related
I want to create a website with a single fixed-width centered column and an additional fixed-width sidebar that is position: fixed on the left. When the window is large, this works perfectly, but when I resize the window, they begin to overlap when there's plenty of room left on the right side of the window. For example:
I'd like the center div to be positioned in the center until it runs into the sidebar, at which point I'd like it to have a more fluid responsive design, where the sidebar starts to push the div to the right as you resize the window. For example:
The only solution I'm aware of is something like this (using the jQuery resize event and adding a class to the center column when the window resizes small enough):
var SMALL_WINDOW_SIZE = 560;
function checkWindowSize() {
var $content = $("#content");
if ($(this).width() < SMALL_WINDOW_SIZE && !$content.hasClass("smallWindow")) {
$content.addClass("smallWindow");
} else if ($(this).width() >= SMALL_WINDOW_SIZE && $content.hasClass("smallWindow")) {
$content.removeClass("smallWindow");
}
}
$(document).ready(function() {
checkWindowSize();
});
$(window).resize(function() {
checkWindowSize();
});
#sidebar {
background: orange;
width: 100px;
height: 200px;
position: fixed;
top: 10px;
left: 10px;
}
#content {
background: blue;
width: 300px;
height: 350px;
margin: 0px auto;
}
.smallWindow {
float: left;
margin-left: 120px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='sidebar'></div>
<div id="content"></div>
I can't help but feel there should be a pure CSS solution or one that uses less or more elegant JavaScript. Is there such a thing?
This isn't by any means the best way of achieving the desired effect with CSS, but it's the methodology behind using CSS media queries to adapt layout that I want to convey.
Obviously if this meets your needs, you'll want to adjust the numbers/widths to suit your case.
*, :before, :after{
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
position: relative;
padding: 20px;
}
.sidebar, .main {
padding: 20px
}
.sidebar {
position: fixed;
top: 20px;
left: 20px;
width: 200px;
background: goldenrod;
color: white;
height: 50vh;
}
.main {
margin-left: 220px;
background: mediumblue;
color: white;
height: 200vh;
}
#media (min-width: 1050px){
.main{
margin: 0 220px 0 220px;
}
}
<div class="wrapper">
<div class="sidebar">
Sidebar
</div>
<div class="main">
Main
</div>
</div>
ยป JSBin
I want to show a webpage only on 100 percent. If the browser height changes I would seen the hole page. At the end of the page is a fixed footer with three different sizes (changeable by JS). If the footer expand the content should shrink.
HTML:
<div id="page">
<section id="content">
<div id="flexContent">
<div id="topFixedContent">
Content on top of the two flexible divs.
</div>
<div id="sizedContent">
This content have a fixed size. If ts too big scrollbars should be visible.
</div>
</div>
<div id="fixedFooter">
Footer with 3 different sizes inside content: 20px, 200px, 100%.
</div>
</section>
</div>
CSS:
body {
height: 100%;
}
#page {
height:100%;
width: 500px;
border-left: 2px solid grey;
border-right: 2px solid grey;
margin: auto;
}
#content {
height:100%;
width: 100%;
background-color:blue;
}
#flexContent {
heigth: 100%;
background-color:red;
overflow: hidden;
}
#topFixedContent {
height:20px;
background-color:yellow;
}
#sizedContent {
height:500px;
background-color:green;
border-bottom: 2px solid red;
}
#fixedFooter {
heigth: 20px;
width: 100%;
bottom: 0;
position: fixed;
background-color:orange;
}
JS (Jquery):
var counter = 0;
$( "#fixedFooter").click(function(){
if (counter == 0){
$("#fixedFooter").animate({height: "200px"});
counter++;
}
else if (counter == 1){
$("#fixedFooter").animate({height: "100%"});
counter++;
}
else if (counter == 2){
$("#fixedFooter").animate({height: "20px"});
counter = 0;
}
});
My example code on Fiddle: https://jsfiddle.net/mnrp72ho/7/
Inside my example are different problems:
fixedFooter schould have the same (variable) width of #page
flexContent should have ScrollBars (vertical & horizontal) if the 100% of hight are full
flexContent have to be visible if the footer have 20px or 200px
if it's possible too, #topFixed Content should be visible if fixedFooter have 100%
I have try a lot, but i haven't found a solution for me. Maybe flex is the right way i don't know. I am open for any solution, but topFixedContent and sizedContent hav to be together.
Notice: I work with JQuery and Bootstrap.
OK, I have solved my problem via JavaScript. My solution calculates the sized and after resize it reorder the div containers.
var counter = 0;
var resizeTimer;
window.onload = function(event) {
rescaleContent();
};
window.onresize = function(event) {
//Um die Anzahl der Funktions-Aufrufe zu verringern.
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
resizeTimer = null;
rescaleContent();
}, 200);
};
function rescaleContent() {
console.log("resize");
footerHeight = $("#fixedFooter").height();
var scrollHeigth = 10;
var newHeight = $(window).height() - footerHeight - $('#topFixedContent').height() - scrollHeigth;
$("#flexContent").animate({height: newHeight});
$("#sizedContent").animate({height: newHeight});
$("#fixedFooter").animate({width: $("#page").width()});
}
$( "#fixedFooter").click(function(){
if (counter == 0){
$("#fixedFooter").animate({height: "200px"}).promise().then(function(){rescaleContent();});
counter++;
}
else if (counter == 1){
$("#fixedFooter").animate({height: "95%"}).promise().then(function(){rescaleContent();});
counter++;
}
else if (counter == 2){
$("#fixedFooter").animate({height: "20px"}).promise().then(function(){rescaleContent();});
counter = 0;
}
});
The CSS looks like (thank's to Stages):
html, body {
height: 100%;
overflow: hidden;
}
#page {
position: relative;
margin:0px auto;
height: auto !important;
min-height:100%;
height:100%;
width: 500px;
border-left: 2px solid grey;
border-right: 2px solid grey;
}
#content {
width: 100%;
height:100%;
background-color:blue;
}
#flexContent {
background-color:red;
}
#topFixedContent {
height:20px;
background-color:yellow;
}
#sizedContent {
width: 100%;
background-color:green;
border-bottom: 2px solid red;
overflow: auto;
z-index: 5;
}
#fixedFooter {
heigth: 20px;
bottom: 0;
position: fixed;
background-color:orange;
z-index: 1;
}
So I don't understand very well what you want but I can solve some of your problems.
1. fixedFooter schould have the same (variable) width of #page:
In the Css : #fixedFooter {width: 500px;}
2. flexContent should have ScrollBars (vertical & horizontal) if the 100% of hight are full:
In Css : #flexContent {overflow: auto;}
3. flexContent have to be visible if the footer have 20px or 200px:
Here you have several solutions, put in Css a z-index higher than the footer, you can ajust the sizedepending on the footer size like you did in JS.
4.if it's possible too, #topFixed Content should be visible if fixedFooter have 100%:
Dont go with a footer of 100% then.
If I missunterstood somethings tell me pls I can correct it.
Hope it helps.
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>
<style>
body { margin: 0px; background-color: #e3e3e3; }
#header { background-color: #cb5454; height: 140px; }
#sticky { background-color: #546bcb; height: 70px; }
#section { height: 1500px; }
#footer { background-color: #cb5454; height: 140px; }
</style>
Here is my code: http://jsfiddle.net/uaqh018d/
I want #sticky to stick to the top of the page after scrolling past #header. I also want it hidden until stuck. And then of course have it unstick+hide again after scrolling back up to #header.
How can I achieve this?
I would recommend adding a class to #sticky when it's ready to be fixed to the top of the screen, and then removing that class when you want to 'unstick' it. Then you can manipulate that class in CSS.
e.g. for a class fixed you'd put the following in your CSS:
#sticky {
display: none;
background-color: #546bcb;
height: 70px;
}
#sticky.fixed {
display: block;
position: fixed;
top: 0;
width: 100%;
}
And then your jQuery would look like this:
$(window).scroll(function() {
var distanceFromTop = $(this).scrollTop();
if (distanceFromTop >= $('#header').height()) {
$('#sticky').addClass('fixed');
} else {
$('#sticky').removeClass('fixed');
}
});
Here's an updated FIDDLE
I might also recommend some jQuery fade or slide effects (see the fiddle).
You can use position: fixed and in js detect when user scroll like this:
$(document).scroll(function() {
//detect when user scroll to top and set position to relative else sets position to fixed
$("#sticky").css({
"top": "0",
"position": $(this).scrollTop() > 140 ? "fixed" : "relative"
});
});
body {
margin: 0px;
background-color: #e3e3e3;
}
#header {
background-color: #cb5454;
height: 140px;
}
#sticky {
background-color: #546bcb;
height: 70px;
width: 100%;
position: fixed;
}
#section {
height: 1500px;
}
#footer {
background-color: #cb5454;
height: 140px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>
References
.scroll()
In my case, the div I wanted to be sticky was inside of another div (ie. not stuck to the page, but in another fixed div on the side of the page). Here's my adaptation of #bowhart's answer to solving this problem given a React component (sticky_adapter.js):
module.exports.makeItSticky = function(thisReactComponent, parentScrollNode = window) {
const thisNode = $(ReactDOM.findDOMNode(thisReactComponent));
const position = thisNode.position();
// Uncomment for verbose logging
//console.log("Initial position: " + UIUtils.stringify(position));
const scrollContainer = $(parentScrollNode);
scrollContainer.scroll(() => {
const distanceFromTop = scrollContainer.scrollTop();
// Uncomment for verbose logging
//console.log("ScrollTop: " + distanceFromTop);
if (distanceFromTop > position.top) {
thisNode.addClass("stick-to-top");
} else {
thisNode.removeClass("stick-to-top");
}
});
};
Now, to make any React component sticky, I just add to the class:
componentDidMount() {
StickyAdapter.makeItSticky(this, ".some-other-div-which-is-the-container");
}
Finally, the css for the sticky class:
.stick-to-top {
display: block;
position: sticky;
top: 0;
z-index: 10;
}
Hey this is and old question but for new visitors I think u just need to add this css code to #sticky:
#sticky { position:sticky;top:0; }
and no need for javascript.
sticky toggles between relative and fixed, depending on the scroll position.
and don't forget that, the parent also should not have overflow property
I'm newbe in jQuery, please do not judge strictly. I want header become fixed when I scroll page 300px. And remove fixed if <300px. And I want to animate it, slide down when I scroll down, and slide up when I scroll top. Something like this Some site, scroll down and you'll see what I want.
My html like that
<div class="heading-wrapper">
1
2
3
4
5
</div>
Css
.heading-wrapper {
width: 100%;
height: 65px;
background: #000;
position: relative;
}
.heading-wrapper.fixed {
position: fixed;
top: -80px;
left: 0;
right: 0;
}
and jQuery
$(window).scroll(function() {
if ($(this).scrollTop() > 300){
$('.heading-wrapper').addClass("fixed");
$('.heading-wrapper.fixed').animate({'top' : '0px'}, 800);
}
else{
$('.heading-wrapper.fixed').animate({'top' : '-80px'}, 800);
setTimeout(function(){
$('.heading-wrapper').removeClass("fixed");
},800);
}
});
It dont work like what I want.
If scrolling by pressing down mouse whell - it dont animate..
Animation appears at once only..
Slide up animation never appears..
If I scrolling fast up and down, the whole structure breaks down, no styles are added where necessary))
Please, help me to fix this, and remember, do not judge strictly! :)
JsFiddle link
Demo
js
$(document).ready(function () {
$("header").before($("header").clone().addClass("animateIt"));
$(window).on("scroll", function () {
$("body").toggleClass("down", ($(window).scrollTop() > 100));
});
});
css
body, html {
margin:0;
padding:0;
}
header {
position: relative;
width: 100%;
height: 60px;
line-height: 60px;
background: #000;
color: #fff;
}
header.animateIt {
position:fixed;
top:-60px;
left: 0;
right: 0;
z-index:999;
transition:0.4s top cubic-bezier(.3, .73, .3, .74);
}
body.down header.animateIt {
top:0;
}
.content {
padding: 0 20px 20px;
background: #fff;
line-height: 1.5;
color: #333;
}
html
<header>
1
2
3
4
5
</header>
Here's how I would do it.
First, depending on the browsers you're supporting, you could add this CSS :
.heading-wrapper {
position: fixed;
top: -80px;
transition: top 1s linear; /*as you wish*/
[...]
}
.heading-wrapper.relative {
position: absolute;
top: 0px;
}
.heading-wrapper:not(.relative).fixed {
top: 0px;
}
Then in Javascript :
var $wrapper = $(".heading-wrapper");
var $win = $(window);
var doc = document.documentElement, body = document.body;
var top = 0;
$wrapper.clone().appendTo("body").addClass("relative");
$win.scroll(function () {
top = (doc && doc.scrollTop || body && body.scrollTop || 0);
if( top > 300)
setTimeout(function(){$wrapper.addClass("fixed");},0);
else if( $wrapper.hasClass("fixed") )
setTimeout(function(){$wrapper.removeClass("fixed");},0);
});
I updated your JSFiddle.
EDIT : Added a cloned menu, absolute.
This is my problem, I have a div and inside 2 divs, one is centered and the other one is fixed on the left, the problem is when I resize the screen the centered div overlaps the fixed one, what I wanted to do is detect when the centered div overlaps the other div and change its left value with javascript, but is not working, any ideas?
This is my design:
<div id="content-wrap">
<div id="content">
</div>
<div id="leftbar">
</div>
</div>
and the CSS:
#content-wrap
{
clear: both;
float: left;
width: 100%;
}
#content
{
text-align: left;
padding: 0;
margin: 0 auto;
height: 470px;
width: 760px;
overflow: auto;
}
#leftbar
{
background-color: transparent;
width: 200px;
height: 470px;
position: absolute;
top: 185px;
left: 50px;
}
and this is the javascript code:
window.onload = function Centrar() {
var leftBar = $get("leftbar");
if (leftBar != null) {
var content = $get("content");
var size = leftBar.offsetLeft + leftBar.offsetWidth;
if (content.offsetLeft < size) {
content.style.left = size + 20 + 'px';
}
}
}
Thanks in advance for any help.
The easiest fix would be to apply a min-width to your #content-wrap container that prevented the overlap from occurring:
#content-wrap {
clear: both;
float: left;
width: 100%;
/* #leftbar width x 2 + #content width */
min-width: 1160px;
}
However, if you want to use Javascript, you'll need to attach the code to the window load and resize events:
$(window).bind('load resize', function() {
var content = $('#content');
var leftbar = $('#leftbar');
// get the right edge of the #leftbar
var leftbarEdge = leftbar.width() + leftbar.offset().left;
// check if an overlap has occured and adjust #content left position if yes
if (leftbarEdge > content.offset().left) {
content.css({
left: leftbarEdge - content.offset().left
});
}
});
The last change you'll need to apply to get this working is to set #content to position: relative in the CSS so it respects the left property you're setting with Javascript:
#content {
position: relative;
/* remaining css */
}
You can see it in action here.