Have you ever seen those web applications that have a pane on the left hand side and a main body and somehow it fits it all into the size of your browser window (viewport) what ever browser/device you use or screen size you have and it doesn't show your browser's scroll bars? I'm talking about the height of the left pane and the body adjusting automatically to the height of your browser window.
Have you ever tried searching for how they do it? I tried and couldn't find a straight answer. I'm no javascript nerd so I had to figure this out the hard way with trial and error. To save any of you some time here is my solution using a little CSS and some responsive javascript (jQuery):
Scenario:
I have a typical page with a banner at the top and a navigation bar just below it, and I want my web application-style left pane and main body pane to fit into the vertical white space of the page body that is not already occupied by the banner or navigation bar. My HTML looks a little like this:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css.css">
<script src="jquery.js"></script>
<script src="js.js"></script>
</head>
<body>
<div id="container">
<div id="banner"></div>
<div id="nav"></div>
<div id="webapp">
<div id="leftpane"></div>
<div id="mainbody"></div>
</div>
</div>
</body>
</html>
So, for this example, my main concern is the #leftpane div. If you understand the code for that, you can duplicate the approach for the #mainbody. (To be honest, I'm writing this post here before I tackle mainbody next)
The CSS for leftpane is:
#leftpane{
margin:0 auto;
float:left;
border:1px solid darkgreen;
background-color:rgba(0, 0, 150, .15);
vertical-align:top;
width:30%;
overflow-y:auto;
}
Notice there is no mention of position:absolute. That's because this example is NOT about filling the page from top to bottom with the left pane. If you want that kind of information, then google will easily find you that. Instead, what we are doing here is having the top of the div element be in its normal position, while the bottom border of the div will expand vertically depending on the size of the window/viewport. I only care about the height of the div in my example. Widths are managed with width: n% and using min-width:n px, but I will not discuss widths any further.
Anyway. How do we get the leftpane to expand according to size of the window? With a bit of Javascript (jQuery). The javascript below is responsive. When the page first loads it calls the snapLeftpane() function and resizes the leftpane and then if the user makes their window bigger or smaller, it calls the snapLeftpane() function again to resize the leftpane again.
But I set some limits. If the window becomes too small, like if the user is messing about and makes their browser window too small, then it snaps the leftpane to the minimum height allowable. And in the opposite situation, when the user has a huge window, it limits the height of the leftpane to the maximum height allowable, so the web app doesn't look ridiculously disproportioned.
Here's the javascript:
function snapLeftpane(){
var minHeight = 450,
maxHeight = 800,
wHeight = $(window).height();
var el = $('#leftpane');
if(el.length){
var top = el.offset().top + 5;
if(wHeight >= minHeight && wHeight <= maxHeight) {
el.height((wHeight - top) + "px");
console.log('naturally expanding height ' + el.height());
} else if (wHeight > maxHeight) {
el.height(maxHeight + "px");
console.log('set to max height ' + el.height());
} else if (wHeight < minHeight) {
el.height(minHeight + "px");
console.log('set to min height ' + el.height());
}
}
}
$(window).on('resize load', function(){snapLeftpane();});
And if you run this code in your browser and play around with the size of the browser window, you will see how it adjusts the height of the left pane accordingly or snaps it to the minimum height or maximum height if you make the window too small or too large. I recommend you modify the min and max heights to your preferences.
That's it. Hope this helps :)
Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts
Tuesday, 19 March 2013
Friday, 4 November 2011
Quick JQuery expanding vertical menu
I'm just posting this as a reference for myself primarily, but if it helps anyone else then that's great. This is a super quick expanding vertical menu. You can animate it by passing 'slow' or 'fast' as an argument to the toggle() method.
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.branch').click(function(){
$(this).children('.subbranch').each(function(){
return $(this).toggle();
});
});
});
</script>
<ul class='tree'>
<li class='branch'><a href='#'>Super Title 1</a>
<ul class='subbranch' style='display:none'>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
</ul></li>
<li class='branch'><a href='#'>Super Title 2</a>
<ul class='subbranch' style='display:none'>
<li><a href="#">Item 4</a></li>
<li><a href="#">Item 5</a></li>
<li><a href="#">Item 6</a></li>
</ul></li>
</ul>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.branch').click(function(){
$(this).children('.subbranch').each(function(){
return $(this).toggle();
});
});
});
</script>
<ul class='tree'>
<li class='branch'><a href='#'>Super Title 1</a>
<ul class='subbranch' style='display:none'>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
</ul></li>
<li class='branch'><a href='#'>Super Title 2</a>
<ul class='subbranch' style='display:none'>
<li><a href="#">Item 4</a></li>
<li><a href="#">Item 5</a></li>
<li><a href="#">Item 6</a></li>
</ul></li>
</ul>
Thursday, 10 February 2011
JQuery Hover Effect on Current, Previous and Next elements
I created this simple effect with JQuery and a little bit of CSS. What is does is if you move your mouse cursor over a link it calls the .hover() function and then it applies a class style using .addClass() to the element you hovered over with the mouse and in addition to this is applies a style to its adjacent neighbours using .next() and .prev() to select the links to which to apply the style.
The code is really simple. First off, you use a hover function. The first argument you pass to it is what to do when the mouse hovers over the element. I use .addClass() to apply a style to the element being hovered over ($(this)). The next argument to pass to the function is what to do when the mouse moves off the element and I use .removeClass() to reset the style of the element back to how it was. I encapsulate the arguments in anonymous functions.
In order to access the elements adjacent to that being selected you can use the .next() and .prev() functions, so if, for example, I had a list of 3 items and was hovering over the second one, I can use prev() to have access to the first element and next() to access the third element. When I move the mouse to highlight the first element, there is no previous element so it doesn't select anything to the left but the next element is still there and is accessible. If I highlight the third element then there is no next element so it only has the previous element to select.
Anyway, here's the javascript code:
$(document).ready(function(){
$('a.link').hover(
/*Carry this out when the mouse hovers over the element*/
function(){
$(this).addClass('bigger');
$(this).next().addClass('big');
$(this).prev().addClass('big');
},
/*Carry this out when the mouse moves off the element*/
function(){
$(this).removeClass('bigger');
$(this).next().removeClass('big');
$(this).prev().removeClass('big');
}
)
});
Now, the CSS to align the elements when the font size got bigger was not straightforward. One would assume that you need to use a combination of vertical-align:middle and display:table-cell or display:inline-block but these didn't do what I wanted. In the end I found the best way to solve the problem was to give the container element (div) a height and then use a large line-height, a large margin-top and text-align:bottom to allow the text to get bigger and not interfere with the content above or below it:
div {height:1.2in; width:100%; border:1px solid black;}
a {margin-top:50px; vertical-align:bottom; line-height:100px; text-decoration:none;}
You can download the code here: http://www.mediafire.com/?kydzwwl4bb4ogjk
And it's under the public domain license so you're free to do what you like with it.
The code is really simple. First off, you use a hover function. The first argument you pass to it is what to do when the mouse hovers over the element. I use .addClass() to apply a style to the element being hovered over ($(this)). The next argument to pass to the function is what to do when the mouse moves off the element and I use .removeClass() to reset the style of the element back to how it was. I encapsulate the arguments in anonymous functions.
In order to access the elements adjacent to that being selected you can use the .next() and .prev() functions, so if, for example, I had a list of 3 items and was hovering over the second one, I can use prev() to have access to the first element and next() to access the third element. When I move the mouse to highlight the first element, there is no previous element so it doesn't select anything to the left but the next element is still there and is accessible. If I highlight the third element then there is no next element so it only has the previous element to select.
Anyway, here's the javascript code:
$(document).ready(function(){
$('a.link').hover(
/*Carry this out when the mouse hovers over the element*/
function(){
$(this).addClass('bigger');
$(this).next().addClass('big');
$(this).prev().addClass('big');
},
/*Carry this out when the mouse moves off the element*/
function(){
$(this).removeClass('bigger');
$(this).next().removeClass('big');
$(this).prev().removeClass('big');
}
)
});
Now, the CSS to align the elements when the font size got bigger was not straightforward. One would assume that you need to use a combination of vertical-align:middle and display:table-cell or display:inline-block but these didn't do what I wanted. In the end I found the best way to solve the problem was to give the container element (div) a height and then use a large line-height, a large margin-top and text-align:bottom to allow the text to get bigger and not interfere with the content above or below it:
div {height:1.2in; width:100%; border:1px solid black;}
a {margin-top:50px; vertical-align:bottom; line-height:100px; text-decoration:none;}
You can download the code here: http://www.mediafire.com/?kydzwwl4bb4ogjk
And it's under the public domain license so you're free to do what you like with it.
Subscribe to:
Posts (Atom)