Stop fixed positioned header to overlap navigation bar - css

I have something like this:
<div id="navigation"></div>
<div id="header"></div>
<div id="content"></div>
The #header has "position:fixed; top: 0;", I need it to be this way except when the #navigation is visible (not scrolled away), in this case the #header should be displayed after the #navigation.
Could this be done with pure css?
Or any clean JS solution?
Here is the jsfiddle.

Sounds like a job for the jQuery Waypoints plugin: http://imakewebthings.com/jquery-waypoints/
Using the sticky element shortcut:
Just add
$(document).ready(function() {
$('#header').waypoint('sticky');
})
and a style for the stuck element
#header.stuck {
position: fixed;
top: 0;
}
Here is the updated fiddle

Here's a solution using jQuery.
Updated JSFiddle
//Checks if navigation is visible and sets position of header accordingly
function headerPosition(){
if($('#navigation').is(':visible')){
$('#header').css('position', 'static');
}
else{
$('#header').css('position', 'fixed');
}
}
//Run function to set correct header position
headerPosition();
//Show/Hide navigation to see function in action - not needed for production
$('button').on('click', function(){
$('#navigation').toggle();
headerPosition();
});

Related

Twitter Bootstrap modal opening/closing causes fixed header to jump

I am almost done with a simple 2-page website for my registered domain names.
Unfortunately I have one small issue I can't seem to fix: a jumpy header when a Twitter Bootstrap modal opens and closes.
On mobile devices there's no problem. The problem only occurs in larger viewports like desktops and laptops.
How to recreate
Open http://www.domains.cloudlabz.nl/domains in a webbrowser and make sure you get a vertical scrollbar by lowering the viewport height.
Click on one of the blue 'more info' buttons.
Notice the jumping header and disappearing scrollbar once the modal opens.
Close the modal and notice the header jumping back and the scrollbar reappearing.
Check the following image (same result in Opera, Safari, Firefox and Chrome):
What I'd like
I'd like the header to stop jumping when opening/closing a modal. The fact the scrollbar disappears is not an issue. Actually, I would like it to stay like that.
Update
I noticed the jumping header only occurs with fixed position elements such as my header (added Bootstrap class navbar-fixed-top). It even occurs on the Bootstrap website itself: http://getbootstrap.com/javascripts. Go to the 'Modals > Optional Sizes' area on a desktop and click one of the buttons. You'll see the right side menu jumping back and forth.
When the modal opens, the class .modal-open is added to the body element (thanks for pointing that out #Pred). It adds a padding of 15px to the right, which is the same width as the scrollbar gutter. This prevents the body from jumping back and forth.
Unfortunately this padding apparently does not apply to fixed elements.
Bootstrap adds class="modal-open" and padding-right: 15px; to body when the modal is shown. To remove the right shift and keep the scroll bar add this to your css:
body.modal-open {
overflow: inherit;
padding-right: 0 !important;
}
Tried in bootstrap 3.3.4
I seemed to have found a quick fix for my issue. It uses a piece of javascript to add extra style to the header (15px padding-right) to prevent it from jumping.
This might not be the best solution but for now it works just fine.
Since there were no issues on viewports smaller than 768px (mobile) this piece of code only adds the extra 15px to larger viewports such as desktops and laptops
<script>
$(document).ready(function(){
// Dirty fix for jumping scrollbar when modal opens
$('#requestModal').on('show.bs.modal', function (e) {
if ($(window).width() > 768) {
$(".navbar-default").css("padding-right","15px");
}
});
$('#requestModal').on('hide.bs.modal', function (e) {
if ($(window).width() > 768) {
$(".navbar-default").css("padding-right","0px");
}
});
});
</script>
If you know a better solution (preferably CSS3 only), please let me know.
Thanks for all the help!
As you usually put Bootstrap navbar as a direct child of the body container:
<body>
<nav class="navbar navbar-fixed-top">...</nav>
</body>
You can use the body padding-right value, calculated in the Bootstrap core code to prevent it from "jumping" when opening a modal window, to fix the navbar issue as well . A pure CSS solution is below:
.navbar-fixed-top {
padding-right: inherit;
}
Easy as that.
When the modal opens, the "modal-open" class is added to the HTML <body> element which hides overflow. You can change this by over-writing the "modal-open" class with overflow: inherit. This will keep the scrollbar in view, just as it is when the modal is closed. Keep in mind that this will change the overflow option whenever any modal is opened on the page. Hope this helps. Good luck!
All this happens because of this part of code in bootstrap.js:
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
}
That annoying problem happens in Firefox 32.0 (Gecko/20100101) and Chromium Version 37.0.2062.94 (Webkit 537.36) (Ubuntu 14.04). Not happens in QupZilla Version 1.6.6 (WebKit 537.21).
For me, the dirty fix is to comment the conditional line, after that it works in all browsers I tested (including some android's browsers).
NOTE: if you comment that line, you should be careful with the size of your modals since bootstrap will not create enough space for the new scrollbar.
Regards.
Another solution is to add:
.modal-open .navbar-fixed-top {
overflow-y: scroll;
}
to prevent its content from jumping. Again, easy as that.
This one only works if you know your page content is longer than the viewport (so any long scrolling page). You can just add the following to your CSS -
html {
overflow-y: scroll;
}
.modal-open {
padding-right: 0!important;
}
I came around same issue and I solved it as follows
just add
body.modal-open {
position: fixed;
overflow: scroll;
width: 100%;
padding-right: 0!important;
}
I manually change bootstap.js:
before change
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
}
Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', '')
}
after change:
Modal.prototype.setScrollbar = function () {
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
var headerPad = parseInt(($('.navbar-fixed-top').css('padding-right') || 0), 10)
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
if (this.bodyIsOverflowing) $('.navbar-fixed-top').css('padding-right', headerPad + this.scrollbarWidth)
}
Modal.prototype.resetScrollbar = function () {
this.$body.css('padding-right', '')
$('.navbar-fixed-top').css('padding-right', '')
}
I have a structure:
<html>
<body>
<nav class="navbar navbar-fixed-top">...</nav>
<section>
<div class="container">...</div>
</section>
<section>
<div class="container">...</div>
</section>
<footer>...</foter>
</body>
</html>
I'm using this CSS:
body.modal-open {padding-right: 0 !important}
body.modal-open nav,
body.modal-open section,
body.modal-open footer {padding-right: 17px !important}
Add the following to your CSS:
body {
overflow: inherit;
padding-right: 0 !important;
}
For Bootstrap 4 sticky-top, use the following snippet. Tested all the CSS solutions on this page but none worked for Bootstrap 4.
<script type="text/javascript">
$('body').on('show.bs.modal', function () {
$('.sticky-top').css('margin-left', '-=0px');
});
$('body').on('hidden.bs.modal', function () {
$('.sticky-top').css('margin-left', 'auto');
});
</script>
My page design was as follows
<header class="container">
<div class="row">
</div>
</header>
<div class="container sticky-top">
<nav class="navbar navbar-expand-lg">
This div jumped/shifted 17px to the right when opening a modal
</nav>
</div>
In my case, it can be solved by adding comments or remove these two lines right: 0; and left: 0; in bootstrap.css file:
.navbar-fixed-top,
.navbar-fixed-bottom {
position: fixed;
/* right: 0;
left: 0; */
z-index: 1030;
}
Note: I use bootstrap v3.3.7
In 4.5, the following code solved my issue of the fixed header sliding left.
body.modal-open {
position: fixed;
overflow-y: scroll;
width: 100%;
padding-right: 0!important;
}
.modal-open .fixed-top {
padding-right: inherit!important;
}

Hide my div using <a href="#nice">

I'm working on a project where I need to hide a div when the a x is clicked. I'm wanting to target a specific div to be closed, the div that is holding the href nice. I'm getting a bit stuck with targeting the div once the X is clicked. Could you give any pointers for simple designer?
HTML
Div name = footer and the link class is "linky"
CSS
.linky:link {
footer:display: none;
}
Any help would be appreciated.
Regards,
Put the link target directly before the footer:
<body>
hide footer
... other content ...
<div id="linky"></div>
<footer>footer</footer>
</body>
the use the + operator:
#linky:target + footer {
display: none;
}
/* to prevent scrolling to the bottom */
#linky {
position: fixed;
top: 0;
}
see this fiddle
a + b will target b if it is directly after a.
Note the two additional differences from your version:
Use :target instead of :link (:link will target links)
Use id instead of class
I'd like to add that the footer will be visible again as soon as the user clicks on any other #anchor link.
Update: Now preventing scrolling; removed simple version because scrolling can not be prevented there
Try this:
<div id="div1">
Hello, i will be hidden on click the below link
</div>
<b>Click here</b> to hide
## this is the link code
<a href="" id="link" onClick="hide()"><b>Click here</b> to hide
<script>
function hide(){
document.getElementById('div1').style.display="none";
}
</script>

<ul> with overflow-y: auto and <li>s with relative position behaves oddly

I've the following mark up
<div class="row-fluid">
<div class="span4">
<ul class="test">
<li>Arun</li>
<li>Krishna</li>
<li>Soundar</li>
</ul>
</div>
</div>
And css
.test {
height: 500px;
margin-top: 10px;
overflow-y: auto;
padding: 10px 4px 70px;
}
And script
$('.test li').draggable({
revert: 'invalid'
})
If you drag the items to the right side, it disappears, I don't know why it is behaving so.
If the overflow-y: auto; style is removed from .test it works fine.
Demo: Fiddle
You may have to increase the width of the preview tab because of the responsive css to replicate the issue in the fiddle
I know this is an old question, but I think I found an answer. The reason the list disappears is because you drag it off the edge of the div and it begins to auto scroll. So, you you just remove it from the flow of the page when it is clicked on, like so:
$('.test li').draggable({
revert: 'invalid'
}).mousedown(function() {
var that = $(this);
//create div to fill the vacated space
$div = $('<div></div>');
$div.width(that.width());
$div.height(that.height());
$div.insertAfter(that);
//remove from flow of the page, set a different background color to see it work
that.css({'position':'absolute'});
});
New fiddle here
The problem with the CSS on bootstrap-combined.min.css. It sets some width due to that it causes the issue.
So remove bootstrap-combined.min.css and try.
Refer LIVE DEMO
UPDATE:
Add border: 1px solid; to your .test class then you will see the actual difference, why it is working if you comment overflow
If you debug on firebug, you will see below CSS class (that is from bootstrap-combined.min.css) is causing your issue
.row-fluid .span4 {
width: 31.4917%;
}
All you required was, the 'min-width:1100px', and 'width:100%;'
I have updated fiddle for you
Fiddle Link : http://jsfiddle.net/br57F/5/
Its working fine. overflow works with content, while draggable, will not add content to parent div. it will just change position in run time of the element.
I hope this will do :)
Just during drag, wrap dragged element by a div include position:absolute style.
So instead this code:
$('.test li').draggable({
revert: 'invalid'
})
Use this one:
$('.test li').draggable({
revert: 'invalid',
start: function(event, el){
$(el.helper[0]).wrap( "<div style='position:absolute;'></div>" );
},
stop: function(event, el){
$(el.helper[0]).unwrap();
}
});
Live Demo

css scrolling too soon

I pretty much got it down packed now. Just a quick thing I want to know how to fix.
I have this post comment button (it scrolls perfectly) however, it scrolls too soon even when you're not even past it's point. Live example:
http://www.krissales.com/#/media/38.Testing-Another-One-Yo
the CSS I have is this:
<div style="float:right;position:fixed;right:14%;padding-top:35px;" style="top: 0px;">
<span class="-paper">Post Comment</span>
</div>
would you guys know how I could go about fixing this? If you still don't understand, basically when I'm at the top of the page, and i scroll just a little, the "post comment" bar moves, I don't want it to move until i get past the area, then it should scroll.
thanks!
First of all, give the button a class and remove inline styles as that is bad practice. Second, create a second class that you'll attach for when you want it fixed. So that you can better understand what I mean, test the following code:
html:
<div class="box"></div>
<div class="box">
<div class="testBox">test</div>
</div>
<div class="box"></div>
css:
.box { height:500px; }
.testBox { background-color:#000000; color:#FFFFFF; width:100px; height:30px; }
.textBoxFixed { position:fixed; top:0; }
javascript:
$(function() {
$(document).scroll(function() {
var scrollFromTop = $(document).scrollTop();
if (scrollFromTop >= 500) {
$('.testBox').addClass('textBoxFixed');
} else {
$('.testBox').removeClass('textBoxFixed');
}
});
});
Read this link, what ou need is a mix between js and css fixed and relative position around the div and read (by jquery) when the divreach the top

How do I force a DIV to extend down to the bottom of the screen?

This is probably not possible with CSS, but maybe I'm wrong:
I have a document structure like this:
BODY
DIV[A]
DIV[B]
DIV[A] is position:absolute with fixed with and centered on screen. It has no height setting.
DIV[B] is position:absolute with top:300px. This is the actual content DIV. Inside that, I position everything with position:absolute. Because I love position:absolute. It gives full control over positioning. No ugly text flow headaches... it's so nice.
Ok. But the problem now: DIV[B] is always only that height what I tell it to be. Now, maybe there's a cool CSS trick that would pull it always down to touch the bottom of the browser viewport?
To set the height to dynamically be the window height - DIV[A]'s height, you'll have to use JavaScript/jQuery and keep calling it with a SetTimeout.
Alternately, if it suits your needs, you can set DIV[B] to be position:fixed; bottom:0px;
<body onload="setupLayout();" >
...
<script language="javascript" type="text/javascript">
// ACTIVITIES TO RUN FOR THE PAGE
function setupLayout() {
setInterval('adjustLayout();', 1000);
}
// ADUST THE MAIN CONTAINER (content panel) LAYOUT
function adjustLayout() {
try {
var divB = $get('divB');
var divAHeight = 20px;
divB.style.height = document.body.clientHeight - divAHeight ;
}
catch (e) { }
}
</script>
</body>
#div_to_touch_the_bottom {
position:fixed;
bottom:0;
top:0;
left:25%;
right:25%;
}
This DIV will touch the bottom of viewport, you can modify its left and right according to your needs. I am not sure that this the answer you are lookign for but it could be a good start
When you want DIV to be a position:absolute, it should be in a position: relative container.
<div style="position: relative">
<div style="position: absolute; top: 300px">
<h3>Content Header</h3>
<!-- Content -->
</div>
</div>
So regarding your problem with DIV[B], you can mix between <table>s and <div>s.
I suppose DIV[A] is your header and DIV[B] your main content div and you would like to always have your content div take all the page when there is not a lot of text in it, right?
If I remember correctly, because I can't test it at the moment, you could:
html, body {
height: 100%;
}
DIV[B] {
height: 100%;
}
I think that should do the trick.
Edit: Here is a good example that might help you: http://www.xs4all.nl/~peterned/examples/csslayout1.html

Resources