Fixed sidebar too tall for browser (bottom is getting cut off) - javascript

Let's say I have a fixed sidebar that is XXpx tall (Refer to http://www.getskeleton.com/ if you want a visual of what I mean). The sidebar looks exactly the way I want, as long as the height of the browser is bigger than the sidebar. However, when the browser height shrinks below the height of the sidebar, the bottom contents get cut off.
Initially, the sidebar has position: fixed, but if the browser gets too small to contain the entire sidebar, I want to change it to position: aboslute. Essentially, I'd like to make it so on both page load and any time the user resizes finishes resizing the page it will check to make sure that the bottom content isn't being cut off, then assign the appropriate position attribute.

You could use a vertical media query for this, like so (let's say the sidebar is 700px tall.)
#sidebar {
position: absolute;
}
media screen and (min-height:700px) {
#sidebar { position: fixed; }
}
By declaring the absolute position first, you make sure that browsers that don't support media queries will get the absolutely positioned sidebar, which will still be functional.

Do something like this:
var $sidebar = $('#idOfSidebar')
,$w = $(window);
$w.resize(function () {
var pos = $w.height() < $sidebar.height()? 'absolute': 'fixed';
$sidebar.css({position: pos});
});

An option is to use overflow: auto for fixed blocks that can be potentially taller than browser`s client height. This can be used as default pure-CSS solution that can work in conjunction with JavaScript methods.

Related

Add sidebar to the right of webpage that resizes and shifts everything accordingly

I'm creating an Chrome Extension, which should add sidebar to all webpages.
This sidebar shouldn't overlap webpage content, it should be placed next to the existing content, essentially shrinking width of body of webpage to initial width - sidebar width.
This is the code I came up with, but I have a problem with some pages like stackoverflow for instance, see how top bar doesn't shrink like the rest of the page does (screenshots attached below the code)
// create sidebar
const sidebar = document.createElement("iframe");
sidebar.src = chrome.extension.getURL("iframe/iframe.html");
sidebar.id = "extensionSidebar";
sidebar.frameBorder = "0";
sidebar.style.height = "100%";
sidebar.style.width = "100px";
sidebar.style.position = "fixed";
sidebar.style.top = "0";
sidebar.style.right = "0";
sidebar.style.zIndex = "2147483646";
// append sidebar to body
document.documentElement.appendChild(sidebar);
// shrink body
document.body.style.width = window.innerWidth - 100 + "px";
Screenshots:
https://prnt.sc/o215x5
https://prnt.sc/o21637
The top bar doesn't shrink as you would like it to do because it is fixed, it will always take 100% of the viewport width. Its CSS properties on your example with stackoverflow are :
...
position: fixed;
top: 0;
left: 0;
width: 100%; /*though it's not "really" 100vw*/
...
Even by changing the html element in CSS, in order to change its maximum size to 80% of the viewport width for instance, the navbar would still take all the viewport's width.
To understand it you can try the following fiddle, it might speak for istelf : https://jsfiddle.net/bcg2vkjm/4/
On it you can "un-comment" the body element inside the CSS and see the result, it might give you some help ! Though it only applies a scale of 1 (so it should not change...), for some reason it makes the fixed element adapt to the body size, which is what you want, you just might have to play along with the translateX and/or scale in the CSS, but it might be a risky solution because it changes quite a lot the way everything is displayed, not only the fixed element, as you can see.
In your javascript you can try the following :
document.querySelector('body').style.transform = "scaleX(something)";
for instance !

Disable scrolling but keep scrollbar CSS

I can't find a solution to this, there was a question over here, but the answers are not very usable (at least for me).
I have a JavaScript modal pop-up that disables everything on the background by placing transparent div over the page. It also disables the scrolling by setting the overflow to hidden, and must do so, because the page is scrollable with the mouse wheel otherwise and distracts the user.
The problem is, when hiding and showing the scrollbar the page resizes and the effect is ugly. Also, my page is designed in such a way that if I stop it from resizing that would be ugly either.
What I want is to disable the scrollbar, but keep it visible (the page content is longer than the screen fits). Is this somehow possible in CSS?
Instead of changing the css, which will remove the scrollbar, and as you said change the layout of the page, try calling a jquery function instead.
// call your pop up and inside that function add below
$('body').on('scroll mousewheel touchmove', function(e) {
e.preventDefault();
e.stopPropagation();
return false;
});
then when you close the modal, call the same function but replace on with off
Since scrollbars are not all 17px wide, I solved this with JavaScript. That is, I calculated the exact width of the scrollbar and added an equal amount of margin to the right of the body element. This also works when the scrollbar isn't present due to a high resolution or a lack of content.
function toggleMenu() {
// get width before hiding scrollbar
let oldWidth = document.documentElement.clientWidth;
// toggle CSS class that sets overflow to hidden
document.body.classList.toggle('MenuOpen');
// get new width after hiding scrollbar
let newWidth = document.documentElement.clientWidth;
// set margin-right value equal to width of the scrollbar
let scrollbarWidth = Math.max(0, newWidth - oldWidth);
document.body.style.marginRight = `${scrollbarWidth}px`;
}
...and my CSS looks like:
html {
background-color: #e6e6e6; /* color of fake scrollbar */
}
body.MenuOpen {
overflow: hidden;
}
Once you start showing your popup, give the body a class (like popupOpen). This should be an easy workaround.
.popupOpen {
overflow: hidden;
margin-right: 17px //size of the scrollbar in each browser
}
When you close your popup, simply remove the class from the body.

How to create a fixed / sticky sidebar in CSS / JS?

I'm trying to create a website with main content area and a sidebar, something like here on Stack Overflow. The goal is that when you scroll down, the sidebar stays visible.
I have seen two approaches to this:
position:fixed;
JavaScript manipulation with the DOM
Approach no. 1, as far as I know, will have a problem when the viewport is smaller than the sidebar contents so I guess that can't be used reliably and JavaScript scripts that I have seen are usually animated or generally "slow" (you can see that there is redrawing going on after each scroll).
Can someone point out a JavScript library / CSS approach that would not suffer from the aforementioned issues?
Edit: an example would be this page but with the sidebar sticking to the top without an animation and correctly handling the situation when the sidebar is higher than content / viewport.
I don't like heavy JS solutions, so important thing to ask is - preferred compatibility. In IE8+ it is possible instead of
var $window = $(window),
$sidebar = $(sidebar);
$window.on('resize', function(){
$sidebar.height($window.innerHeight());
});
$window.resize();
do something like this (pure CSS solution):
#sidebar {
position: fixed;
left: 0; /* or right */
top: 0;
bottom: 0;
overflow: auto;
}
When you have top&bottom / left&right value at the same time, box will be stretched. (JSFiddle demo)
Got it. It is Javascript based, but I'm sure that's nothing heavy and even IE8 should solve it pretty fine.
var top = $('#sidebar').offset().top;
var height = $('#sidebar').height();
var winHeight = $(window).height();
var gap = 10;
$(window).scroll(function(event) {
var scrollTop = $(this).scrollTop();
// sidebar reached the (end - viewport height)
if (scrollTop + winHeight >= top + height + gap) {
// if so, fix the sidebar and make sure that offset().top will not give us results which would cancel the fixation
$('#sidebar').addClass('fixed').css('top', winHeight - height - gap + 'px');
} else {
// otherwise remove it
$('#sidebar').removeClass('fixed').css('top', '0px');
}
});​
demo
You could catch client window's height and giving it to your sidebar like this :
var sidebarHeight = $(window).innerHeight();
$('#sidebar')​​​​​​​​​​​.css('height',sidebarHeight);​​​​​​​​​​​​​
With the proper CSS for the sidebar :
#sidebar {
position: fixed;
right: 0;
top: 0;
width: 200px;
overflow: hidden;
}
Here is a working JSFiddle.
You could also watch for window resizing to avoid a mess on resize :) Here is the way to go with jQuery
Good luck
Not sure if you have this figured out but I have created a contained sticky sidebar jQuery plugin. It's really simple and allows you to invoke with just one line of jQuery. Take a look here: http://mojotech.github.com/stickymojo/
It starts by position: fixed; then uses javascript to handle any resizes, scrolls and even allows you to specify a footer element that it should not intersect. By combining these approaches you will get a smooth looking fixed element. Plus, we made it easy for you.
Code and demo here: http://closure-library.googlecode.com/svn/docs/class_goog_ui_ScrollFloater.html

applying 'display:hidden' to a div at a certain window width using js

I am using media queries to make a responsive site. That isn't my problem but it is why I am here today with this question.
At a certain browser width, my horizontal navigation at the top of my page becomes too wide (becomes squished) and looks awkward in my layout. What I want to do is this: When a users browser reaches a certain min-width, I would like to (using js) hide the horizontal navigation (an unordered list of 6) that originally rendered on the users screen (if you are viewing wider than 650px) and replace it with a single 'button' that when clicked drops down the un-ordered list.
Now, the CSS isnt the problem. I just cant seem to figure out how to do the transition from the original horizontal nav that originally renders, to a more user friendly navigation.
A simple solution would be to have 2 sets of navigation mechanisms. Hide one and show the other.
You will need to add an eventlistener on the resize event for document, where you will check the innerWidth of the window and decide which navigation div to display.
document.addEventListener("resize", function () {
if (window.innerWidth < 650) {
document.getElementById("horizontal_nav").style.display = "block";
document.getElementById("dropdown_nav").style.display = "none";
} else {
document.getElementById("dropdown_nav").style.display = "none";
document.getElementById("horizontal_nav").style.display = "block";
}
});
Alternatively, you can keep your horizontal navigation but specify a max-width of 650px, once this has been reached, it will stop growing.
div#horizontal_nav {
width: 100%;
max-width: 650px;
}
Maybe these can help:
http://www.bram.us/2011/10/24/jquery-mobile-select-jquery-mobile-navigation-replacement-plugin/
https://github.com/joggink/jquerymobiledropdown
I know. It´s jQuery but I hope ppl get the general idea.

how to dynamically (re)position an element according to the bottom of the page using JS / Jquery?

the back story: i have a tab section on a page which when navigated through displays sections (divs) of varying height.
the result, is that certain inputs (which are strangely positioned for reasons i can't change) on this page reposition themselves problematically.
the proposed solution: as the page height changes, have these problem inputs repositioned according to the page bottom (from which their appropriate distances are always a constant).
what i'm thinking is that i need some js that does something like,
page height change triggers input position from bottom to = x.
there are two inputs if that's at all relevant. :)
if only there was css for this (i know there is under normal circumstances, but trust me -- not in this case).
thanks for your time & help i've been struggling with this for weeks!
It sounds like you just need to position the inputs absolutely to the bottom of a relatively positioned div. Like -
#form {
position: relative;
}
#inputs {
position: absolute;
bottom: 0;
}
<div id="form">
<div id="inputs">
<input id="weirdinput" />
</div>
</div>
If thats not enough to get you pointed in the right direction you will need to provide some sample code for the crowd to look over.
You could try something like this using the jQuery event for the resizing of a window:
$(window).resize(function() {
var windowHeight = $(window).height();//get new height of window
var desiredHight = windowHeight - 50;
$('input.myclass').css('top', desiredHeight.toString() );
});

Categories

Resources