I'm wondering if this is a bug or (more likely) a misunderstanding in using the dev tools / CSS. I was playing around with a JSFiddle with the following style:
div.notrelative {
height: 100px;
width: 100px;
background: #eaf;
margin: 50px;
font-size: 9px;
position:relative;
font-family: Arial;
}
body {
margin:30px;
}
div.absolute {
height: 20px;
width: 20px;
position: absolute;
background: #eea;
margin-bottom: 10px;
top: 0;
left: 0;
and I was looking at the highlighted areas in dev tools both on JSFiddle and on a local copy, and I noticed something strange. Chrome was only highlighting a portion of the body in blue (after the top margin by the child element but strangely not the left margin), despite the body taking up the entire page (as seen by the gray background color). However, just creating something simple like a border around the body completely seems to fix the highlighting issue. Is there a reason why Chrome highlights differently in the two cases?
Margin collapsing causes div.notrelative to extend its margins outside of <body> vertically and push <html> to be bigger than <body>. Thus, when you highlight <body>, the area beyond <body> but within <html> is not highlighted. That unhighlighted area represents the margins of div.notrelative. Adding borders prevents margin collapsing in the case of parent and first/last child.
As for why that area outside <body> is affected by its background-color, based on the answer here, it is because <html> takes the background-color of <body>.
Related
I am trying to understand the rules behind z-index and how it interacts with the overflow property.
I have this html:
<body>
<div class="cell">
Here is some text to keep things interesting
<div class="boxy"></div>
</div>
</body>
And this css:
.boxy {
position: absolute;
z-index: 9999;
top:70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
position: relative;
/* comment these two lines out and the box appears */
/* or change them both to 'visible' */
/* changing only one of them to 'visible' does not work */
overflow-y: auto;
overflow-x: auto;
}
I would have expected that the cyan box appears even though it is out of the size of the div.cell because its z-index and its position are set.
However, the only way to make the cyan box appear is to comment out the overflow-x and -y lines.
My question is: How can I make the cyan box appear on the screen while keeping the overflow as either hidden or auto? But more importantly, I'm looking to understand why this is happening. What are the css and layout rules being applied here?
See my Plunkr. This example, is of course a much simplified version of the HTML/CSS I am actually working with.
EDIT
There seems to be some confusion in the answers below because I didn't explain things well enough. If you comment the two overflow lines out, you can see that the cyan box appears. It appears outside of the border of .cell. Why does this happen? How can I make the cyan box appear, while still hiding overflow and z-index?
The reason the cyan box appears only when overflow-x and overflow-y are visible, and disappears otherwise, is simply because the cyan box is overflowing the cell box. overflow: visible simply means "paint this box even if it is overflowing its containing block" — the cell box is the containing block of the cyan box because its position is relative. Any other values of overflow cause overflowing content to be clipped from view. There is nothing special going on here; in particular, the z-index is completely irrelevant and there is no such interaction as the question title alludes to (and there really is no reason to set it to such a huge number unless you're worried about scripts injecting other elements into the cell).
The only way to allow the cyan box to appear while the cell has a non-visible overflow is to remove position: relative from the cell and apply that declaration to the parent of the cell (in your example, it's the body). Like this:
body {
position: relative;
}
.boxy {
position: absolute;
z-index: 9999;
top: 70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
overflow: auto;
}
<div class="cell">
Here is some text to keep things interesting
<div class="boxy"></div>
</div>
Absolute-positioned elements do not contribute to the dimensions of their parents.
Therefore, the .cell DIV has no content that affects its dimensions, making it 100% wide by 0px high.
To make the element appear, you'll have to add a height to .cell that will encompass the DIV, in this case 120px (70px top + 50px height).
The Parent Class cell need to be set it's height. because height of absolute element doesn't affect it;s parent.
.boxy {
position: absolute;
z-index: 9999;
top:70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
position: relative;
/* comment these two lines out and the box appears */
/* or change them both to 'visible' */
/* changing only one of them to 'visible' does not work */
overflow-y: auto;
overflow-x: auto;
min-height: 120px; /* height 70px(Top)+50px*/
}
Your problem
Your problem is related to cell node that hides boxy when overflow is specified on cell node.
The reason
The reason behind is that boxy with position absolute does not contribute to height of cell and overflow hides it.
Why is it shown without overflow?
By default overflow is visible, which for browser means do not do anything special for overflow functionality and it does not need to render overflow => does not hide boxy.
Z-indices are local inside their clipping hierarchical parent context. This is very non-intuitive. They have their own z-stack context, which normally parallels that of the enclosure hierarchy. But they're still subject to clipping! Which can be a real pain if you're intuitively expecting the z-indices to be absolute.
Note that some jquery containers, such as accordion, quietly specify overflow: auto. Even if it's not explicitly in your code. (This can be overridden locally after it's found.)
Also note that if overflow-x: visible is set, but overflow-y is set to a non-visible, then the rendering engine quietly internally changes overflow-x to be the same as overflow-y for your amusement. But you found this out already.
You probably should be able to circumvent the unwanted non-"visible" overflow clipping, even with your high z-index, by invoking transform: translate(0,0); [or whatever desired offset, % or pixels] inside the style of the div that you want to levitate. Transform should create a new local z-stack for that element and its children. Which will let you get around an overly-restrictive parent or grandparent.
I'm trying to get a simple page layout where the navbar sits vertically along the right side of the user's window, taking up no more than 20% of the available space. The remaining 80% of space to the left is used for content.
I want the entire page to be resizable, so no matter how big or small the browser window is (within reason), the content will resize to the user's screen. Everything works and resizes great, but there's one problem with the navBar. Here's a CSS excerpt:
body{
background-color: #111111;
font-family: Roboto;
color: #cccccc;
font-weight: 300;
font-size: 14pt;
height: 100%;
}
#content{
width: 80%;
float: left;
}
#navBar{
width: 20%;
height: 100%;
background-color: #00C9FF;
float: left;
position: absolute;
}
#welcome{
background-color: #222222;
text-align: center;
margin: 1%;
}
The Problem:
If I leave the code above as is, the navBar renders on the right side of the screen, as it should, but it is not 100% the height of the browser window. Note it still resizes when the browser window's WIDTH is changed.
If I set navBar's position to absolute (position: absolute) the navbar renders exactly how it should render, except it floats to the left side of the browser, basically making it on the complete opposite side of where it should be.
Demo: http://codepen.io/anon/pen/YPyvzO (remove position: absolute to see where the navBar SHOULD render)
I have tried several different things including setting "HTML" in CSS to height: 100% and several different position properties for navbar, all to no avail. I'd like for this to be done only in CSS, but I'm not sure if it's possible.
Add the following:
position: absolute;
right: 0;
to #navBar. One thing that took me a long time to understand is that position: absolute overrides everything, even floats.
when you resize the browser the width and height change, so for this purpose you have to use media query in CSS and in this you have to tell the browser that in this width the navbar should be in given width. and another option is that you can use bootstrap, in bootstrap you not write too much css. and all the work become easy.
I have an inner of fixed width containing the content of variable size. I want the height of that inner-container to be as big as the content, and at least as big as the screen's height (when the content is smaller). The page also has a fixed size footer.
Normally I'd think of setting min-height: 100% to both inner and outer (root) containers, but that doesn't work in CSS.
The code I present below is a simplified example of the situation I have on a bigger page (with much more various elements in the root-container). A green inner-container is not filling the entire screen's height as I'd like it to be. I did manage for it to do so (for example by setting root-container's height instead of min-height, but then the rendering behaved wrongly when the content was bigger than the screen's height (you can quickly simulate that by changing the font-size to a bigger value, like 21px). I want to have it working (the green column filling at least the screen's height, black on it's both sides throught the whole height and the footer on the very bottom) in both cases.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Example</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<style type="text/css">
html,
body {
height: 100%;
margin: 0;
}
#root-container {
min-height: 100%;
background: black;
color: white;
margin-bottom: -200px;
}
#root-container:after {
height: 200px;
content: "";
display: block;
}
#inner-container {
min-height: 100%;
width: 400px;
background: green;
color: white;
font-size: 11px;
margin-left: auto;
margin-right: auto;
}
#footer {
height: 200px;
background: orange;
color: black;
}
h1 {
margin-top: 0;
}
</style>
</head>
<body>
<div id="root-container">
<div id="inner-container">
<h1>Content</h1>
And when the body finally starts to let go<br/>
let it all go at once<br/>
not piece by piece<br/>
but like a whole bucket of stars<br/>
dumped into the universe<br/>
Whoh! Watcb it go!<br/>
Good-bye small hands, good-bye small heart<br/>
good-bye small head<br/>
My soul is climbing tree trunks<br/>
and swinging from every branch<br/><br/>
They're calling on me<br/>
they're calling on me<br/><br/>
Do you think I'm an animal?<br/>
Am I not?<br/>
Do you like fur<br/>
Do you wanna come over<br/>
Are we captive only for a short time<br/>
Is there splendor, I'm not ashamed<br/>
Desire shoots through me<br/>
Like birds singing<br/>
(The way you move no ocean's waves were ever as fluid)<br/><br/>
They're calling on me<br/>
they're calling on me<br/>
I hit the mark!<br/>
I target moon, I target sky, I target sun<br/>
Fall down on the world before it falls on you<br/><br/>
Like beggars, like Stars<br/>
like whores, us all<br/>
Like beggars, like dogs<br/>
Like Stars, us all<br/><br/>
Shoot straight for my heart<br/>
(And when you were near no sky was ever quite so clear)<br/><br/>
Like stars, so small<br/>
Like us, when we fall<br/>
Like beggars, like whores<br/>
Like lovers, Get Up!<br/>
Get up, too far
</div>
</div>
<div id="footer">
<h1>Footer</h1>
</div>
</body>
</html>
And the same example uploaded to JSFiddle: http://jsfiddle.net/gNT8m/
This is a bug: children of parents with min-height can't inherit the height property.
There are many potential workarounds, but you're right that this should work the way you initially tried.
Update:
As to workarounds, the simplest that occurs to me is to set display: flex on your #root-container. I haven't cross-browser tested this solution, so you might want to investigate it further, but using flexbox is a good way to go.
See it working.
You'll want to add a few other niceties, like adding position: relative to your footer and adding some space (padding: <your footer's height>px) to your #inner-container to make sure your footer doesn't cover up any content.
When you scroll with the mouse wheel in Windows 8 the fixed background image bounces around like crazy. This only affects IE 10 and IE 11. This affects elements with position:fixed as well.
Here is an example with a fixed background-image:
http://www.catcubed.com/test/bg-img-fixed.html
Here is example code:
#section{
position: fixed;
top:0;
left:0;
background-color:#eee;
background-position: top left;
background-image: url("images/7.png");
background-size: auto;
background-repeat: no-repeat;
z-index: 10;
}
Is there a solution to keep the background still in IE 10 and 11?
I know it is a bit late for an answer but I've had the same problem and was able to fix it by adding these attributes to my css file
html{
overflow: hidden;
height: 100%;
}
body{
overflow: auto;
height: 100%;
}
From the comments:
This solution stops scroll events from firing on the window, so do be careful if you're using anything that relies on such events firing. codepen.io/anon/pen/VawZEV?editors=1111 ( overflow: hidden, scroll events don't work) codepen.io/anon/pen/PNoYXY?editors=1111 ( overflow: auto, scroll events fire) - Dan Abrey
So this might cause some problems in your projects. But I don't see another way to workaround this bug in IE.
This looks like a z-index bug, try adding z-index: 1.
Looking into this, I've found the best way to debug is to:
Create a simple element at the top of the page, e.g.
<style>#test {position: fixed; background: red; top: 0; left: 0; width: 4em}</style>
<div id="test">Test</div>
In all the above cases, this works correctly, and the scroll is smooth. So this proves it can be done! Now slowly add your properties back in, until you are able to get the element with position fixed to work in the context of your site.
I then found that adding a z-index to the fixed items resolved the issue. (e.g. z-index: 1)
I also discovered that once a position is set on a child element, the bug presents it's self from that point down/onwards.
So you need to ensure none of the child elements have a position set,
or if they do, you explicitly set a position on each child.
E.g.
<!-- Works -->
<div style="position: fixed;">
<div>Nice</div>
<div>Wicked</div>
<div>Cool</div>
</div>
<!-- Element with position: relative, experiences the bug -->
<div style="position: fixed;">
<div style="position: relative;">sad</div>
<div>sad</div>
<div style="position: fixed;">happy</div>
</div>
It's fixable, but will require some tweaking!
Here is a workaround (tested on Windows 8.1):
Move the "background" CSS property to the BODY element. Currently it is on the DIV element with id="filler". Here is the resulting CSS:
body {
font-family: Helvetica, Arial, sans-serif;
background: #fff url(blue-kitty.jpg) no-repeat fixed center 100px;
}
#filler {
text-align: center;
}
.big-margin {
margin-top: 500px;
}
try to turn off smooth scrolling option.
Internet Options - Advenced Tab - Use Smooth Scrolling
it's like rendering bug.... MS IE team is investigating....
just simply define body container to relative.
<style>
body
{
position: relative;
}
</style>
The fix in my case was to simply remove the z-index property from the element that has position:fixed, IE then stopped the strange flickering.
(disabling smooth scrolling on IE options worked while having he z-index property but that's not a solution since users would most likely have it on by default).
I have read a vast amount of posts on the subject of css heights filling the viewport and have failed to find a working answer. So I'm reluctantly starting yet another thread about this in the hope of finding the missing part of the jigsaw I have probably been staring at without seeing it.
My DOCTYPE is xhtml transitional and I'm currently testing on IE6, FF6 and Safari 5 with the same problem.
I have a container div that also displays an image driven border within a table and I want this to fill the browser window, no bigger, no smaller but adaptable to each browser (minimum heights will be set to ensure all content is contained to account for older resolutions).
I have set the html and body styles as follows:-
html {
height:auto !important;
height: 100%;
min-height: 100%;
border: solid;
border-color: black;
overflow: hidden;
}
body {
height: 100%;
height:auto !important;
min-height: 100%;
border: solid;
border-color: black;
}
As you can see I have added a border to each of the elements so that I can actually see the size of each when I view the page. The html element fills the window fine, but the body element doesn't. It just shows a short box along the top of the window.
Can anyone offer a suggestion as to what may be causing the problem?
This is all you need for the css:
html,body {
padding: 0;
margin: 0;
height: 100%;
}
Live example: http://jsfiddle.net/tw16/gyAKJ/