Given the following structure, I need level2 have a min-height without changing the structure. Further, I am not able to move the overflow: hidden to a different class (the example is simplified, it would affect a lot of other things). It works with px, but not with %. All other css properties can be changed.
I am aware of vh, which works exactly like it should. But I would love a solution with CSS2.
Fiddle
HTML:
<div id="level1">
<div id="level2">
<div id="heighter"></div>
</div>
</div>
body and html: height 100%
level 1: min-height 100%, overflow hidden
level 2: min-height 100%
heighter: height 200px
Edit: More informations about the overflow:hidden
I am using this for a offcanvas navigation. This is a place where I can't use max-width (right?). If I replace the overflow with the max-width, the layout gets recalculated and after that I am able to scroll the level2 on the x-axis (left and right). Same problem as here (click on Push-Menu-Left and then you are able to scroll the x-axis). What I am trying right now is preventing the x-axis scrolling and being able to use the min-height: 100% corretly.
In order to calculate min-height, div#level2 needs to refer to the height definition of its parent. In your code, div#level1 does not have a specified height. You an specify one like so:
#level1 {
height:100%;
overflow: hidden; /* This has to be here */
background-color: red;
}
WORKING EXAMPLE
EDIT:
Explicitly setting height on div#level1 (rather than setting min-height), you no longer need the overflow:hidden definition. Removing that allows the page to scroll when div#heighter expands beyond the browser's height.
(You mentioned that you need the overflow:hidden for other reasons. If possible, please edit your question to describe those reasons a bit more.)
#level1 {
height:100%;
background-color: red;
}
#level2 {
min-height: 100%;
background-color: lightseagreen;
}
#heighter {
height: 2000px;
width: 100px;
background-color: white;
border: 5px dashed black;
}
WORKING EXAMPLE
http://jsfiddle.net/b8uj75e5/3/
#level2 {
min-height: 1000px; /* Working */
min-height: 100%; /* Not working */
background-color: lightseagreen;
display: block;
position: absolute;
width: 100%;
}
IT LIVES.
I just messed around until it worked.
Related
Ok, so I have a mobile application with Cordova and AngularJS. For the styling I use Less and Bootstrap.
Problem
In the mobile app I have tried to size my divs with percentage (%). But this does not seem to work. I cannot seem to change the following behavior: The divs are as big as the content inside of them. This problem sounds quite easy and I have tried many options on here (stackoverflow) aswell as on the web. Yet I have not found the solution to fix it and it is getting quite annoying.
I have tried
Adding html, body { height: 100% },
Adding html, body, #canvas { height: 100%}
Adding #canvas { min-height: 100% }
Adding html { height: 100% } body { min-height: 100% }
And a lot of other variations. Using px works, but I don't know how big my mobile device is, so that isn't realy handy.. (I also use bootstrap and some media queries for styling).
Example
When I add elements to my div I get the following behavior:
I want to remove that white empty space, but I can only achieve that when using px instead of %.
Less example:
html, body {
background: transparent;
height: 100%;
margin: 0;
padding: 0;
}
#canvas {
min-height: 100%;
}
body {
-webkit-touch-callout: none; //prevent callout to copy image, etc when tap to hold
-webkit-text-size-adjust: none; //prevent webkit from resizing text to fit
-webkit-user-select: node; //prevent copy paste, to allow, change 'none' to 'text'
min-height: 100%;
margin: 0;
padding: 0;
background-color: #cgiColor;
}
.header {
top: 0px;
width: 100%;
height: 5%;
background: #companyColor;
color: #textColor;
}
.incidentContainer {
background: #appBodyColor;
width: 100%;
height: 70%;
}
.footer {
position: absolute;
color: #textColor;
bottom: 0px;
height: 15%;
width: 100%;
background: #companyColor;
}
Extra information
I am using AngularJS, so my application is a single page application. My index.html looks as follows:
<body oncontextmenu="return false" >
<div class="{{ pageClass}}" ng-view ></div>
<script type="text/javascript" src="cordova.js"></script>
<script data-main="main" src="lib/require.js"></script>
</body>
With of course the standard links to my CSS sheets, and so on.
All the other pages are includes in the 'ng-view' and don't have any or tags. This because they are included.
Solution
The solution was to add the following CSS rule:
div[ng-view]{
height: 100%;
}
This worked, because all divs (except for html & body) are children of this item. Adding the 100% made the div space span to 100% of the screen and thus provides a space for percentage to work.
Credits go to Jai for this answer!
Have you tried to add the following css and set Important attribute
html, body { height: 100% !important }
What seems to me, the directive ng-view is the parent of your application and header, content, footer are loaded in this div. So you have your header div at correct place, your footer is also placed correctly as it is absolutely positioned.
But in case of your content area, that is relative to the ng-view div.
I would recommend you to make it 100% height. Something like:
div[ng-view]{
height: 100%;
}
This most likely is because of the fact that in CSS the 100% is a relative value.
With width the default 100% is the width of the screen, or whatever you are looking at.
Height however does not take the height of the screen as 100%. It needs a solid value.
I think that if you change
html, body {
background: transparent;
height: 100%;
margin: 0;
padding: 0;
}
with
html, body {
background: transparent;
height: 100vh;
margin: 0;
padding: 0;
}
it should work.
The 100vh should set the height of the html to the height of the viewport.
I guess this way works, I have to say though that I myself have not used something to get my page to have a height that is 100% of the screen.
Yay, rendered HTML!
class="incident" is only expanded as large as it needs to be. I believe your fix should be to make that element have a height of 70% (because it will be relative to the whole-page) and then incidentContainer should have a height of 100%.
Percentage heights are relative to the parent element, not the root, so you need to be very aware of any containers, even ones stealthily added by a framework.
Also, if it helps, Jelmergu suggested the vh unit type. This could fit your use case - one "Viewport Height" is equivalent to "1% of the browser's content area". So, 100vh would take up the whole screen. This is true even on deep-level children.
I've come across numerous question of the similar nature but my situation is a bit different; my outer container is height 100% instead of a fixed height.
I have a bunch of divs inside a container. They overflow and I want to have a scrollbar to allow scrolling.
This is exactly what I want to achieve: http://jsfiddle.net/jcjw2jmo/
Except, the link I posted has a fixed height: 200px;. I want to have a percentage height instead.
I've tried setting a percentage height and max-height with no luck. Here's my progress: http://jsfiddle.net/k52eh0xr/
How do I get both the fiddles to have the same behaviour but with using percentages instead?
Thanks so much
PS. I know this can be done using Javascript/jQuery but I am looking for a CSS-only solution
I think you need set your html and body tag with height:100% so you can use percent like you want
html, body {height:100%}
DEMO
The problem you're having relates mostly to using percentage heights in CSS.
If you're going to use a percentage height on a child element, you need to specify the percentage height for all parent elements up to and including the body and root elements (html).
Try this in your code:
HTML (no changes)
CSS
/* NEW */
html, body {
height: 100%; /* necessary when using percentage heights within body
on non-absolutely positioned children (such as .outer)
more info: https://stackoverflow.com/a/31728799/3597276 */
overflow: hidden; /* prevent vertical scrollbar on browser window,
in conformance with demos posted in question */
}
.outer {
border: 1px solid black;
height: 50%; /* ADJUSTED */
/* max-height: 10%; REMOVED */
overflow-y: scroll;
width: 300px;
}
.inner {
/* height: 10%; REMOVED
max-height: 10%; REMOVED */
}
.item {
background: grey;
border: 1px solid red;
height: 50px;
}
DEMO: http://jsfiddle.net/k52eh0xr/5/
I have the following layout (I'm using Meteor):
<template name="headerFooter">
<div class="container-fluid fill-height">
{{> header}}
{{> UI.contentBlock}}
{{> footer}}
</div>
</template>
<template name="home">
{{#headerFooter}}
<div class="row body-film">
<div id="newsfeed" class="col-sm-offset-7 col-sm-5 block-film">
{{#each stories}}
<div class="story">...</div>
{{/each}}
</div>
</div>
{{/headerFooter}}
</template>
and this (relevant) css backing it up:
html {
height: 100%;
}
body {
min-height: 100%
}
.fill-height {
height: 100%;
}
The html and body elements are both behaving as expected. They fill their areas at any zoom level or size.
However, the container-fluid with the fill-height class added isn't doing the job. It's only wrapping it's content, and not filling to the bottom. This is a problem because it is responsible for adding body-film and block-film to the page, which are just semi-transparent backgrounds to give the whole thing some color unity.
Here are some screenshots, all with the page zoomed out so the content doesn't fill the height:
Now here it is with the body element selected. As you can see it fills the parent just fine.
But the container-fluid doesn't.
With fill-height I've tried both height and min-height, and they look exactly the same.
Your help is appreciated!
Update
I've been trying every possible combination of min-height and height on these three elements, and nothing works properly.
height on all three works when the content is too small for the viewport, but when the content is too large for the viewport, the content block overflows out of the body entirely, which means the films are too short for it.
min-height on all three seems to me to be the most logical way to go, but it breaks when the content is too small. In this case, the body element doesn't stretch to fill its html parent.
What's going on!!!!????? Is this a bug in the new Blaze templating engine Meteor uses?
Update
I've just tried height: inherit in my fill-height, and it didn't work either. I'm really at the end of my rope. This seems like it should be so simple.
Update
Alright, I've got a slight change to happen. With this less:
.fill-height {
min-height: 100%;
height:auto !important;
height: 100%;
}
.body-film {
.fill-height();
}
.block-film {
.fill-height();
}
The container-fluid is now full height, but not the body-film and block-film which are using the exact same mixin!!
Here is a screenshot, showing the row.body-film, which should be full height, since the container-fluid above it is (take my word for it, the container-fluid is now stretched to fill the body).
Note, manually adding the fill-height to the html declaration of the row didn't change anything, it behaves identically as if it were simply receiving that through the body-film mixin.
Why is it that some elements don't respond at all to all of these min-height demands?
P.S., I'm using Chrome, but it is on a ubuntu machine, so I can't be sure if there are any inconsistencies.
Answer
The following ended up working:
html, body {
height: 100%;
}
.container-fluid {
height: 100%;
overflow-y: hidden; /* don't show content that exceeds my height */
}
.body-film {
height: 100%;
overflow-y: auto; // a value of 'scroll' will force scrollbars, even if they aren't necessary. This is cleaner.
background-color: fadeout(#studio-bar-color, #studio-body-film-trans-delta);
}
.block-film {
min-height: 100%;
overflow-y: hidden; /* don't show content that exceeds my height */
background-color: fadeout(#studio-bar-color, #studio-block-film-trans-delta);
}
The overflow attribute was extremely key, and it's something didn't previously know much about. Giving a scroll value to the entire body (the thing that needed to be able to move up and down) was the answer, as well as giving the innermost element (block-film) the min-height to ensure it stretched itself and subsequently all of the parent elements.
I know you said you've tried every combination, but what about:
html, body {
height: 100%;
}
.fill-height {
min-height: 100%;
height:auto !important; /* cross-browser */
height: 100%; /* cross-browser */
}
The problem with setting min-height: 100% on the body, is that height: 100% on the child div does not actually have a proper parent height to reference, and will not work.
EDIT:
This logic applies to all child divs. So in your case, the body-film div is a child of container-fluid. Because container-fluid now has a min-height of 100%, and not a defined height (it is set to auto), when you give a height percentage to body-film, it doesn't have a height to reference. It's worth having a read of MDN - CSS height and MDN - CSS min-height.
In other words, if you wish to have a div with a height or min-height of 100%, then all of its parent elements need to have a defined height of 100%, all the way up to the html tag.
What you may need to do is something like this:
html, body {
height: 100%;
}
.container-fluid {
height: 100%;
overflow-y: hidden; /* don't show content that exceeds my height */
}
.body-film {
min-height: 100%;
overflow-y: scroll;
}
This may not be the definitive answer as it depends on what you want exactly, but hopefully this sets you on the right track.
Although this doesn't directly relate to the html sizing problems, I recently discovered a much easier way to achieve this sort of "transparent film" thing, using box-shadow.
This article breaks it down pretty well. He also offers other methods, but frankly this seems like the simplest.
<div class="example"></div>
.example {
position:relative;
width: 300px;
height: 313px;
box-shadow: 0px 313px rgba(255, 0, 92, 0.6) inset;
background: url(/img.png);
}
I have encountered what I consider a bug in Safari and was wondering if anyone might be able to shed some light on why this outcome is taking place. I have included a very simple example below, but basically my issue is this. I have a child element with a width of 300px and a height of 80px, I have a this child nested in a parent with a width of 0px and an overflow that is hidden. These two elements are wrapped in a container that has no width set and all three elements are floated left. The content is being hidden by the parent, however the container that is wrapping them both is extending the full width of the "hidden" child. Works great in every browser except Safari and I don't know why.
summary: width: 0px; and overflow: hidden; does not work in safari
<html>
<head>
<title></title>
<style type="text/css">
#container {background: rgba(0,0,255,1); float: left;}
#block {width: 0px; background: rgba(255,0,0,0.50); float: left; overflow: hidden;}
#content {width: 300px; height: 80px; background: rgba(0,255,0,0.50);}
</style>
</head>
<body>
<div id="container">
<div id="block">
<div id="content"></div>
</div>
</div>
</body>
</html>
Certain display values seem to be where the bug happens in Safari.
After a lot of trial and error it seems that a good solution may be setting max-width to the same as width. Keep in mind that if you animate width you need to set max-width to something that allows width to expand (possibly a value of auto), temporarily, while the animation occurs.
Read the various CSS comments below to understand more about this problem.
HTML:
<div id="container">
<div id="block">
sfdklhgfdlkbgjhdlkjdhbgflkjbhgflkdfgid
</div>
</div>
CSS:
#container {
flex: 0 0 auto;
background: red;
/* BUG: Certain display values seem to be where the bug happens, if display was just inline here, there would be no issue. */
display: inline-flex;
overflow: hidden;
border: dotted 2px green;
}
#block {
width: 0;
/* height: 0; Setting height to 0 simply creates the illusion that width is fixed. If you look at the border, the width is still there, so height 0 does not help. */
background: blue;
/* BUG: Certain display values seem to be where the bug happens, if you don't need this, change it. */
display: inline-flex;
overflow: hidden;
/* Has no practical effect here. */
text-overflow: clip;
/* font-size: 0; still keeps a little bit of width and can spoil the look of animating the width open from 0. */
/* margin-right: -100vw; is a nasty hack that totally works but is bad for animating margins. */
/* BEST FIX: Setting this property to the same as width may be the best way to fix the issue. */
max-width: 0;
}
Running example at: https://jsfiddle.net/resistdesign/k0b5s4p7
If you are presentnig text inside that div. Then, you should try to zero font-size.
.class{
font-size:0;
}
Or use text-indent
.class{
text-indent: -999px
}
If you also set height: 0; on #block your problem will be solved. Not sure why this is happening though :/
Please look at the following: http://jsfiddle.net/ran5000/uZ7dD/
the header div has a fixed height of 40px, I want that the content div will use the remaining height of the screen without scroll and regardless of the screen height.
any ideas?
I generally use position:absolute for this, and then set the top value to start at the bottom of the header.
http://jsfiddle.net/uZ7dD/4/
.content {
background-color: yellow;
position:absolute;
top:40px; bottom:0; left:0; right:0;
}
Do you mean like that?
If so, I've used
position: fixed;
property in CSS.
I'm not sure what the browser support is like for the calc CSS feature, but this would be a good case for it. You can read about it here. You would need to change the height of the content div to height: calc(100% - 40px). This, of course doesn't take into account any space taken up by margin, padding, or border so it will still overflow a bit. If you make sure your divs don't have any of those it works perfectly. Here is my JSFiddle for it.
You can also use position: absolute and set the top value to 40px and the bottom to 0px but your parent element needs to have position: relative set.
Alternatively, you can use JavaScript/jQuery to calculate the required height of the content div and apply it.
For css3 browsers just use:
.content {
width: 100%;
background-color: yellow;
height: -moz-calc(100% - 40px);
height: -webkit-calc(100% - 40px);
height: -o-calc(100% - 40px);
height: calc(100% - 40px);
}
for non-css3 browsers use this workaround,
HTML:
<div class="container">
<div class="header">i am the header</div>i am the <content></content>
</div>
CSS
.header {
width: 100%;
height 40px;
line-height: 40px;
background-color: blue;
}
.container{
height: 100%;
background-color: yellow;
}
Hope I could help :)
In this case, the properties of table elements have some advantage in the fact that they have a lot of positioning power. In this case specifically, table rows and cells will always adjust to fill the table container.
Obviously, you don't want to be using actual table html elements, as that would not be semantic, which is where css comes into the game:
If you put a container/wrapper element around both your header and content, and then set it to be display: table; with 100% height and width it will act as the base table element.
Setting your header and content to display: table-row; will now associate them with that container and allow everything to share the table properties. Setting a fixed height on one will still work, and the other will simply fill the remaining space.
<div class="container">
<div class="header">i am the header</div>
<div class="content">i am the <content></content></div>
</div>
And the css:
.container { display: table; width: 100%; height: 100%; }
.header, .content { display: table-row; }
This approach also has the benefit of being well supported across browsers.