I am trying to dynamicly change the width of a div using CSS and no jquery. The following code will work in the following browsers: http://caniuse.com/calc
/* Firefox */
width: -moz-calc(100% - 500px);
/* WebKit */
width: -webkit-calc(100% - 500px);
/* Opera */
width: -o-calc(100% - 500px);
/* Standard */
width: calc(100% - 500px);
I want also support IE 5.5 and higher, i found the following: expression. Is this the correct usage:
/* IE-OLD */
width: expression(100% - 500px);
Can I also support Opera and the Android browser?
Almost always box-sizing: border-box can replace a calc rule such as calc(100% - 500px) used for layout.
For example:
If I have the following markup:
<div class="sideBar">sideBar</div>
<div class="content">content</div>
Instead of doing this: (Assuming that the sidebar is 300px wide)
.content {
width: calc(100% - 300px);
}
Do this:
.sideBar {
position: absolute;
top:0;
left:0;
width: 300px;
}
.content {
padding-left: 300px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
}
html,
body,
div {
height: 100%;
}
.sideBar {
position: absolute;
top: 0;
left: 0;
width: 300px;
background: orange;
}
.content {
padding-left: 300px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: wheat;
}
<div class="sideBar">sideBar</div>
<div class="content">content</div>
PS: I won't work in IE 5.5 (hahahaha) , but it will work in IE8+ , all mobile, and all modern browsers (caniuse)
Width Demo
Height Demo
I just found this post from Paul Irish's blog where he also shows off box-sizing as a possible alternative for simple calc() expressions: (bold is mine)
One of my favorite use-cases that border-box solves well is columns. I
might want to divide up my grid with 50% or 20% columns, but want to
add padding via px or em. Without CSS’s upcoming calc() this is
impossible… unless you use border-box.
NB: The above technique does indeed look the same as would a corresponding calc() statement. There is a difference though. When using a calc() rule the value of the width of the content div will actually be 100% - width of fixed div, however with the above technique, the actual width of the content div is the full 100% width, yet it has the appearance of 'filling up' the remaining width. (which is probably good enough for want most people need here)
That said, if it is important that the content div's width is actually 100% - fixed div width then a different technique - which makes use of block formatting contexts - may be used (see here and here for the gory details):
1) float the fixed width div
2) set overflow:hidden or overflow:auto on the content div
Demo
Just have a fallback before the calc will do the trick.
width: 98%; /* fallback for browsers without support for calc() */
width: calc(100% - 1em);
See more here https://developer.mozilla.org/en-US/docs/Web/CSS/calc
use this
.content
{
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding-right: 500px;
margin-right: -500px;
}
Just spent the best part of 3 hours trying to workaround this for a specific case on andriod devices, couldnt get box sizing to work so i've linked it into my JS as a dirty workaround... no jQuery required though! :)
Taken on working code on andriod 2.3.
<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>
<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>
JS with event listeners
var orient =
{
orientation:window.orientation,
width: window.innerWidth,
check: function()
{
// if orientation does not match stored value, update
if(window.orientation !== this.orientation)
{
this.orientation = window.orientation; //set new orientation
this.width = window.innerWidth; //set new width
this.adjustIrritatingCSS(this.width); //change ui to current value
}
//if width does not match stored value, update
if(window.innerWidth !== this.width)
{
this.width = window.innerWidth; //set new width
this.adjustIrritatingCSS(this.width); //change ui to current value
}
},
adjustIrritatingCSS: function(screenWidth)
{
//disgusting workaround function
var titleBoxes = document.getElementsByClassName('sessionDiv');
var i = titleBoxes.length;
var sessWidth = screenWidth - 300; // calc(100% - 300px); -> equivalent
while(i--)
{
titleBoxes[i].style.width = String( sessWidth + "px");
//resize image in auto sized div
}
sessWidth = null; //clear width
titleBoxes = null; //clear nodelist
i = null; // clear index int
}
};
window.onload = function()
{
window.addEventListener('resize', function(){orient.check();});
//on resize, check our values for updates and if theres changes run functions
window.addEventListener('orientationchange', function(){orient.check();});
//on rotate, check our values for updates and if theres changes run functions
setInterval(function(){orient.check();}, 2000);
//occasionally check our values for updates and if theres changes run functions(just incase!!)
orient.adjustIrritatingCSS(orient.width);
//sets value on first run
};
Hope this helps anyone who cant get the box-sizing working!
PS I have experienced problems with ios using this...
Change #menuLog width with % or px and you will see magic. Works with every device even < 2.3
*{
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#menuLog{
width:30%;
/*width:300px;*/
height: 60px;
padding: 5px;
background-color: #ddd;
}
#menuLog > div[inline-log="1"]{
display: inline-block;
vertical-align: top;
width: 100%;
height: 100%;
margin-right: -60px;
}
#menuLog > div[inline-log="1"] > div[inline-log="1.1"]{
margin-right: 60px;
height: 100%;
background-color: red;
}
#menuLog > div[inline-log="2"]{
display: inline-block;
vertical-align: top;
width: 60px;
height: 100%;
}
#menuLog > div[inline-log="2"] > div[inline-log="2.1"]{
display: inline-block;
vertical-align: top;
width: 55px;
height: 100%;
background-color: yellow;
margin-left:5px;
}
<div id="menuLog">
<div inline-log="1">
<div inline-log="1.1">
One
</div>
</div><div inline-log="2">
<div inline-log="2.1">
Two
</div>
</div>
</div>
I wanted to add the no-calc, no-border-box (i.e., CSS2) alternative.
Normal-flow block elements initially have width: auto, which is effectively the width of the containing block minus the margin, border, and padding widths.
The example above can be done, without border-box, simply as
.content {
padding-left: 300px;
}
Similarly, with
.content {
margin-left: 1px;
border-left: 1em solid;
padding-left: 1rem;
}
the effective width is 100% - 1px - 1em - 1rem.
For absolutely positioned elements, height: auto has similar properties:
.content {
position: absolute;
top: 0;
bottom: 0;
margin-bottom: 1px;
border-bottom: 1em solid;
padding-bottom: 1rem;
}
Here the effective height is 100% - 1px - 1em - 1rem.
Related
This question already has answers here:
Setting Element Width Based on Height Via CSS
(10 answers)
Closed 3 years ago.
I saw solution for height depending on width: css height same as width. Or here: https://stackoverflow.com/a/6615994/2256981.
But my question is opposite.
My element:
<body>
<div id="square"></div>
</body>
Style for it:
body, html {
margin: 0;
height: 100%;
min-height: 300px;
position: relative;
}
div#square { /* My square. */
height: 75%; /* It's height depends on ancestor's height. */
width: 75vh; /* If supported, preliminarily sets it's width. */
position: absolute; /* Centers it. */
left: 50%; top: 50%; transform: translate(-50%, -50%);
background-color: darkorange; /* Makes it visible. */
}
Script, that keeps it square:
window.onload = window.onresize = function (event) {
var mySquare = document.getElementById("square");
mySquare.style.width = mySquare.offsetHeight + 'px';
};
Complete code here: http://jsfiddle.net/je1h/hxkgfr9g/
The question is to make the same thing in pure CSS. No scripting.
There are two techiques I am aware of to keep the aspect ratio of an element according to it's height :
When height is relative to the viewport :
You can use vh units :
div {
width: 75vh;
height: 75vh;
background:darkorange;
}
<div></div>
For a height based on the height of a parent element :
You can use a dummy image that has the aspect ratio you want. Example with a 1:1 aspect ratio you can use a 1*1 transparent .png image or as commented by #vlgalik a 1*1 base64 encoded gif :
html,body{
height:100%;
margin:0;
padding:0;
}
#wrap{
height:75%;
}
#el{
display:inline-block;
height:100%;
background:darkorange;
}
#el img{
display:block;
height:100%;
width:auto;
}
<div id="wrap">
<div id="el">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
</div>
</div>
Note that this last demo doesn't update on window resize. But the aspect ratio is kept on page load
UPDATE :
As reported in the comments setting display:inline-flex: on #el seems to solve the updating on window resize problem.
Edit: Missed that you wanted to set the width depending of the height, this does the opposite :(
To support all ratios you can use padding-bottom. Percentages in padding-bottom are always relative to the width of the element:
/* the wrapper has a width */
.wrapper {
position: relative;
width: 25%;
margin-bottom: 10px;
}
/* these elements set the height (using padding-bottom) */
.square {
padding-bottom: 100%;
position: relative;
}
.widescreen {
padding-bottom: 56.25%; /* 9/16 = 0.5625 */
}
/*
* This is the content.
* Needs position:absolute to not add to the width of the parent
*/
.content {
/* fill parent */
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
/* visual */
padding: 10px;
background: orange;
color: white;
}
<div class="wrapper">
<div class="square">
<div class="content">square</div>
</div>
</div>
<div class="wrapper">
<div class="widescreen">
<div class="content">16:9 ratio</div>
</div>
</div>
The only downside is, that you need a bunch of wrapper elements.
Short version: Make the image fit nicely the visible area for small windows, starting from this fiddle
Update: There doesn't seem to be a solution for this issue. I thought there might be one because Chrome actually makes it possible (see my answer) but behavior is different in other browsers.
Longer version:
I'm working on a lightweight fluid lightbox and have an apparently simple CSS issue I can't resolve.
I want the content (a single image) to be downsized if needed to fit, while keeping the aspect ratio the same.
Here's a demo fiddle: http://jsfiddle.net/3a9y9/2/ . Resize the window so the image doesn't fit height wise.
It almost works, but the height given to the image is slightly more than what's actually visible so a bit of the bottom gets clipped. I've tried tweaking things to no avail; I wish I understood how come the available height is too high.
Maybe it's related, but IE 9 doesn't even maintain the aspect ratio with this attempt of a solution. Also, Chrome behaves strangely when resizing the window and clicking on run in the fiddle will sometimes redraw differently.
What's the solution?
It's no problem to wrap the <img> in a <div> or two if it's necessary, but the top-level structure should ideally remain the same (i.e. a .featherlight-content inside a .featherlight and that's it).
In featherlight.min.css, change .featherlight-image{width: 100%} to .featherlight-image{max-width: 100%}
and at the end, write the following css:
#media only screen and (min-height:1000px) {
.featherlight-image { height: 900px; }
}
#media only screen and (min-height:700px) {
.featherlight-image { height: 600px; }
}
#media only screen and (max-height:700px) {
.featherlight-image { height: 400px; }
}
What it's doing is changing the width of the lightbox from fixed 100% into a maximum of 100% (so that it's adjusted as per height). And then with #media, the height of the image is restricted. #media will allow for responsiveness based on browser height.
Higher resolution browsers will show the image at 900px height; those with a minimum of 700px height will show it at 600px, and smaller ones will show it at 400px.
You can of course adjust the numbers as per your preference; but this solution worked and solves the problem of long images.
Here's a jsfiddle. Note that using data-featherlight="image" is important for this to work properly.
Hope it helps.
In my opinion, the easiest way to both fit an image in the container and to center it is absolute positioning with margin: auto:
.featherlight img {
max-width:90%;
max-height:90%;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
margin: auto;
}
(Fiddle)
Alternatively, you can try to set the size of the image in viewport relative units (vw/vh), they have quite good browser support now: http://caniuse.com/#search=vw
Note: The following appears to be true only for Chrome, but it doesn't work in Firefox or IE...
After much twiddling around, my conclusion is that there's a fundamental difference in the way that height and width are treated in general and that it affects calculations here.
It's bound to be related to the flow of things, like how reducing the width of a <div> will have the content flow down, expanding the height, but how reducing the height of a <div> won't make it wider.
The clipping here is due to the fact that the border-bottom and padding-top are not taken into account in the available height. The solution is thus to remove those altogether.
If one still wants a border, then it can be faked by adding an absolutely positioned <div>. Here's the corresponding fiddle.
It gets cut off because the padding is throwing it off.
It doesn't work in IE or Firefox because they don't assume that the height of content div should stretch to fit its container's height. You would have to use height: 100% or some other percentage. This causes more problems when trying to achieve a max-height.
It doesn't enlarge the image when the size gets larger in height because that is the way most browsers handle re-rendering the page (or not re-rendering in this case) when the size of the viewport changes in height. You will have to force a re-rendering of the page. The only CSS way I know how to do that is with a CSS3 animation.
Here is a solution that does not work in Firefox or IE (so... not that great of a solution), but it fixes the cutting-off and resizing issues.
http://jsfiddle.net/SombreErmine/ENrnu/5/
It utilizes calc() and CSS3 animations; so it's definitely limited in practical use. I'm not posting this as the solution. I'm mostly posting it to share some information on what I've learned. Hopefully, this will help lead to a real solution.
HTML Code:
<div class="featherlight" style="display: block;">
<div class="featherlight-content">
<img src="http://placekitten.com/640/480" alt="" class="featherlight-image featherlight-inner"/>
</div>
</div>
CSS Code:
.featherlight {
position:fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: center;
background: rgba(0, 0, 0, 0.8);
}
.featherlight:before {
/* position: trick to center content vertically */
content:'';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
}
.featherlight .featherlight-content {
padding: 25px;
position: relative;
text-align: center;
vertical-align: middle;
display: inline-block;
min-width: 30%;
margin-left: 5%;
margin-right: 5%;
max-height: 95%;
background: #fff;
}
.featherlight .featherlight-image {
max-width:100%;
max-height:calc(100% - 50px);
vertical-align: bottom;
-webkit-animation: render_update 1s linear 0s infinite;
-moz-animation: render_update 1s linear 0s infinite;
-o-animation: render_update 1s linear 0s infinite;
animation: render_update 1s linear 0s infinite;
}
#-webkit-keyframes render_update { from { padding-bottom: 0.001px; } to { padding-bottom: 0px; } }
#-moz-keyframes render_update { from { padding-bottom: 0.001px; } to { padding-bottom: 0px; } }
#-o-keyframes render_update { from { padding-bottom: 0.001px; } to { padding-bottom: 0px; } }
#keyframes render_update { from { padding-bottom: 0.001px; } to { padding-bottom: 0px; } }
You can try the following approach. Elements that have a set width become wider when they have padding and/or border-width. To avoid these problems, make use of the now common box-sizing: border-box; reset.
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
An element can be centered by setting height: 100%; to a "ghost" element (it can be a pseudo element) inside the parent and vertical-align: middle; to both.
.featherlight {
background-color: rgba(0, 0, 0, 0.8);
bottom: 0;
font-size: 0;
left: 0;
overflow: auto;
padding: 0 5%;
position: absolute;
right: 0;
text-align: center;
top: 0;
}
.featherlight:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.featherlight-content {
display: inline-block;
margin: 5% 0;
max-width: 100%;
vertical-align: middle;
}
Images can be made responsive-friendly by applying max-width: 100%; and height: auto; to the image so that it scales nicely to the parent element.
.featherlight-content img {
border: 25px solid #fff;
display: block;
height: auto;
max-width: 100%;
}
See live example here: http://jsfiddle.net/cdog/AXzz8/.
This question already has answers here:
Prevent padding from making an element bigger?
(2 answers)
Closed 6 years ago.
I'm not a designer. When writing CSS it often happens that I need to add some padding to an element. How do you avoid that padding to propagate to the parent element ?
HTML:
<div id="outer">
<input id="login">
</div>
CSS:
#outer {
width: 300px;
}
#login {
width: 100%;
padding: 1em;
}
If you use that HTML+CSS, you'll see that the #outer element is bigger than 300px. The easiest solution if to re-write the #login's width to "300px - to_pixel(1em)". It works well but also means that now the font size needs to be fixed. Is there another way where I don't need to convert everything in pixels ?
What you want is the box-sizing property. Take a look at this jsFiddle for it in practice. Just add this:
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
to your #login CSS. This is supported in most modern browsers, including IE8+.
You can css box-sizing property like this:
#outer {
width: 300px;
background:red;
height:100px;
}
#login {
width: 100%;
padding: 1em;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
}
http://jsfiddle.net/TQXdn/
box-sizing does not work in IE7
Yes you have to fix this or adjust according to width + padding . The Actual Size when you are using padding will be
actual size = Defined Width + Padding Width + Border Width
then if you want to limit it to the container size then take care about the CSS box model
#outer {
width: 300px;
border:1px solid red;
padding:1em;
}
#login {
width: 100%;
}
It will put the input in center of the container.. Use Box Model as suggested in question comments also.
There is my solution:
width : calc( 100% - 10px );
padding: 5px;
#outer {
width: 300px;
background:red;
height:100px;
position: relative;
}
#login {
position: absolute;
left: 1em;
right: 1em;
top: 1em;
bottom: 1em;
}
See it here:
http://jsfiddle.net/22ABj/
I usually have my structure laid out something like this:
<div id="all">
<div id="page">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
</div>
Where the body will hold a background pattern, "all" will hold a dropshadow for the page going up and down, and "page" may often have a repeating-y background as well.
I have tried variations on using the css height/min-height properties:
html, body {
height:100%;
...
}
#all {
height:100%;
min-height:100%;
}
#page {
height:100%;
min-height:100%;
height:auto !important;
}
It seems like if I remove height:auto from "all" then it seems like it works UNTIL you scroll, then after the scroll the background for all dissappears
example
However if I keep the height:auto there then I get the problem of the background for page not working
example
Hopefully someone knows a fix?
Well, here's what I ended up with for the CSS:
html, body {
height:100%; /* IE6: treaded as min-height*/
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
color: #494949;
text-align: center;
background-color: #3f91a7;
background-image: url(images/bg_body.jpg);
background-repeat: repeat-x;
background-position: center top;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
#all {
margin: 0px;
padding: 0px;
height:100%; /* IE6: treaded as min-height*/
min-height:100%; /* real browsers */
height:auto !important;
background-image: url(images/bg_all.png);
background-repeat: repeat-y;
background-position: center top;
overflow: hidden;
}
#page {
width: 993px;
padding: 0 0 10000px;
margin-top: 0px;
margin-right: auto;
margin-bottom: -10000px;
margin-left: auto;
text-align: left;
background-color: #FFF;
background-image: url(images/bg_page.jpg);
background-position: center top;
background-repeat: repeat-y;
height:100%; /* IE6: treaded as min-height*/
min-height:100%; /* real browsers */
height:auto !important;
}
#header, #footer {
text-align: center;
font-size: 16px;
padding: 20px;
}
#content {
padding: 25px;
}
I haven't had a chance to test it in anything other than Firefox, but, hoipefully it will give you a good start.
I would just flip the location of your div#all and div#page...
<div id="page">
<div id="all">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
</div>
Although the question was posted some years ago, I ran into the same challenge and found this earlier thread today. Although I reckon there might be more fine solutions by now, I wanted to share the one I found today nevertheless.
Had the same problem, background 1 full screen, adaptive and fully below everything else and another repeating(-y) background number 2 should go on top, but not scroll out of sight because it was set to follow the height of the window which was given to the particular div which holds background 2.
Let's start with the divs I created:
<div id="full_background">
<img src="images/bkg_main.jpg" alt="" />
<div id="absolute">Contains background set to repeat-y</div>
<div id="content">Contains the content</div>
</div>
the css looks like this:
* { margin: 0px; padding: 0px; }
html { height: 100%; }
body { height: 100%; }
#full_background { width: 100%; min-height: 100%; position: relative; float: left; }
#full_background>img { position: absolute; top: 0; left: 0; position: fixed; width: 100%; z-index: 1; display: block; }
#full_background>div { position: relative; z-index: 2; }
#absolute { position: fixed !important; left: 0; width: 100%; height: 100%; background: url("../images/bkg2.png") top left repeat-y; }
#content { width: 290px; margin-left: 20px; padding: 30px; line-height: 1.7em; font-family: 'Lato', sans-serif; position: relative; float: left; }
First off, I added a full screen & resizing background image to my site (using the div full_background and the img tag) using the following solution (very easy css solution which works like a charm in every browser and most older versions down to for example IE7) - http://www.webdeveloper.com/forum/archive/index.php/t-256494.html > see last answer by aj_nsc
Next, using the following jQuery method - http://nicholasbarger.com/2011/08/04/jquery-makes-100-height-so-much-easier/ - I created a div with id = absolute, which is given the same height as the browser window (also on resizing). I placed my repeating(-y) background number 2 in here. Set this div to position:fixed and it will stay put when the div with the content is being scrolled through.
Then below this div you put the div with your content, which freely expands downwards beyond the browser window.
Upon scrolling, the two backgrounds will keep filling the full area of the browser window (vertically as well) at all times and stay put, with the content scrolling up and down over them.
This way, upon resizing, you also make sure that both backgrounds keep filling the full background area at all times.
I tested this solution in CH, FF, IE7-9 and Safari and it worked in all of them without any problems whatsoever.
Here's what's happening: You've set html & body to have a height of 100%, but that 100% is the height of the viewport, not the document. Since #all's height is set to 100%, it is set to 100% of the parent's height, which happens to be body, which is set at 100% of the height of the viewport. Everything's inheriting the height of the viewport.
The way to fix this problem is actually the same way you would fix clearing floats that have an outer container. All you have to do is put overflow:auto; on #all. You don't even need any height declarations on any other elements, and you may be able to eliminate either the #all or the #page div.
More info here: http://www.sitepoint.com/blogs/2005/02/26/simple-clearing-of-floats/
Have you tried:
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
#all {
min-height: 100%;
}
? Only for IE 6, you should set height: 100%; for #all (because it interprets that basically as min-height (as a result of a bug). As IE6 doesn't understand the min-height attribute, height effectively becomes a replacement for min-height).
If you set height: 100%; for other browsers, they will take it as 100% height of the viewport, not 100% of the page, so scrolling won't work correctly.
My comment on the downvote:
It has become clear, that my answer doesn't solve the whole problem. What we have here, seems to be quite a complex case - at least no one here seems to have found an answer yet? I've even looked into Ingo Chao's excellent (German) book, which comes to the same conclusion: Setting the parent's height won't work, and setting the child's height won't work, if the parent's height wasn't set explicitly, but rather dynamically by the size of the content.
But my answer could still help to restrict the possibilities a little bit - because setting height on #all will most likely not work on any browser except IE 6. If you disagree, please post a comment, because in that case, I'd also like to learn more about this.
This worked for me:
#page {
width: 993px;
padding: 0px;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
text-align: left;
background-color: #FFF;
background-image: url(http://jeffkilroy.com/hosted/layout1/images/bg_page.jpg);
background-position: center top;
background-repeat: repeat-y;
/* height:100%; IE6: treaded as min-height*/
height: expression(document.body.offsetHeight); /* sets min-height for IE */
overflow: auto;
min-height:100%; /* real browsers */
/* height:auto !important; */
}
Forget 100% on the divs, try moving your background image to the html element and the full height border to the body.
html {
height:100%;
background-color: blue;
}
body {
margin: auto auto;
padding: 0;
color: #494949;
/*min-height: 100%; */
height:100%; /*for ie6*/
border-left:solid 2px red;
border-right:solid 2px red;
background-color:#fff;
width: 960px;
}
Have you tried this :
function getWindowHeight() {
var windowHeight = 0;
if (typeof(window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
}
else {
if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
}
else {
if (document.body && document.body.clientHeight) {
windowHeight = document.body.clientHeight;
}
}
}
return windowHeight;
}
window.onload = init;
function init(){
document.getElementByID("all").style.height = getWindowHeight() + "px";
}
Or put page instead of all
I have a page with a variable-height header, content area, and footer. I want the content area to always fill the viewport, and grow vertically to fit content as necessary. I've found lots of examples of doing this with fixed-height headers, but none where the height is unknown.
Any solution needs to work in IE 6, 7 and 8, Firefox 3.x and Safari 4. Can this be done with pure CSS? Do I have to give in and resort to table-based layout?
EDIT:
An additional requirement is that I can place elements inside the content area and get them to expand to the full height of the content area (be it viewport height - header height - footer height or larger than that). Some of the content we want to display has "header" and "footer" sections of their own, so what I'm really looking for is a nestable solution.
Ok so the min-height CSS property doesn't work :)
I played around with an actual HTML file now and I believe I found a way.
.header-footer
{
height: 10%;
background-color: lightYellow;
display: table;
width: 100%;
}
.container
{
margin-left: auto;
margin-right: auto;
height: 80%;
width: 100%;
display: table;
}
.inner
{
background-color: lightPink;
height: 100%;
}
We use the display: table property to make sure each <div> sits nicely under and over the other ones.
NOTE: You have to set a height property for each of the elements on the page. It doesn't have to be as large as 10% that I chose, but at least something. Once the content is inserted into the element that is larger than the height value it should expand.
I've created two seperate HTML pages for you to examine to see if this suits you:
Content not larger than the viewport
Content larger than viewport
Hopefully this is what you're looking for.
Thanks
if you want the header to change size, use a relative height. The content will already fill the viewport vertically.
You can try using the min-height CSS property on the header, content and footer.
e.g.
.header-footer
{
min-height: 20%;
}
.content
{
min-height: 80%;
}
Make sure that you set both <html> and <body> tags to have a min-height: 100% that way you can fill up the entire viewport.
This should allow for the page to expand as needed but stay at a minimum of 100%.
Thanks
I spent a day experimenting with this option and hit so many odd dead-ends that my professional advice is now this:
You designed it wrong.
Skip the variable height header entirely. It's a dumb idea anyway. I did. Worked great for me. Now I am the proud owner of a significantly simpler DOM cobweb and no hurdles that lead me to stackoverflow.
Please see this fiddle: http://jsfiddle.net/qH6K3/
<div id="a">
<div id="b1">BOX1</div>
<div id="b2">BOX2</div>
</div>
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
html,body{height:100%}
#b1 {
background-color: red;
height: 45px;
width:100%;
}
#b2 {
background: blue;
height: 100%;
width: 100%;
}
#a { height: 100%; padding-bottom: 45px; }
Please try this for CSS: http://jsfiddle.net/K64Mm/6/
Variable height, content 100% height (supports even iframe 100% height), no superfluous scrollbars, scrollable on touch devices.
<div class="wrapper">
<div class="top topBar">
</div>
<div class="content">
<iframe scrolling="yes" src="http://www.zeffirino.com"></iframe>
</div>
</div>
html, body { width: 100%; height: 100%; overflow: hidden; margin: 0px; padding: 0px; }
.wrapper { width: 100%; height: 100%; padding-bottom: 45px; -webkit-overflow-scrolling: touch !important; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
.top { height: 45px; background-color: red; }
.content { height: 100%; width: 100%; overflow: auto !important; }
.content iframe { display: block; border: none; width: 100%; height: 100%; }