Working on a project requiring old-school CSS support and want to keep <aside> filling up the page by remaining the same height as the <article> element's box (It may be between a header and footer, in which case it would not extend past them.)
<article id="article">
...
<aside id="sidebar">
Here's my attempt at dynamically setting the height. It doesn't seem to work.
<script>
function sidebarHeight() {
sidebar=window.document.getElementById('sidebar')
article=window.document.getElementById('article')
sidebar.style.height=article.style.height;
console.log('article.style.height: ' + article.style.height);
}
window.onresize=sidebarHeight;
</script>
This doesn't work because article.style.height always has the value "" instead of the current height. How can I keep the sidebar stretched vertically in sync with the article height?
By the way, can someone explain why the only way to get at properties like height, or at least color, which I know works, requires a call to getElementById()? If I use the more logical-sounding getElementsByTagName('article') I get access to a much more limited set of properties.
To get the calculated height onresize you need to use .offsetHeight and you need to add a unit to the returned value.
sidebar.style.height = `${article.offsetHeight}px`;
also, your DOM queries should just be called on document
sidebar = document.getElementById('sidebar')
article = document.getElementById('article')
article {
float: left;
height: 40vh;
width: 75vw;
background-color: gray;
}
aside {
float: right;
width: 20vw;
background-color: tomato;
}
<article id="article"></article>
<aside id="sidebar"></aside>
<script>
function sidebarHeight() {
sidebar= document.getElementById('sidebar')
article= document.getElementById('article')
sidebar.style.height= `${article.offsetHeight}px`;
}
window.onresize=sidebarHeight;
</script>
Related
I'm not sure what kind of keyword should I use to ask this question,
I already search this in Google but looks like my keyword is bad.
The problem is, I have two div relative element with dynamic content, meaning the height of this two element is not fixed and they are scrollable.
Let's say the first div has a class name of l-content stand for Left-Content and the second div has a class name of r-content stand for Right-Content.
The l-content will have more content than the r-content but they will both scrollable when the screen size is not enough to show the whole content.
Now what I want to happen is when the r-content has reached it's last content then scrolling on it will be stop so that only the l-content will continue scrolling.
The Example is like on Facebook, as you can see where ads,Recommendation,etc are shown in the right side of it
when the last content is reached then that element looks like fixing it's position.
I'm not sure if it is fixing or not but I'd like my r-content to be like that But have no idea on how.
Current this is all i have, note that I am using Bootstrap on this:
CSS
h1 {
font-family: sans-serif;
color: #FFF;
letter-spacing: 2px;
font-weight: 300;
}
.l-content, .r-content {
display: table;
float: left;
margin-bottom: 8px;
text-align: center;
padding: 20px;
}
.l-content {
width: 800px;
height: 2000px;
background: #E04C4E;
margin-right: 8px;
}
.r-content {
width: 430px;
height: 1000px;
background: #5996BC;
}
HTML
<!--LEFT CONTENT-->
<div class="col-lg-8 l-content">
<h1>Left Content with Continue Scrolling.</h1>
</div>
<!--RIGHT CONTENT-->
<div class="col-lg-4 r-content">
<h1>Right Content with Continue Scrolling but scrolling will stop when last content is reached.</h1>
</div>
I am not sure if it they are using a Javascript to do it.
Anyway, Thank you so much. Any help would be appreciated.
I believe you need javascript here, and jQuery is geared for exactly this.
scroll() and scrollTop() are the magic functions here:
var h = $(preceding-content).height()
var s = $('#your-sticky-element')
$(window).scroll(function(){
if($(window).scrollTop() <= h){
$(s).css({
'position':'fixed',
'top':'0px'
});
}else{
$(s).css({
'position':'initial'
});
}
}
This will work best if it's static content above your sticky element. If it's updating its height in real time, you're going to be doing a lot of calculations just to keep an element in place.
Code
Demo
The basic form of HTML looks like this:
<div class="home">
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<!-- blah, blah, blah! -->
</main>
</div>
</div>
W.r.t the HTML, I am trying to make the element #main fill the entire height of the browser viewport using JavaScript/jQuery like so:
jQuery(document).ready(function($){
// get height of browser viewport
var window_h = $(window).height();
// get height of the jumbotron, i.e. element #main
var jumbotron_h = $('.home #main').outerHeight(true);
// calculate necessary padding (top/bottom) to apply on #main so that the
// element's height is equal to that of the browser's viewport,
// and its contents are centered vertically
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
// apply calculated padding on the element dynamically
$('.home #main').attr('style', 'padding-top:'+jumbotron_padding+'px;padding-bottom:'+jumbotron_padding+'px;');
});
As clearly explained in the comments in the code above, the code automatically calculates the necessary padding to be applied on #main so that its height is equal to that of the browser's viewport.
It works well, except, the calculated padding (and therefore the resultant height) is wrong in one case that I was able to identify.
Easily reproducible at least on Windows 7, Google Chrome browser (latest) when you resize the browser window to 567x724 px, which implies 551x611 px viewport size, (you can use an extension like Window Resizer), you'll notice that the element's calculated padding results in its height being larger than that of the browser's viewport.
Why is this happening? I wasn't able to reproduce the same at any other resolution. What could I possibly be missing here?
First off, Jquery's .outerheight() function includes padding, which means that when you measure the height of your #Main element after this function runs the first time, it will equal the window.height. In other words - it will look awful when you resize your browser. You can see this in action on this fiddle when you resize the browser window the old-fashioned way. You can use margins instead, but then you'll have to adjust your CSS quite a bit. Even then, resizing the window still looks awful and buggy and has inconsistent results across browsers. You can see that on this fiddle.
The specific bug you're referring to is probably due to inconsistent math when you resize your window - a combination of your use of padding (which is included in .outerheight() as mentioned above) and the viewport size not being easily divisible by 2 (it's impossible to have half a pixel and different browsers will render that half a pixel differently).
I should also point out this line of code:
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
This forces your page to always be #main.height() + 60, which can be bigger than your viewable window, depending upon your window size. #main.height() comes out to around 200.5px (there we are with another half pixel).
Assuming that your goal is to vertically center the #Main element, your best bet is to use one of the many straight CSS methods available. The table method seems most applicable here because it is completely dynamic (and thus can be responsive) - simply create a single cell CSS table, use CSS valign, and build your entire page inside that cell. For older versions of IE you'll need to use a tiny hack (display:Inline-block;) to make it work.
HTML:
<div id="parent">
<div id="child">Content here</div>
</div>
CSS:
#parent {display: table;}
#child {
display: table-cell;
vertical-align: middle;
}
IE fix:
#child {
display: inline-block;
}
Based on #Thomas's answer, I've identified two possible solutions. I am going with the #2 solution considering better browser support for it.
1. Using the unit vh (viewport height). Browser support: IE9 and above.
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100vh; /* 100% viewport height */
vertical-align: middle;
}
2. Dynamically setting height of parent (.home #primary) equal to that of browser's viewport.
JS:
jQuery(document).ready(function($){
var window_h = $(window).height();
var jumbotron_h = $('.home #main').height();
if (window_h <= (jumbotron_h + 60)) {
var window_h = jumbotron_h + 60
}
$('.home #primary').attr('style', 'height:'+window_h+'px;');
});
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100%; /* 100% height of parent */
vertical-align: middle;
}
body {
height:100vh;
}
.element-to-be-centered {
font-size:1em;
text-align:center;
top: 49%;
-webkit-transform: translateY(-49%);
-ms-transform: translateY(-49%);
transform: translateY(-49%);
}
I have been doing quite a bit of experimenting lately with centering content. This technique will work without having to set a height on any element.
This will work in ie9 and up.
In your CSS
html, body {
height: 100%;
}
div, #main {
height: 100%;
}
I have a very simple webpage with a problem. It ahs 3 divs that sit ontop of each other, the header, content then footer.
I want my footers height to expand to the bottom of the page. How can I do this?
The header has a constant height, the content will vary in height depending on the content received from an AJAX call. So I cant explicitly set it.
Heres my JSFiddle: http://jsfiddle.net/5U6ZB/2/embedded/result/
<div id="header"></div>
<div id="content">
<!-- height is dynamic sometimes it will be full of divs that makes it
longer than the screen height other times it only has 1 div -->
</div>
<div id="footer">
<!-- How do I make the footer height fill up the rest of the page height? -->
</div>
body { background-color: white; }
div { width: 100%; }
#header {
height: 400px;
background-color: RGB(200,200,200);
}
#content {
}
#footer {
background-color: RGB(112,112,112);
/*How do I make the footer height fill up the rest of the page height?*/
}
html {
background-color:#093; /*the footer color*/
}
body {
background-color: #f6f; /*the body color*/
}
Sounds like the easiest solution in your case would be to make the body background the same colour as the footer and make your content white. This would give the illusion of the footer going all the way to the bottom.
body { background-color:RGB(112,112,112); }
div { width: 100%; } /* Divs are block elements which automatically take 100% width so this is redundant. */
#header {
height: 400px;
background-color: RGB(200,200,200);
}
#content {
background-color:white;
}
#footer {
background-color: RGB(112,112,112);
}
:root {
background-color: siteBackgroundColor;
}
body {
background-color: footerColor;
}
This doesn't really expand the footer, but visually expands its background color.
A similar approach to fayerth's, this will adjust height dynamically when the browser is resized (and is based on jQuery).
Instead of resizing the footer directly, I added the additional empty element <div class="flex-footer"> and resized that instead. My thought is that it should give a less jittery effect if the footer contains a bunch of elements as well as not fussing with any children of the footer that are sized relative to the parent.
Your CSS should then apply whatever background color necessary.
Note my comment about negative margins. This was necessary in my case since the design required the use of negative margins. I've included that bit in case yours does as well.
$(function(){
$(window).load(resizeFooter);
$(window).resize(resizeFooter);
});
// Dynamically resize footer to fill page, IE8 doesn't like this.
function resizeFooter() {
var windowHeight = window.innerHeight;
var headerHeight = $("header").height();
var contentHeight = $("div.main").height();
var footerHeight = $("footer").height();
// 107 references a negative margin in header - you'll need to account for this if necessary
var flexFooter = windowHeight - (headerHeight + contentHeight + footerHeight - 107);
$(".flex-footer").css("min-height", flexFooter);
}
In pure CSS, it's not possible, but if you want to use some fancy Javascript, you can dynamically change the height of the footer to stretch the remaining height, assuming the content doesn't already do it for you.
var header = document.getElementById("header"),
content = document.getElementById("content"),
footer = document.getElementById("footer"),
height = window.screen.height - header.clientHeight - content.clientHeight;
footer.clientHeight = (height < 150) ? 150 : height; // Sets a minimum height of 150px
It's usually better to follow SynXsiS's suggestion though, as it tends to give a nicer appearance. In the end, it really depends on the way you design the look and feel of your page.
very simple, and works for me :)
footer{ position:absolute; width:100%; top: (read below); }
you can try with diferent percents values in top property, when the footer take the desired place in your screen, that percent will apply to all resolutions :)
I am tweaking a wordpress theme - and have the same problem. But - if I implement a sticky footer, it actually partially scrolls away with the content. Wordpress is a mess so I'm not sure why it's doing this - but what I need is to let the footer sit below the main content, but THEN fill the rest of the screen so it doesn't look silly on shorter pages.
Any ideas of an easy CSS fix other than the color trick? (which I may do ;)
Claudia
I want to center a div inside a parent div. The only way I can do it is by using margin-left property. The formula is:
margin-left = (parent.width/2) - (child.width/2)
but I can't get it done via JavaScript because of two things:
The width isn't defined in the style thus cannot be accessed via document.getElementById("child").style.width
document.getElementById("child").offsetWidth doesn't give the proper and the correct width for unknown reasons
I am using this code, but as said above, it doesn't work
<script type="text/javascript">
document.getElementById("fb_share").style.marginLeft = parseInt((document.getElementById("vss_border").offsetWidth / 2) - (document.getElementById("fb_share").offsetWidth / 2)) + "px";
</script>
If there is any other solution via CSS (but it must be margin-left and no width change) please tell.
Since you said JavaScript, I can't avoid mentioning jQuery's position function:
$("#myDiv").position({
my: "center",
at: "center",
of: $('#parent')
});
I found your problem. The child width is set to 691px, so once it tries to center the fb_share div it only sets it by a few pixels.
All you have to do is set the style, e.g:
<div id="fb_share" style="width:150px;">
Breakdown
Nothing wrong with your javascript.
The child is almost the same width as the parent, causing a minimum center.
Set the child width correct and all should be working fine
This is actually a quite common question. The problem is exacerbated by the fact that different browsers understand the stuff differently. The easiest thing is actually non-CSS:
<div id="parent" style="width:100%">
<div align="center">
your own stuff
</div>
</div>
However if you need to do this in pure CSS, then the answer will be something like this:
In your CSS:
div.parent {
text-align: center;
width: 100%;
}
#wrapper {
margin-left: auto;
margin-right: auto;
text-align: left;
}
div.child {
text-align: left;
}
Then, in your HTML, you'd have something like this:
<div class="parent">
<div id="wrapper">
<div class="child">
Your stuff here
</div>
</div>
</div>
I used this (second) approach to centre the entire page content within the browser window (in my case, instead of the first div, I had <body>. If you want to see where I used this, have a look at http://www.ooklnet.com/
I'm pretty confused! with this:
...
<div id="main">
<div id="content">
<div class="col1">
...COLUMN1 CONTENT GOES HERE...
</div>
<div class="col2">
...COLUMN2 CONTENT GOES HERE...
</div>
</div><!-- #content -->
</div><!-- #main -->
...
there are columns as you see, and I want to set their container element's height to the maximum size of both columns(plus 130px). so by using Prototype framework:
//fixing column height problem
Event.observe(window,"load",function(){
if(parseInt($('col1').getStyle('height')) > parseInt($('col2').getStyle('height')))
$('main').setStyle({'height' : parseInt($('col1').getStyle('height'))+130+'px'});
else
$('main').setStyle({'height' : parseInt($('col2').getStyle('height'))+130+'px'});
});//observe
It working nice in Firefox, Opera, Safari & Chrome but it fails to return the actual height of columns. in IE7+ (not tested in IE6) it returns NaN as columns height.
I've managed to find out that's because of this:
.col1,.col2{"height:auto;"}
I've also used "$('col1').offsetHeight" and it's returning 0 as the height value of each column.
the HTML is styled in this way:
#main{
height: 455px;
background: #484848 url(../images/mainbg.png) repeat-x;
}
#content{
/*height:80%;*/
width: 960px;
direction: rtl;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
position: relative;
}
.col1,.col2{
width: 33%;
text-align: right;
margin-left:3px;
padding-right:3px;
line-height:17px;
}
.col1{padding-top:20px;}
.col1 ul{
margin:0;
padding:0;
list-style: url(../images/listBullet.gif);
}
.col1 ul li{
margin-bottom:20px;
}
.col2{
top: 0;
right: 70%;
position: absolute;
}
any idea on the issue please?!
update/ It tooks three days to solve, and I was at the very risk of making a bounty!
for the solution please take a look at this question/answer.
As a completion for Marc's answer; There's an equal for jQuery's height() in Prototype:
$('col1').getDimensions().height //or .width ofcourse
And here's the docs: http://prototypejs.org/api/element/getDimensions
Update: I agree with crescentfresh below. Since I had the absolute same problem in the past, I've searched all possible methods to find the dimension properties but I failed as you will. please take a look at this:
function getStyle(oElm, strCssRule){
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
}
As you see, the function has been written to get the computed rendered current style of an element, but in our case even this method will fail, I guess. (worth a try)
So, as crescentfresh said, you have to find the problem in your CSS positioning method while not wasting your time seeking for a proper javascript function which could be able to do the magic. let's begin by removing that #content DIV and letting the #main to be the only wrapper of said columns, and then styling the remain to achieve the desired goal.
Since IE wants to give you a hard time, you can give it some special attention and use a property that I believe it will recognize...
var height;
if(document.all) { //This means it is IE
height = document.getElementById('col1').offsetHeight;
}
else {
height = //Use what is working in other browsers now
}
From:
Why would jquery return 0 for an offsetHeight when firebug says it's 34?
An element that is not actually taking
part in the document render process
has no dimensions, and will give an
offsetWidth/Height of 0.
Both Prototype's getDimensions() and jQuery's height() read the offsetHeight or clientHeight properties, which you've tried and got 0. So somewhere in your code there must be something taking #col out of the rendering flow. That's all I can think of.
Artarad,
The above style i.e. css shows that you have not assigned height.
Please try adding _height:auto in class which will look like
.col1,.col2{
width: 33%;
_height:auto;
height:auto;
text-align: right;
margin-left:3px;
padding-right:3px;
line-height:17px;
}
Basically, many browsers fail to recognize the height when assigned to a particular div or any element . In this case we use the above work arounds.
I hope the above helps you.
Thanks,
Samiksha
I don't know if it will work (without testing), but you could try jQuery and height(); this (in theory) gives the computed height. Worth a try...
I know this is an old question but I found a better answer than "Fix the css and forget the javascript".
I had the exast same problem and used .innerHeight() and it forced jQuery to calculate the height. For some reason .outerHeight() did not work whilst .innerHeight() solved the problem. Not sure if there is a similar method for prototype. You could look into the jQuery library and figure out how .innerHeight() works, and write your own.