make div 100% of browser height depending on length of content - javascript

I have 2 divs, a navigation and a main content in a bootstrap grid system. The length of either can vary depending on amount of content. I need them both styled to fill 100% of the browser window IF neither has the content to reach the bottom naturally. But if at least one of the divs has more content than the length of the browser window, I need to be able to scroll down the page with the styles of both divs remaining in tact and both have a height of the longer of the 2 divs.
I'm currently using a javascript resize function which seems to work but not in the case where neither div is long enough to fill the height of the browser window. Any suggestions?
HTML
<div class="row">
<div id="nav" class="col-xs-2">
Variable Height Navigation
</div>
<div id="main" class="col-xs-10">
Variable Height Content
</div>
</div>
Javascript
function resize() {
var h = (document.height !== undefined) ? document.height : document.body.offsetHeight;
document.getElementById("nav").style.height = h + "px";
}
resize();
window.onresize = function () {
resize();
};

I am trying to understand you question, and if I'm correct what you are looking for is:
Both divs need to be equally high
They need be at least the height of the screen
They need to take the height of the highest div
So let's try to achieve this goal as simply as possible:
var main = document.getElementById('main');
var nav = document.getElementById('nav');
function resize(){
var highest;
// Set the divs back to autosize, so we can measure their content height correctly.
main.style.height = 'auto';
nav.style.height = 'auto';
// Find the highest div and store its height.
highest = main.clientHeight > nav.clientHeight
? main.clientHeight
: nav.clientHeight;
// Check if the highest value is the div or the window.
highest = highest > window.innerHeight
? highest
: window.innerHeight;
// Assign the newly found value
main.style.height = highest + 'px';
nav.style.height = highest + 'px';
}
resize();
// Also, you don't need to wrap it in a function.
window.resize = resize;
// However, better would be:
window.addEventListener('resize', resize, false);
#main, #nav {
width: 100%;
height: auto;
}
#main { background: red; }
#nav { background: green; }
<div id="main"></div>
<div id="nav"></div>
Now, If you aren't bothered with the actual sameness in heiught of both divs but just want them to at least be one screenful, you should consider using CSS:
html, body { height: 100%; }
#nav, #main { min-height: 100%; }
I think that is the better solution (no Javascript!) and sort-of does what you want, bar the fact that you won't have to equally high div elements. However, you would barely notice it as each will at least fill the page.

You could try using viewport height:
For example:
#nav {
min-height: 100vh;
}
#main {
min-height: 100vh;
}
See Bootply.
This will also remove the need for JavaScript.

Related

Convert vh units to px in JS

Unfortunately 100vh is not always the same as 100% browser height as can be shown in the following example.
html,
body {
height: 100%;
}
body {
overflow: scroll;
}
.vh {
background-color: blue;
float: left;
height: 50vh;
width: 100px;
}
.pc {
background-color: green;
float: left;
height: 50%;
width: 100px;
}
<div class="vh"></div>
<div class="pc"></div>
The issue is more pronounced on iPhone 6+ with how the upper location bar and lower navigation bar expand and contract on scroll, but are not included in the calculation for 100vh.
The actual value of 100% height can be acquired by using window.innerHeight in JS.
Is there a convenient way to calculate the current conversion of 100vh to pixels in JS?
I'm trying to avoid needing to generate dummy elements with inline styles just to calculate 100vh.
For purposes of this question, assume a hostile environment where max-width or max-height may be producing incorrect values, and there isn't an existing element with 100vh anywhere on the page. Basically, assume that anything that can go wrong has with the exception of native browser functions, which are guaranteed to be clean.
The best I've come up with so far is:
function vh() {
var div,
h;
div = document.createElement('div');
div.style.height = '100vh';
div.style.maxHeight = 'none';
div.style.boxSizing = 'content-box';
document.body.appendChild(div);
h = div.clientHeight;
document.body.removeChild(div);
return h;
}
but it seems far too verbose for calculating the current value for 100vh, and I'm not sure if there are other issues with it.
How about:
function viewportToPixels(value) {
var parts = value.match(/([0-9\.]+)(vh|vw)/)
var q = Number(parts[1])
var side = window[['innerHeight', 'innerWidth'][['vh', 'vw'].indexOf(parts[2])]]
return side * (q/100)
}
Usage:
viewportToPixels('100vh') // window.innerHeight
viewportToPixels('50vw') // window.innerWidth / 2
The difference comes from the scrollbar scrollbar.
You'll need to add the height of the scrollbar to the window.innerHeight. There doesn't seem to be a super solid way of doing this, per this other question:
Getting scroll bar width using JavaScript

Adjust text size dynamically within div and also responsive

I have two working JSFiddle which I want to combine and work together.
JSFiddle-1 : http://jsfiddle.net/MYSVL/3050/
window.onresize=function() {
var child = $('.artist');
var parent = child.parent();
child.css('font-size', '18px');
while( child.height() > parent.height() ) {
child.css('font-size', (parseInt(child.css('font-size')) - 1) + "px");
}
Here the text inside artist container is responsive and its stretching to maximum font size when the screen is bigger. Its also shrinking to smallest font size when screen size is smaller.
JSFiddle-2 : http://jsfiddle.net/MYSVL/3047/
function calcDivHeights() {
window.onresize=$(".artist").each(function () {
var child = $(this);
var parent = child.parent();
//child.css('font-size', '18px');
while (child.height() > parent.height()) {
child.css('font-size', (parseInt(child.css('font-size')) - 1) + "px");
}
});
}
Here the function is checking for every artist div and adjusting the font size according to the while condition but I am unable to make it responsive like my JSFiddle-1 . Once the text size is smaller it remains smaller even I make the screen bigger. I want my JSFiddle-2 to work exactly as JSFiddle-1 so that I can maintain the responsiveness of the text according to screen size.
Can someone please help me out or feel free to modify my JSFiddle-2 in order to achieve the goal.
Thanks in advance
I can't see differences between your two fiddles except for the commented child.css('font-size', '18px'), both should do the same thing.
Your second fiddle seems to not works properly because once you resize window to a smaller resolution, child becomes smaller or equal to parent. Then, when you return on bigger resolution, you call again while( child.height() > parent.height() ), but now your child height is not greater than your parent height.
I think the following will just do what you're asking for:
$(document).ready(function () {
function adjustFontSize() {
var child = $('.artist');
var parentHeight = child.parent().height();
while( child.height() > parentHeight ) {
child.css('font-size', (parseInt(child.css('font-size')) - 1) + "px");
}
while( child.height() < parentHeight ) {
child.css('font-size', (parseInt(child.css('font-size')) + 1) + "px");
}
};
adjustFontSize(); // Call it when document is ready
window.onresize = adjustFontSize; // Call it each time window resizes
});
.artist-container {
width: 20%;
height: 40px;
border: 1px solid black;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="artist-container">
<div class="artist">Audhit Audhit Audhit Audhit Audhit Audhit Audhit</div>
</div><br>
<div class="artist-container">
<div class="artist">Lorem</div>
</div><br>
I think the CSS media queries approach is so much better for making a web responsive, than calculating everything with Javascript all the time.
For example, you can think about three sizes:
Phone (lets say, 400px width)
Tablet (lets say, 800px width)
Computer (lets say, >800px width)
One way of achieving this, using the desktop first approach, would be:
/* DESKTOP */
body {
font-size: 1em;
...
}
...
/* General rules for desktop
...
/* TABLET */
#media screen and (max-width:800px and min-width:400px) {
/* Overwrite the rules you want to change */
body {
font-size: .75em;
}
...
}
/* PHONE */
#media screen and (max-width:400px) {
/* Overwrite the rules you want to change */
body {
font-size: .75em;
}
#div1 {
height: 20%;
}
...
}
In addition to this, don't forget to work with relative units (em, vw, vh, rem...) and percentages.
Here you have a really good link about responsive design.

Jquery event capture change in margin-left

I have a situation in here I have a div that was margin: auto to get it to be centered.
That works fine, but when I resize the window I want it to stop centering when a certain margin-left is reached.
The ideia is that I have a floating object to the left, and I dont want it to be overlapped.
Anybody as a suggestion?
Thanks
EDIT: Code Addded
<nav id="servicos_nav">
<div id="full">
...
</div>
<div id="minimized">
...
</div>
</nav>
<section id="content">
… PHP generated code …
</section>
The nav is absoluted possitioned because it was some effects, changind minimized by full with animations.
Section content as width of 860px and margin auto. But there is and element in the nav that always as 140px width and I dont want that minimizing the window causes the content to overlap with that element.
SolutionEdit: My solution based on the awnser (the static width was just easier :-) ):
window.onresize = function(event) {
if(window.innerWidth <= 1142)
{
$("#content").css("margin-left","140px");
}
else
{
$("#content").removeAttr("style");
}
};
You may have to work on the math as this is not my strong point but something like this should work
var contentWidth = $('#content').width();
var leftWidth = $('#left').width();
$(window).resize = function(event) {
var windowWidth = window.innerWidth;
if (windowWidth <= (contentWidth + (leftWidth * 2)) {
$('#content').css('margin-left', leftWidth);
} else {
$('#content').css('margin-left', 'auto')
}
}
demo
Edit: changed to use jQuery .resize rather then override onresize
You could use the offset of #content.
$(window).resize = function(event) {
if ($('#content').offset().left < leftWidth) {
$('#content').css('margin-left', leftWidth);
} else {
$('#content').css('margin-left', 'auto')
}
}
elements that have margin 0px auto don't have an accessible margin left. That means an element with margin: 0px auto will have margin-left and margin-right equal to 0.
The solution lies in CSS, not in Javascript. You could, and should rethink your layout. Here, this is a way of doing it with css min width.

Detect users position on web page

Let's say I have a single HTML page. 2000 pixels long for example. I want to detect if a visitor reaches a certain point on the page.
The page structure:
0px = begin of the page;
500px = about us page;
1000px = contactpage;
Is there a way with jQuery to detect if a user reaches the points described above?
You probably want jQuery's scroll event-binding function.
Yes, I would create three divs and then have a mouse over event on each. Example:
$("#begin").mouseover(function(){
alert("over begin");
});
$("#about").mouseover(function(){
alert("over about");
});
$("#contact").mouseover(function(){
alert("over contact");
});
You can see a working fiddle here: http://jsfiddle.net/ezj9F/
Try THIS working snippet.
Using this code you don't have to know position of the element you want to check if it is visible.
JQuery
var $window = $(window);
// # of pixels from the top of the document to the top of div.content
var contentTop = $("div.content").offset().top;
// content is visible when it is on the bottom of the window and not at the top
var contentStart = contentTop - $window.height();
// content is still visible if any part of his height is visible
var contentEnd = contentTop + $("div.content").height();
$window.scroll(function() {
var scrollTop = $window.scrollTop();
if(scrollTop > contentStart && scrollTop < contentEnd) {
console.log('You can see "HELLO"!');
} else {
console.log('You cannot see "HELLO"!');
}
});
HTML
<div class="scroll"></div>
<div class="content">HELLO</div>
<div class="scroll"></div>
CSS
div.scroll {
background-color: #eee;
width: 100px;
height: 1000px;
}
div.content {
background-color: #bada55;
width: 100px;
height: 200px;
}
EDIT: Now the algorithm is checking if any part of the div.content is visible (it is considering height of the element). If you are not interested in that change contentEnd to var contentEnd = contentTop.

How to reliably get screen width WITH the scrollbar

Is there a way to reliably tell a browser's viewport width that includes the scrollbar, but not the rest of browser window)?
None of the properties listed here tell me the width of the screen INCLUDING the scrollbar (if present)
I figured out how to accurately get the viewport width WITH the scrollbar using some code from: http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript
Put this inside your $(document).ready(function()
$(document).ready(function(){
$(window).on("resize", function(){
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
});
// Get the correct window sizes with these declarations
windowHeight = viewport().height;
windowWidth = viewport().width;
});
What it Does:
When your page is 'ready' or is resized, the function calculates the correct window height and width (including scrollbar).
I assume you want to know the viewport width with scrollbar included, because the screen it self does not have a scrollbar. In fact the Screen width and heigth will be the computer screen resolution itself, so I'm not sure what you mean with screen width with the scroll bar.
The viewport however, the area where only the page (and scroll bars) is presented to the user, meaning, no browser menus, no bookmarks or whatever, only the page rendered, is where such scroll bar may be present.
Assuming you want that, you can measure the client browser viewport size while taking into account the size of the scroll bars this way.
First don't forget to set you body tag to be 100% width and height just to make sure the measurement is accurate.
body {
width: 100%;
// if you wish to also measure the height don't forget to also set it to 100% just like this one.
}
Afterwards you can measure the width at will.
Sample
// First you forcibly request the scroll bars to be shown regardless if you they will be needed or not.
$('body').css('overflow', 'scroll');
// Viewport width with scroll bar.
var widthWithScrollBars = $(window).width();
// Now if you wish to know how many pixels the scroll bar actually has
// Set the overflow css property to forcibly hide the scroll bar.
$('body').css('overflow', 'hidden');
// Viewport width without scroll bar.
var widthNoScrollBars = $(window).width();
// Scroll bar size for this particular client browser
var scrollbarWidth = widthWithScrollBars - widthNoScrollBars;
// Set the overflow css property back to whatever value it had before running this code. (default is auto)
$('body').css('overflow', 'auto');
Hope it helps.
As long as body is 100%, document.body.scrollWidth will work.
Demo: http://jsfiddle.net/ThinkingStiff/5j3bY/
HTML:
<div id="widths"></div>
CSS:
body, html
{
margin: 0;
padding: 0;
width: 100%;
}
div
{
height: 1500px;
}
Script:
var widths = 'viewport width (body.scrollWidth): '
+ document.body.scrollWidth + '<br />'
+ 'window.innerWidth: ' + window.innerWidth + '<br />';
document.getElementById( 'widths' ).innerHTML = widths;
I put a tall div in the demo to force a scroll bar.
Currently the new vw and vh css3 properties will show full size including scrollbar.
body {
width:100vw;
height:100vh;
}
There is some discussion online if this is a bug or not.
there is nothing after scrollbar so "rest of the window" is what?
But yes one way to do it is make another wrapper div in body where everything goes and body has overflow:none; height:100%; width:100%; on it, wrapper div also also has 100% width and height. and overflow to scroll. SO NOW...the width of wrapper would be the width of viewport
See Example: http://jsfiddle.net/techsin/8fvne9fz/
html,body {
height: 100%;
overflow: hidden;
}
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
}
With jQuery you can calculate the browser's scrollbar width by getting the width difference when overflow: hidden is set and overflow: scroll is set.
The difference in width will be the size of the scrollbar.
Here is a simple example that shows how you could do this.
You can get the window width with scrollbar , that way:
function scrollbar_width() {
if (jQuery('body').height() > jQuery(window).height()) {
/* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append(calculation_content);
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return (width_one - width_two);
}
return 0;
}
Check out vw: http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
body {
width: 100vw;
}
http://caniuse.com/#search=vw
This is my solution for removing the 'scrollbar shadow', because scrollWidth didn't work for me:
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
It's easy, but it works. Make sure to add a comment explaining why you assign the same value twice :)

Categories