UI-Router: Height:100% on body element ignoring nested view height - css

I'm building an angular application that frequently uses nested views. Certain views, however, are taller than the other elements on the page and end up extending well beyond the end of the parent view.
I'm using Ryan Fait's Sticky Footer so I have a wrapper around a containing div set to height:100% and I would have expected the page to just adapt and move the footer to the bottom of the nested view however I'm seeing the style elements of the footer border and background-color are remaining at end of the parent div while the content of the footer is being pushed to the end of the nested div.
Including an image as I'm struggling with getting the language exact:
I'm really looking for any solution from fixing the css to something that seems hackier like changing the footer or using ng-if/ng-class on certain pages. I'm imagining I'm misunderstanding something about CSS/UI-Router but I can't really track it.
The code isn't really interesting but here is it?
CODE
.wrapper {
min-height: 100%;
margin-bottom: -50px;
}
.push {
height: 50px;
}
.footer {
display: block;
height: 50px;
}
.nested {
max-height: 500px;
}
<body>
<div class="wrapper">
<div>
<h1>Some text</h1>
<ui-view class="nested"></ui-view>
</div>
<div class="push"></div>
</div>
<footer class="footer">
<span>some copy</span>
</footer>
</body>

If you use percentage values for height (i.e. a relative height), the parent element heights have to be defined too. In your case you also need height: 100% on body and html, like
html, body {
height: 100%;
}

Related

Making an element expand to the width of its contents (when the contents are wider than the viewport)

After about 15 years writing CSS, I'm still discovering things I don't understand...
Below is a simple page with an h1 element that is 2000px wide. As expected, this causes the page to have a horizontal scrollbar.
But the problem is, the parent div.wrapper does not expand to the width of its contents – its yellow background only extends as far as the width of the viewport. (Run the below snippet and scroll horizontally to see the problem.)
body { margin: 0; }
.wrapper { background: yellow; }
h1 {
width: 2000px;
border: 2px solid red;
}
<!doctype html>
<html>
<body>
<div class="wrapper">
<h1>Hello</h1>
<p>More content</p>
</div>
<p>More content outside wrapper</p>
</body>
</html>
Here's the weird thing: Try adding body { position: absolute } to the above CSS and it fixes it. The div.wrapper now extends to the width of its contents – the yellow goes all the way to the right of the document.
Questions:
Why does setting body { position: absolute } fix the problem?
Are there any better (more intuitive) ways to fix the problem?
Constraints: I do not always know the width of the inner contents, I just want the wrapper to always extend so its background color goes all the way to the right of the contents.
Let's start with this:
But the problem is, the parent div.wrapper does not expand to the
width of its contents – its yellow background only extends as far as
the width of the viewport.
By default a div is a block element and a block element takes up the whole width of it's parent container so your wrapper in this case has the width of the body which is the width of the screen. In addition to this we are facing an overflow as the child content width is bigger than the parent width and by default:
Content is not clipped and may be rendered outside the padding boxref
This explain why the background doesn't cover the h1 as this one is rendred outside.
To change this behavior we have two solutions:
We change the behavior of overflow by specifing a value different from visible (the default one). By doing this you will also notice some changes to margin because you are also facing a margin collapsing (margin of h1 and p are collpasing with the margin of div.wrapper).
body {
margin: 0;
}
.wrapper {
background: yellow;
margin:10px 0;
}
h1 {
width: 2000px;
border: 2px solid red;
}
<div class="wrapper" style="overflow: auto;">
<h1>Hello</h1>
<p>More content</p>
</div>
<div class="wrapper" style="overflow: hidden;">
<h1>Hello</h1>
<p>More content</p>
</div>
<div class="wrapper" style="overflow: scroll;">
<h1>Hello</h1>
<p>More content</p>
</div>
<p>More content outside wrapper</p>
We change the display property of the element to something else than block. We can for example use inline-block or inline-flex and in this case the wrapper will fit the content of its element and he will overflow the body
body {
margin: 0;
}
.wrapper {
background: yellow;
display: inline-block;
}
h1 {
width: 2000px;
border: 2px solid red;
}
<div class="wrapper">
<h1>Hello</h1>
<p>More content</p>
</div>
<p>More content outside wrapper</p>
Concerning this:
Why does setting body { position: absolute } fix the problem?
We all know what position:absolute means but the intresting part is this one:
Most of the time, absolutely positioned elements that have height and
width set to auto are sized so as to fit their contents. However,
non-replaced, absolutely positioned elements can be made to fill the
available vertical space by specifying both top and bottom and leaving
height unspecified (that is, auto). They can likewise be made to fill
the available horizontal space by specifying both left and right and
leaving width as auto. ref
You haven't told the div how to handle the overflow caused by the width of the inner element. Add overflow: auto.
body { margin: 0; }
.wrapper { background: yellow; overflow: auto; }
h1 {
width: 2000px;
border: 2px solid red;
}
<!doctype html>
<html>
<body>
<div class="wrapper">
<h1>Hello</h1>
<p>More content</p>
</div>
<p>More content outside wrapper</p>
</body>
</html>
I do not believe that there is an obvious reason why adding position: absolute to the body fixes this. It does take body out of the document flow, but body is the container for all the content. So I would describe it as a quirk.
We could describe body as being the initial constraint for the width of the content, the .wrapper. Being absolute removes this constraint. Actually, it likely remove the width constraint for any further elements on the page, so they will probably all expand to contain any inner content.
Yeah, you can use width: fit-content;
MDN describes it as;
fit-content
The larger of:
the intrinsic minimum width
the smaller of the intrinsic preferred width and the available width
It works as expected; the containing element expands. But, as usual, IE lags behind and doesn't support it...
EDIT To be clear; this specification is still in Working Draft status, and as such should not be used in production environments (except if you don't care about Internet Explorer).

100% height is making div overflow

this question is probably pretty common, as i've been going over answers here for the past 3 hours. and still, no success.
I have a parent html which takes 100% height of the page. the body takes also 100% of the page.
In the body element i have 3 divs. i have the 3rd and last one, to take the rest of the page and leave no whitespace after it (which it does now).
tried height: 100%; on the last div and overflow: hidden; on the body element. this just stratches my page and removes the scroll bar (but the website still scrolls O_O ).
please help.
edit: it seems the question itself isn't clear.
I want the last div to take the rest of the page height to the end of it.
#div1{
max-height: 150px;
}
#div2{
max-height: 150px;
}
#div3{
padding: 10px 0;
margin: 0;
height: 100%;
}
all nested inside a body element which is nested inside html element.
I also have hidden info which is required to show when i click.. so i do need the page to stratch, if any more info is added to the page (hiding overflow on the entire document is going to be a problem than)
Maybe try this code:
<body>
<div id="container" style="height: 100%"; overflow="hidden">
<div>
asas
</div>
<div>
sdsd
</div>
<div>
wewe
</div>
</div>
</body>

body background extends into margins or is cut-off when scrolling

I have a layout where I need to use height: 100% on html and body (and any wrapper divs I resort to using) to achieve an effect similar to pages, so that the content on my first "page" is centred, scrolling down the content on the second "page" is centred etc.
The html looks like this:
<section class="page" id="p01">
<div class="spacer">
</div>
<div class="outer">
<div class="inner">
Some content
</div>
<div class="inner">
Some content
</div>
</div>
</section>
<section class="page" id="p02">
<div class="spacer">
</div>
<div class="outer">
<div class="inner">
Some content
</div>
<div class="inner">
Some content
</div>
</div>
</section>
and the vertical centring etc. achieved with this styling:
body, .page {height: 100%; margin: 0 auto;}
.spacer {
float: left;
height: 50%;
margin-bottom: -150px;
}
.outer {
height: 300px;
width: 100%;
background-color: #fca;
clear: both;
position: relative;
display: block;
white-space: nowrap;
}
.inner {
width: 41%;
margin: 0 6%;
height: 300px;
background-color: green;
display: inline-block;
vertical-align: middle;
white-space: normal;
}
.inner:first-child {
margin-right: 0;
}
You can see it at work in this fiddle:
http://jsfiddle.net/terraling/3V5rV/
The problem is the body background (here I'm just using color, but on my site it will be an image) leaks out into the body margins, i.e. the body content has a max-width and should be centred with white margins.
I can fix that either by... setting html background-color to white, as per
http://jsfiddle.net/terraling/yM53t/
...but body background becomes cutoff when scrolling into the second page (that wasn't a problem in the first fiddle).
Alternatively I could set the background image on a wrapper div and not on the body. That solves the problem of it leaking into the body margins, but it still has the same problem that it is cut off on scrolling.
(see: http://jsfiddle.net/terraling/3V5rV/1/ )
Any solution that involves removing the height: 100% declaration from any of html, body or wrapper collapses the layout (including replacing with max-height: 100%).
There's a whole lot of problems with this construct and not all of them can be solved, unfortunately.
The background issue
As you have seen yourself the background of body extends to the viewport if html does not have a background. That's solvable.
The float issue
When an element floats it does not contribute to the height of its parent element. So they don't grow (e.g. body does not expand). That can be solved if you can use alternatives. For vertically centering an element you could use display: table-cell e.g., which allows you to vertically center the content.
The height issue
This is where all hope is gone. height: 100% refers to the height of the parent, of course. The parent of body is html which in turn is the child of the viewport. You gave html the size of 100% (= the size of the viewport) and body the size of 100% (= size of html = size of viewport).
So now body has a fixed height and it can't expand meaning the background doesn't expand as well. Now one might have the idea to give body no size so that it can expand. But .page has 100% too. If a parent (in this case body) has no fixed size 100% has no meaning and will be treated as auto, which means as big as the content. And the content has a height of 300px. So the .page elements wouild no longer have the height of the viewport but 300px.
As for the collapse of the CSS, you should either specify the height specifically height:200px; or add padding to the bottom/top of the page so that the content wraps. You can also use min-height:200px; then add the margin-bottom:20px; to separate the pages. I would approach this at a specific height with the wrapper having the specific background-image and bottom-margin.
In order to center your background-image to the <html> you can specify the position as 50%.
This can be done by doing background:url('yourimage.jpg') repeat 0 50%;This will ensure the background is centered.

Footer not sitting at bottom of the page

I'm having issues with the footer on a site I'm making. It won't sit at the bottom. I know its a common complaint, but everything I've tried either hasn't worked or broke other CSS elements.
I've loaded the website on a temp domain for you to see.
It's on we-sx.com.
I want the footer to sit under the .container div which has a box-shadow effect.
Because you have:
position: absolute;
on the class ".container"
Remove that and it should be under the div.container
Now that will cause your div.container to collapse because of the two floated elements inside. You will need a clearfix for that issue. You could add this to your "content" class.
.content:after {
content: "";
display: table;
clear: both;
}
here you can find some code as follows
Add the following lines of CSS to your stylesheet. The negative value for the margin in .wrapper is the same number as the height of .footer and .push. The negative margin should always equal to the full height of the footer (including any padding or borders you may add).
In CSS:
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}
Follow this HTML structure. No content can be outside of the .wrapper and .footer div tags unless it is absolutely positioned with CSS. There should also be no content inside the .push div as it is a hidden element that "pushes" down the footer so it doesn't overlap anything.
In HTML Body:
Your website content here.
<div class="push"></div>
</div>
<div class="footer">
<p>Copyright (c) 2013</p>
</div>
This is a common problem, and the best solution I've seen is this:
http://ryanfait.com/resources/footer-stick-to-bottom-of-page/
Basically you're putting all of your content in a div that has a minimum height of 100%, and that pushes the footer div to the bottom.

Sticky footer, or rather: content doesn't stretch down to footer

So I wanted a sticky footer on a page and got this one to work for me. All is well, but no, not really..
The problem is that I wanted the content above the footer to stretch all the way down to it. Now the box containing the main content end just after the text in the box, and there's a large space between the footer and the content. What I want is the background of the main content to stretch down to the footer!
See my beautiful image!
This is what I have right now in html:
<div id="wrap">
<!-- start header -->
<div id="header">
<div id="header-content">
</div>
</div>
<!-- end header -->
<!-- start main -->
<div id="main">
<div id="main-content">
</div>
</div>
<!-- end main -->
</div>
<!-- start footer -->
<div id="footer">
</div>
And in css:
html {
height: 100%; }
body {
height: 100%;}
/* wrap */
#wrap {
min-height: 100%; }
/* main */
#main {
background-color: #43145c;
overflow: auto;
padding-bottom: 50px; }
#main-content {
width: 720px;
margin: auto;
background-color: #643280;
padding-top: 20px; }
#footer {
position: relative;
margin-top: -50px;
height: 50px;
clear: both;
background: red; }
I tried setting min height of main to 100%, but didn't work. I just want the backgroundcolor of main-content all the way down to footer, since it's different to the body and main box.
Does it make any sense? Can anyone help?
I know this was asked 6 months ago, but I've been searching for the solution to this problem for quite a while now and hope other people can benefit from the solution I employed being archived. You were spot on when you said that somehow the main box needs to get the min-height of the space between the header and footer.
Unfortunately, I don't know how this can be done with pure CSS, it's quite easy with javascript of course but that solution is not always viable, and it's kind of messy in terms of code separation. The good news is that depending on what you need to do, there is a CSS hack you can employ.
What I did was add an absolutely positioned element below body that essentially stretched from below the header to above the footer.This way I could add a background or a gradient on this #divBelowBody that essentially allowed me to pretend this problem is solved (although this solution leaves a bitter taste in my mouth).
In addition, if you wanted to add a border around your content div and were hoping that it extended to the footer even when content was small, you're screwed (although not really, I can probably think of a hack or two to make this workable), so it only works if you were hoping to add a background or gradient etc.
You can see the code in action here:
http://jsfiddle.net/qHAxG/
Expand the result section horizontally to more clearly see what's going on.
Try this:
Replace your HTML and BODY Styles in the Style Sheet with this:
html,body {height: 100%;}
Then replace your "wrapper" with this:
#wrap {
min-height: 100%;
height: auto;
}
Hope that helps.
Try this
HTML
<body>
<div id="wrap">
<!-- start header -->
<div id="header">
<div id="header-content">
</div>
</div>
<!-- end header -->
<!-- start main -->
<div id="main">
<div id="main-content">
</div>
</div>
<!-- end main -->
<div class="push"></div>
</div>
<!-- start footer -->
<div id="footer">
</div>
</body>
CSS
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
/* wrap */
#wrap {
background: green;
height: auto !important;
margin: 0 auto;
}
#wrap,
#main,
#main-content {
margin-bottom: -50px;
min-height: 100%;
height: 100%;
}
/* main */
#main {
background-color: #43145c;
}
#main-content {
width: 720px;
margin: 0 auto;
background-color: #643280;
}
.push, #footer {
height: 50px;
}
#footer {
position: relative;
background: red;
}​
see THIS demo: it might be of use. It seems like you want a div with a background color to stretch to the bottom. But the problem with the sticky footer is that it stays at the bottom also - get's out of your way when the content extends past the view-port. So It needs some distance ( height of the content ) to know how when to do that. If that height isn't designated by actual content... 100% isn't really going to do the trick either. because then the "sticky" footer doesn't really work... it would be off the screen. What is it really 100% of ?
this whole thing has frustrated me for a year... but I always find a way to make it look the way I want even if I can't get it to function the way I want... hopefully that link demo above will maybe lend another piece to the puzzle. Good Luck !

Resources