iFrame 100% height causes vertical scrollbar - html

I see alot of questions about 100% height iFrames but noone seems to have the exact same problem as I do.
What I want to do is to have an iFrame that covers the entire viewport, with no scrollbars, without setting overflow: hidden on the body.
I get a 5px bottom margin to my iFrame that won't go away with css, and it causes a vertical scroolbar. The standard advice seems to be to set overflow: hidden on the body, but that's not really solving the problem, and it's not enough for me.
Here's a super simple jsFiddle example. (notice the double vertical scrollbars)
This behaviour is the same in Chrome 15, IE9 and FF9 for me.

It's not the iframe that produces the scrollbar, it's the whitespace after it
<iframe src="http://www.bbc.co.uk" frameborder="0"></iframe>
<!-- Whitespace here; This is being rendered! -->
</body>
If you don't want to see it, use
* { line-height: 0; }
edit: Turns out the problem persists if you remove the whitespace, but the solution is the same. Iframes are rendered as inline elements by default (iframe = 'inline frame'), and thus have a line-height which causes the issue.
Alternatively, you may want to try iframe { display: block; } or a combination of both solutions.

Update:
working example in chrome 16.0.*, firefox 10.* (apparently ie9 acts up and displays a scrollbar either way -- either a disabled one if the height is set to 99% or a active one that can't scroll if height is 100%):
place the following in a html file and open it (don't know what jsfiddle is doing different, but it doesn't work the same way)
<style>
* {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
/*overflow: auto;*/ /* not needed, this is the default value*/
}
</style>
<iframe src="http://www.bbc.co.uk" frameborder="0"/>

To summarize it:
white space before causes 4px white space at the rigth of the iframe.
white space after csuses 4px white space after the iframe.
This is due to the inline character of iframe as pointed out in the first post.

Not seeing a vertical scroll-bar outside of jsFiddle with this:
<html>
<head>
<style>
body {
padding: 0;
margin: 0;
}
iframe {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: auto;
}
</style>
</head>
<body>
<iframe src="http://www.bbc.co.uk" frameborder="0"/>
</body>
</html>
EDIT: Here's a snippet from under the Elements tabs of what gets selected when I inspect the white-space in Chrome.

To prevent the scroll bar try this:
CSS:
html, body { height:100%; margin:0;}
.bdr { border: thick solid grey }
.h100 { height:100%;}
.w100 { Width: 100% }
.bbox { box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.vat { font-size: 0; vertical-align:top}
HTML:
<body class="bbox"><!-- no WS here--><iframe
class="bdr h100 w100 vat bbox" name="iframe1"
src="http://www.bbc.co.uk"> </iframe><!--no WS here either--></body>
The .bbox style prevents sub divs from growing. .Vat is necessary for IE and Firefox.
An alternative for .vat is: display:block. Or
display:inline-block + vertical-alignment:top
.brd is for demonstration purposes.

Related

Unwanted scrollbars when placing two divs below each other

I have two fullscreen divs which are placed relatively below each other. But when I'm visiting the page, the browser always shows me unwanted scrollbars and a width greater than 100vw. When there is only one div, the whole thing works like a charm. Would appreciate any help here :)
<html>
<head>
<link rel="stylesheet" type="text/css" href="normalize.css">
<style>
.section {
position: relative;
width: 100vw;
height: 100vh;
background-color: red;
}
.section.second {
background-color: green;
}
</style>
</head>
<body>
<div class="section">ASD1</div>
<div class="section second">ASD2</div>
</body>
</html>
This is a known issue.
According to https://caniuse.com/#feat=viewport-units,
"Currently all browsers but Firefox incorrectly consider 100vw to be the entire page width, including vertical scroll bar, which can cause a horizontal scroll bar when overflow: auto is set."
You can add following CSS style to fix it,
html, body {margin: 0; padding: 0; overflow-x:hidden;}
Example (JSBin)
Thats because BODY element has its own margins by default. You need to make it zero. You can check it here (jsfiddle example).
body { margin: 0; }
First of all, to remove unwanted margins and paddings, you should always perform a CSS reset (resets all browser specific properties to zero) or a CSS normalization (sets all properties to the same default value for every browser, but not zero). For debugging purposes it is enough to write the following:
* {
margin: 0;
padding: 0;
}
In a real project you should definitely use a better solution like Eric Meyer’s reset or Normalize.css.
Okay, now we managed to solve the spacing issue, but this still leaves us with the scrollbar issue. For a solution look at this post. It says
(...)the horizontal scroll is present because of the vertical scroll.
which you can solve by giving max-width: 100%.
Hence, this is the final solution:
* {
margin: 0;
padding: 0;
}
.section {
position: relative;
width: 100vw;
height: 100vh;
max-width: 100%;
background-color: red;
}
.section.second {
background-color: green;
}
<div class="section">ASD1</div>
<div class="section second">ASD2</div>

css width 0 and overflow hidden issue in safari

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 :/

Body height 100% displaying vertical scrollbar

Out of curiosity, considering the example below, why does having the margin on the #container div cause a vertical scrollbar to appear in the browser? The container is much smaller in height than the body height which is set to 100%.
I have set the padding and margins to 0 for all elements except the #container. Note that I have deliberately omitted absolute positioning on the #container div. In this case how is the browser calculating the height of the body and how is the margin affecting it?
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* { padding:0; margin:0;}
html, body { height:100%; }
#container
{
padding:10px;
margin:50px;
border:1px solid black;
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<div id='container'>
</div>
</body>
</html>
Example also on JSFiddle
If you paint the backgrounds of html and body (giving each its own color), you'll quickly notice that body is being shifted down along with #container, and #container itself isn't offset from the top of body at all. This is a side effect of margin collapse, which I cover in detail here (although that answer describes a slightly different setup).
It's this behavior that's causing the scrollbar to appear, since you've declared body to have 100% the height of html. Note that the actual height of body is unaffected, as margins are never included in height calculations.
Based upon #BoltClock♦'s answer, I fixed it by zeroing the margin...
so
html,body, #st-full-pg {
height: 100%;
margin: 0;
}
works where id "st-full-pg" is assigned to a panel div (which further contained panel-heading and panel-body)
A bit late, but maybe it helps someone.
Adding float: left; to #container removes the scrollbar, as W3C says:
•Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
html,body {
height: 100%;
margin: 0;
overflow: hidden;
}
This worked for me
adding float:left; is nice, but will interfere with central horizontal positioning using margin:auto;
if you know how big your margin is, you can account for that in your height percentage using calc:
height: calc(100% - 50px);
browser support is good, but only IE11+
https://caniuse.com/#feat=calc
/*removes default margin & padding*/
html, body{
padding: 0px !important;
margin: 0px !important;
}
/*sets body height to max; and allows scrollbar as page content grows*/
body{
min-height: 100vh;
}
I have found a solution: add padding: 1px 0; to body prevents vertical scrollbars to appear
For those who are coming here for an easier to understand answer that even includes code samples, this answer (copied from here) is for you.
No JavaScript or definite pixel values (such as 100px) are required, just, pure CSS and percentages.
If your div is just sitting there on its own, height: 50% will mean 50% the height of the body. Normally, the height of the body is zero without any visible content, so 50% of that is just, well, zero.
This is the solution (based on this) (uncomment the background lines to get a visualisation of the padding):
/* Makes <html> take up the full page without requiring content to stretch it to that height. */
html
{
height: 100%;
/* background: green; */
}
body
{
/*
100% the height of <html> minus 1 multiple of the total extra height from the padding of <html>.
This prevents an unnecessary vertical scrollbar from appearing.
*/
height: calc(100% - 1em);
/* background: blue; */
}
/* In most cases it's better to use stylesheets instead of inline-CSS. */
div
{
width: 50%;
height: 50%;
background: red;
}
<div></div>
The above was written so that there would still be the usual padding. You could set the dimensions of the red div to 100% and still see padding on each side/end. If you don't want this padding, use this (although it doesn't look nice, I recommend you stick with the first example):
/* Makes <html> take up the full page without requiring content to stretch it to that height. */
html, body
{
height: 100%;
}
/* You can uncomment it but you wouldn't be able to see it anyway. */
/*
html
{
background: green;
}
*/
body
{
margin: 0;
/* background: blue; */
}
/* In most cases it's better to use stylesheets instead of inline-CSS */
div
{
width: 50%;
height: 50%;
background: red;
}
<div></div>
I saw this problem fixed before where you put all the contents of body in a div called wrap. Wrap's style should be set to position: relative; min-height: 100%;. To position #container div 50px from the top and left put a div inside wrap with a padding set to 50px. Margins will not work with wrap and the div we just made, but they will work in #container and everything inside it.
here's my fix on jsfiddle.
you can add non-breaking space into the body tag.
<body> <othertags>...</body>
html, body {
height: 100%;
overflow: hidden;
}
If you want to remove the body scrolling add the following style:
body {
height: 100%;
overflow: hidden;
}
Inspired by #BoltClock, I tried this and it worked, even when zoom out and in.
Browser: Chrome 51
html{
height: 100%;
}
body{
height: 100%;
margin: 0px;
position: relative;
top: -20px;
}
I guess body was shifted down 20px.
It works for me:
html,
body {
height: 100%;
height: -webkit-fill-available; // Chrome
}
// Firefox
#-moz-document url-prefix() {
body {
box-sizing: border-box;
margin: 0;
padding: 1px;
}
}
Add overflow: hidden; to html and body.
html, body {
height: 100%;
overflow: hidden;
}
I found a quick solution: try set height to 99.99% instead of 100%

DIV with "position:absolute;bottom:0" doesn't stick to the bottom of the container in Firefox

I have this HTML source:
<!DOCTYPE html>
<html>
<head>
<title>Stylish Web Page</title>
<style type="text/css">
body { padding: 0; margin: 0; }
div.table { display: table;}
div.tableRow { display: table-row;}
div.tableCell { display: table-cell;}
div.contentWrapper { width: 100%; height: 760px; position: relative;
margin: 0 auto; padding: 0; }
div.footerBar { width: inherit; height: 60px; background-image: url("BarBG.png");
background-repeat: repeat-x; position: absolute; bottom: 0; }
</style>
</head>
<body>
<div class="table contentWrapper">
<div class="tableRow"> </div>
<div class="footerBar"> </div>
</div>
</body>
</html>
The footer is supposed to appear at the bottom of the page, and it does so in Opera and Chrome; However, in Firefox, there's a lot of empty room following the footer. What am I doing wrong? How to fix it?
Here's a screenshot: The blue highlight is the footer.
(Please note: "position: fixed" is not what I want; I want the footer to show up at the bottom of the page, not the browser window.)
The issue in Firefox is caused by display:table. Essentially you are telling Firefox to treat this element as a table.
In Firefox position:relative is not supported on table elements. It isn't a bug though, as in the spec the treatment of position:relative table elements is undefined.
This means that in your example the footer is being positioned relative to the window and not the container.
One solution is to use display:block instead or just remove the display rule entirely. You will see the footer will drop down to its rightful place.
A second solution would be to wrap another non-table div around the container and set position:relative to that instead.
A third option is to add position:relative to the body. Live example: http://jsfiddle.net/tw16/NbVTH/
body {
padding: 0;
margin: 0;
position: relative; /* add this */
}
What version of FF do you have? In FF 6 it displays correctly: http://screencast.com/t/zAjuG8FP99nX
Have you cleared the cache? Maybe there's something left from previous versions of the page.
Did you close the Firebug window? That pushes the content up when open.
Later edit: the last line means: "after you close firebug, scrollbars disappear and div is at the bottom"

Border around 100% body height and width (HTML 4.01 Strict)

Okay, this is driving me crazy right now.
I want to have a border around my document. It should be nicely going around the whole window/viewport. So I define:
body {
border: 1px solid red;
}
When my document is in quirks mode, this works fine. At least in IE, which is my primary target here. A red border shows up at the very edges of my page, obviously because by predefined CSS body and html are set to fill the screen.
When going to standards mode by setting a HTML 4.01 strict DOCTYPE, body and html collapse to the real (smaller) size of the content, the border is drawn right through the middle of the screen. So I define:
body, html {
padding: 0px;
margin: 0px;
border: 0px none;
width: 100%;
height: 100%;
}
body {
border: 1px solid red;
}
And I get — scroll bars, scrolling exactly one pixel to show the bottom/right borders. However, I want that border visible right away.
Is there a no-bullshit (like "height: 99.9%;", "overflow: hidden;" or "switch back to quirks mode") method to get a border at 100%, without unnecessary scroll bars? IE-only is fine, cross-browser would be better, of course.
As SpliFF already mentioned, the problem is because the default (W3C) box model is 'content-box', which results in borders being outside of the width and height. But you want those to be within the 100% width and height you specified. One workaround is to select the border-box box model, but you can't do that in IE 6 and 7 without reverting to quirks mode.
Another solution works in IE 7, too. Just set html and body to 100% height and overflow to hidden to get rid of the window's scrollbars. Then you need to insert an absolutely positioned wrapper div that gets the red border and all content, setting all four box offset properties to 0 (so the border sticks to the edges of the viewport) and overflow to auto (to put the scrollbars inside the wrapper div).
There's only one drawback: IE 6 doesn't support setting both left and right and both top and bottom. The only workaround for this is to use CSS expressions (within a conditional comment) to explicitly set the width and height of the wrapper to the viewport's sizes, minus the width of the border.
To make it easier to see the effect, in the following example I enlarged the border width to 5 pixels:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Border around content</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
overflow: hidden;
}
#wrapper {
position: absolute;
overflow: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
border: 5px solid red;
}
</style>
<!--[if IE 6]>
<style type="text/css">
#wrapper {
width: expression((m=document.documentElement.clientWidth-10)+'px');
height: expression((m=document.documentElement.clientHeight-10)+'px');
}
</style>
<![endif]-->
</head>
<body>
<div id="wrapper">
<!-- just a large div to get scrollbars -->
<div style="width: 9999px; height: 9999px; background: #ddd"></div>
</div>
</body>
</html>
P.S.: I just saw you don't like overflow: hidden, hmmm...
Update: I managed to get around using overflow: hidden by faking a border using four divs that stick to the edges of the viewport (you can't just overlay the whole viewport with a full-sized div, as all elements below it wouldn't be accessible any more). It's not a nice solution, but at least the normal scrollbars remain in their original position. I couldn't manage to let IE 6 simulate the fixed positioning using CSS expressions (got problems with the right and bottom divs), but it looked horribly anyway as those expressions are very expensive and rendering got tediously slow.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Border around content</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#border-t, #border-b, #border-l, #border-r {
position: fixed;
background: red;
z-index: 9999;
}
#border-t {
left: 0;
right: 0;
top: 0;
height: 5px;
}
#border-b {
left: 0;
right: 0;
bottom: 0;
height: 5px;
}
#border-l {
left: 0;
top: 0;
bottom: 0;
width: 5px;
}
#border-r {
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
</style>
</head>
<body>
<!-- just a large div to get scrollbars -->
<div style="width: 9999px; height: 9999px; background: #ddd"></div>
<div id="border-t"></div><div id="border-b"></div>
<div id="border-l"></div><div id="border-r"></div>
</body>
</html>
You'll love this one.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style>
html {
height: 100%;
width: 100%;
display: table;
}
body {
display: table-row;
}
#wrapper {
display: table-cell;
border: 5px solid red;
}
</style>
</head>
<body>
<div id="wrapper"></div>
</body>
</html>
http://www.test.dev.arc.net.au/100-percent-border.html
I figured since tables keep a lot of "quirky" behavior even under standards mode they might be the solution. Turning the HTML element into a table is pretty funny though.
Before marking this down for not working in IE6 consider that's a very trivial issue to fix. The point is that using the table drawing algorithm is the solution, and a pure CSS solution is also possible:
<table class="outer"><tr><td class="inner"> ...page content...
Until CSS3 gives us inside borders and box-model switching you need two divs. The first to give the 100% height and the second to provide the border. Otherwise the border goes on the outside of the 100% height (ie, 1px+100%+1px)
BTW. You should collect some stats before going "IE only". IE does not have the marketshare it once did. Anywhere between 10 - 30% of your users may be on other browsers.
Here's a simple solution using only the html and body elements (no need for nested divs). It takes advantage of the special behaviour of the HTML element (it can't have an outer border so it must shrink to display it).
<html>
<head>
<style>
html {padding:0; margin:0; border:5px solid red;}
body {height:100%; padding:0; margin:0; border:0;}
</style>
</head>
<body>
</body>
</html>
It also a bit ugly, but giving the body
position:relative;
top:-1px;
left:-1px;
worked for me.
Try setting borders for the html element. The body element is only as high as it needs to but, as far as I remember, the html element takes the whole space (it's where you should set your background, too).
I'm not sure how borders look, I usually only set backgrounds.
border is out of 100% size. Try padding: -1px or margin: -1px.