I'm trying to determine the height of a div. This sounds simple, but is complicated by the fact that it's only descendant contents are floated, so asking for the height/outerHeight (using jQuery)/clientHeight/offsetHeight only returns 0, even though it's clear that on the page, it is rendered certainly with a height. Here is an example of the HTML structure:
<div id="root">
<div class="header"></div>
<div class="body">
<div class="text-left" id="text-one">
<p>Some text taking up multiple lines</p>
</div>
<div class="text-right" id="text-two">
<p>Other text</p>
</div>
</div>
</div>
The "text-left" and "text-right" elements have "float: left;" and "float: right;" on them, so when I ask for the height of "root", it tells me it's 0. However, of course, when I get the height of the "text-one" and "text-two", it correctly tells me that it's 20 or whatever.
How can I determine the REAL height of the the "root" element? (For example, if "text-one" had a height of 50 and "text-two" had a height of 20, it would know that the true height is 50)
I imagine there's some kind of logic to work out all the descendant elements' heights and calculate if they're floated etc etc and give me a final figure...but I'm not smart enough to work that out.
Thanks in advance.
EDIT: Please note changing the HTML (to include a "clear", for example) is not an option. I need to be able to tell the height of this div as it is.
That's because the height is zero. Try viewing this
<html><head><title>test</title></head><body>
<div id="root" style="border:1px solid red">
<div class="header"></div>
<div class="body">
<div class="text-left" id="text-one" style="float: left;">
<p>Some text taking up multiple lines</p>
</div>
<div class="text-right" id="text-two" style="float: right;">
<p>Other text</p>
</div>
</div>
</div></body>
Header is empty, and body only contains elements floated out of the layout, so it also counts as empty, leaving root bereft of content to hold it open.
Also by the same reasoning, the body element is zero height; which you can verify by adding <body style="border:1px solid blue">
If all #root's children (strictly speaking, descendants) are floated, then it does indeed have a height of zero. Try setting a background colour on it to prove that it occupies no vertical space.
If you get the heights of the two floated elements, then you can take the greater of those:
var height = Math.max(leftHeight, rightHeight);
How about a function that reads all inner divs and stores the maximum height value from the two divs?
I dont think is very correct but here is try:
var max_height = 0;
$.each( $('#root div'), function(x, y){
var yHeight = $(y).height();
max_height = ( yHeight > max_height) ? yHeight : max_height;
});
console.log(max_height); //should have the height value.
Working Demo
I deleted an answer because I missed out on what a lot of others has already pointed out: the height is, quite literally, 0, and everything is working. What you need to do to get the height that, in your words, the root div 'seems' to have, is to make that div actually have that height, which can easily be achieved by simply clearing the floats at the end of the div.
<div id="root">
<div class="header"></div>
<div class="body">
<div class="text-left" id="text-one">
<p>Some text taking up multiple lines</p>
</div>
<div class="text-right" id="text-two">
<p>Other text</p>
</div>
</div>
<div style="clear: both;"></div>
</div>
As partly referenced above the problem here is a css issue, specifically clearing of floated elements. An excellent overview of which can be found at www.positioniseverything.net/easyclearing.html. As you are unable to alter the html mark-up you could take the positioniseverthing solution and apply it by adding a class to the parent of the floated elements with js/jQuery,
$('#root .body').addClass('clearfix');
Now you should be able to access the height with,
$('#root').height();
as mentioned above. Hope that helps
Set the overflow of the root element to hidden, then its height will stretch to match the inner elements. Tested with the link you posted in another comment, and it works!
#root {
background-color: lightgreen; /* for demo purposes */
overflow: hidden;
}
If using a CSS file is not an option, then you can use your jQuery to set the CSS:
$('#root').css( 'overflow', 'hidden' );
// ...then your height code
Related
I have some problems when rendering on only app(iOS) NOT website:
I have to use pure Javascript without any other libraries.
<div class="header" style="position:fixed; z-index: 99;"></div>
<div class="content" style="position:relative">
<div class="cover" style="position:absolute; z-index:999;"></div>
//some text content
</div>
The Cover div didn't display overlapping Header. What can I do to that?
I want that initially user will see Cover first, then scroll up then see fixed Header and eventually Content.
I dont want to change the HTML, because when I put header in content div, header usually jumps and take moment to back the correct position when scrolling content div.
Thanks for any help!
Give #content a z-index property, too. Say, 100.
The problem looks like z-index context. z-index is not a global value - it is relative to it's parent. You have #header with z-index:99, and it's sibling #content with z-index:auto(say 1 for argument's sake). #header always overlaps #content, and its children.
You are using absolute property to cover class, relative to content className that means, it position will change according to content class. Remove relative property to content class, add wrapeer to all header and content className.
<div style="position:relative">
<div class="header" style="position:fixed; z-index: 99;"></div>
<div class="content" >
<div class="cover" style="position:absolute; z-index:999;"></div>
//some text content
</div>
</div>
I need your help please. I am writing on images with absolute containers, take a look here: jsfiddle.net/z2hmcdt2
In the data field "data-wanted-height" is always the wanted pixel height, I want for this container. I place 1:x inline container into it.
For example this container:
<div id="fields_item_3" class="fields_item aleft" style="top:140px;left:13px;width:180px;line-height:22px;font-size:12px;font-weight:400;color:#000;" data-wanted-height="22">
<div class="item">Sample Street 123</div>
<div class="item spacer">•</div>
<div class="item">12345</div>
<div class="item">Sample City</div>
</div>
How can I resize the font-size so that it will fit always? No wrap or anything and its irrelevant how long the text will be.
Does anyone have a solution for my problem?
Thanks in advance
I am attempting to create a series of window sized divs with inner divs of variable sizes > window size. The catch is it needs to scroll as if the divs where not nested.
In short I want THIS:
css{
block{ height:100wh; }
innerBlockSmall{ height:100wh; }
innerBlockLarge{ height:200wh; }
}
<div class="block">
<div class="innerBlockLarge"></div>
</div>
<div class="block">
<div class="innerBlockSmall"></div>
</div>
https://jsfiddle.net/cbuh8psd/
to act just like THIS
css{
innerBlockSmall{ height:100wh; }
innerBlockLarge{ height:200wh; }
}
<div class="innerBlockLarge"></div>
<div class="innerBlockSmall"></div>
https://jsfiddle.net/t6zrvo7u/1/
Unfortunately scroll "Focus" is triggered by hovering over the scrollable element. In this case it is an undesirable behavior.
There are 2 possible solutions that I am currently aware of.
Manually Assigning scroll "Focus" via javascript. (Optimal)
Completely overwriting default HTML scrolling javascript, for
example the library ISCROLL5.
(ok, if the performance hit is small)
Unfortunately after looking through developer.mozilla's HTML5 documentation I have not run across any way to "Focus" scrolling to an element via javascript.
As for option 2 : ISCROLL5 has had an undesirable performance hit with over ~15-20 scrolling divs.
I am hoping I am missing something here, any solutions, fixes, or advice would be much appreciated.
This solution allows scrolling over entire document while keeping the possibility of scrolling each nested div with mouse. I hope I understood you correctly.
This is just a concept, it does not prevent nested elements from scrolling along with window. But it can be improved.
Array.prototype.slice.call( document.getElementsByClassName('sbRemover') )
.forEach(function (div) {
var scroll = 0,
mousedown = false,
mouseBtnHandler = function (e) {
mousedown = e.type == 'mousedown';
}
div.addEventListener('scroll', function (e) {
// Change of div's scrollTop. Negative when scrolling down
var diff = scroll - e.target.scrollTop;
// Save new scroll value to be able to compare with it later
scroll = e.target.scrollTop;
// Do nothing when div is scrolled by dragging the scrollbar
if (!mousedown) {
// Scroll the window to the same amount of pixels the div was scrolled
window.scrollTo(window.pageXOffset, window.pageYOffset - diff);
}
});
div.addEventListener('mouseup', mouseBtnHandler);
div.addEventListener('mousedown', mouseBtnHandler);
});
body, div {
margin: 0;
padding: 0;
}
.block{
position: relative;
width:100vw;
height:100vh;
overflow: hidden;
z-index: 1;
opacity: 100;
}
.sbRemover{
width:100%;
height:100%;
padding-right:15px;
overflow: auto;
}
.largeContent{
height:225vh;
}
.smallContent{
height:100vh;
}
<div id="simpleCanvas">
<div class="block" style="background-color: blue">
<div class="sbRemover">
<div id="ok" class="largeContent" style="background-image: url('http://silviahartmann.com/background-tile-art/images/grey-repeating-background-8.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: red;">
<div class="sbRemover">
<div class="largeContent" style="background-image: url('http://a1star.com/images/star--background-seamless-repeating9.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: green">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
<div class="block" style="background-color: blue">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
<div class="block" style="background-color: red;">
<div class="sbRemover">
<div class="largeContent" style="background-image: url('http://people.stfx.ca/x2011/x2011ane/info102/assignment1/11500341-abstract-colorful-repeating-background.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: green">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
</div>
I have no idea why you would wish to do this, but the only way I can think of achieving the effect you want is along the lines of recreating the scrollbar, the good news however is that this needs not come at the cost of losing your native like experience.
Sadly I can't remember the project I wrote this code for, though one way to achieve this is to make yourself a scrollbar component. This scrollbar component would indeed provide a fake scrollbar, but provide a native like interface. So, how do you do this?
You determine the width of the scrollbar by taking the difference between an element with and without overflow: scroll. Let this be scrollWidth
You create a <div> with overflow: auto of width scrollWidth and position: fixed this in place on the right side of the body. Let the scrollTop property be scrollPosition.
Inside the element you add another <div> with width 0 (this at least works in Chrome, check whether other browsers treat this differently) and let height be documentLength.
Now, you can fully control the scrollbar by setting documentLength and scrollPosition any way you wish to. In your case you would set documentLength as the combined scrollHeights of each element and scrollPosition based on the relative scrollTop's in those nodes.
A very basic demonstration of the concept (not the implementation) can be found in this jsfiddle (note the width of the scrollbar is fixed to 20px in this case and there is no dynamic code whatsoever).
I am trying to create a site with a set of images that can be viewed by scrolling the page vertically or by clicking a button that links to the next image in the set using an anchor tag.
The images are centered vertically and horizontally inside a container that responds to the size of the browser window.
<a id="1">
<table cellpadding="0" cellspacing="0" border="0" height="100%" width="100%">
<tr valign="middle"><td align="center">
<img src="image.png">
</td></tr>
<tr><td>
Down
</td></tr>
</table>
</a>
I know of no other way to achieve this but to use tables though I am aware that it is very poor markup.
I have also found that the site renders correctly in Firefox 16.0.2 but not in Safari 5.0.6 where after the second image in the set the tables appear to grow in height exponentially.
How can I code this site for better accessibility and with proper markup?
The way I would probably do it without resorting to too many hacks would be to just put each image in a div, set some dimensions based on css, then use javascript to adjust accordingly.
Here is the sample HTML:
div class="item">
<img src="http://www.focus-itoutsourcing.com/wp-content/uploads/2013/10/Software-testing-trends-2013.jpg" />
</div>
<div class="item">
<img src="http://www.focus-itoutsourcing.com/wp-content/uploads/2013/10/Software-testing-trends-2013.jpg" />
</div>
The sample CSS:
html {height:100%;}
body {height:100%;}
div.item {
width:100%;
height:100%;
text-align:center;
}
div.item > img {
max-height:100%;
max-width:100%;
}
And finally the jquery which simply readjusts sizes on resize and at the start.
$(document).ready(function(){
//Setup function for sizing.
var win = $(window), body = $('body');
var els = $('div.item');
function DoResize() {
var height = win.height(),
width = body.width();
els.each(function(i,el){
var ele = $(el);
ele.height(height).width(width);
var img = ele.find('img');
var difference = (height - img.height())/2.0;
img.css('margin-top',difference+'px');
});
}
DoResize();
$(window).on('resize', DoResize);
});
I set up a jsfiddle for you to see it in action. It also readjusts for resizing of the window. It should work in most browsers even IE7 according to caniuse.com.
Update:
To include the captions and such you can do a variety of things. The easiest would be to add relative positioning to each item, then absolute positioning to each element you want to position with respect to each image.
You would do the html more or less like so:
<div class="item">
<img src="http://www.focus-itoutsourcing.com/wp-content/uploads/2013/10/Software-testing-trends-2013.jpg" />
<div class="caption">
Caption for Item 1
</div>
<div class="link">
Item link
</div>
</div>
Then the style would just have updates for the other classes within the parent div.
I updated the jsfiddle here to show you some things you can do: link
Updated again:
Add the following script tag to your page:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
before the Resizing script.
Damn Miltox beat me too it. His is better though. Just to say the reason safari was weird was you had multiple tables set at 100% height each stacked on top of each other so they were adding up, you should have had one big table. Miltox's answer will have fixed that all anyway.
I am trying to move everything contained within the div id "tile", to the center of the web browser. By default the CSS is undefined and it appears on the left side of the browser. What I would like to do is move the entire div to the center using javascript when the button "move" is clicked.
The html is shown directly below, and the attempted (but not working) javascript is shown below that.
html
<div id="tile">
<div class="menu">
<ul>
<li> Vis </li>
</ul>
</div>
<div id="tabcontent4">Some generic content</div>
<button onclick="move();" type="button">Move</button>
</div>
</div>
javascript
document.getElementsById("tile").style.align='center';
EDIT: How would I move the div to a specific location?
There is no "align" property in CSS. The closest is text-align, but you probably want to use the CSS declaration margin: 0 auto, which will move the whole <div> to the center of the page. So you want:
document.getElementById("tile").style.margin="0 auto";
Make sure that tile has a specified width.
You can do this with just CSS:
<div id="tile" style='margin:0 auto;width:300px'>
...
</div>
Or, put it in a container, and center its content:
<div id='container' style='text-align:center'>
<div id='tile' style='width:300px'>
...
</div>
</div>
Of course, non-inline styles are preferred.
Nice username, BTW.
// EDIT
To place the div in a specific location with javascript:
document.getElementById('tile').style.position = "absolute";
document.getElementById('tile').style.left = "100px";
document.getElementById('tile').style.top = "100px";
It must have a position defined, usually absolute or relative.
Once again, this can - and usually should - be done with CSS:
#tile { position:absolute; left:100px; top:100px }