The output of this code looks pretty much identical in FF, Chrome and Safari on Windows. In IE7 it looks weird.
For all other browsers the frame div exactly wraps the canvas div even though there is a 24X24 div in the frame but outside the canvas. IE7 leaves extra space in the frame, above the canvas, for the "blue-box" div. Once floated I thought the space it would otherwise occupy would collapse. That's the behavior I see in the other browsers.
Is there some trick to getting IE7 to collapse the space like the other guys?
Edit: Just to give an idea to what this example is supposed to represent. It's supposed to represented an embedded widget. The "canvas" is where the content belongs. The "frame" is what the hosting site uses to control the appearance and the behavior between the widget and the rest of the page. The red-box and blue-box divs represent controls in the widget. The red-box is a control put there my the widget code. The blue-box represents a control added by the frame (perhaps a handle to allow the widget to be dragged around the page)
Here's the complete sample
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>CSS Positioning</title>
<style type="text/css">
#frame {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#canvas {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#blue-box{
position: relative; /* so I can position this element */
float: right; /* I want this element all the way to the right */
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
#red-box{
position: relative; /* so I can position this element */
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
</style>
</head>
<body>
<div id="frame">
<div id="blue-box">blue</div>
<div id="canvas">
<div id="red-box">red</div>
</div>
</div>
</body>
</html>
Extra example for Emily ====================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>CSS Positioning</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#one {
background-color: red;
float: right;
}
#two {
background-color: blue;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="one">one</div>
<div id="two">two</div>
</body>
</html>
There could be a problem with the sizing on the "frame" and "canvas" divs. It looks like they are both the same size plus the size of border (which gets added to the total size of the element). Try not specifying a size for your "canvas" div, but give it a margin to space it properly with the "blue-box" div.
When in doubt, reset your elements by setting your margin/padding to 0 one questionable elements. Default spacing can occur between browsers if they are not defined.
Also, I don't believe "position:relative" is needed here.
Acorn
I've run into that problem before and I'm struggling to remember what happened with it. I thiiiink you need to take position: relative off of the #blue-box.
#frame contains #canvas which has a width of 400px and #blue-box which has a width of 24px.
#frame must have a width of at least 424px (might need more...depends on what padding is on your elements) but #frame only has width of 400px.
Try changing the width of #frame to 430px to get both boxes on the same line. Depending on what padding the css reset removed, you may be able to make the width of #frame smaller.
Then you need to put #blue-box inside of #canvas
<div id="frame">
<div id="canvas">
<div id="blue-box">blue</div>
<div id="red-box">red</div>
</div>
</div>
Floated divs do not overlap or 'reach down into divs below them'. Here's a good article on CSS Floats
This is one time I will recommend using absolute positioning. position: absolute removes the element from the flow of the document -- just like you want with #blue-box.
#frame {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#canvas {
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#blue-box{
position: absolute; /* so I can position this element */
right: 0; /* I want this element all the way to the right */
top:0;
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
#red-box{
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
<div id="frame">
<div id="blue-box">blue</div>
<div id="canvas">
<div id="red-box">red</div>
</div>
</div>
have you tried removing the spaces in the code. ie7 can be funny about white space.
<div id="frame"><div id="blue-box">blue</div><div id="canvas"><div id="red-box">red</div></div></div>
Josh
IE adds some extra padding and margin. You should use a reset.css file and try again.
In general, IE doesn't behave as a browser should, so you might need to create IE specific stylesheets.
<!--[if IE]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie.css" /><![endif]-->
<!--[if IE 6]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie6.css" /><![endif]-->
<!--[if IE 7]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie7.css" /><![endif]-->
EDIT:
The wrapping canvas is the one messing things up because it's the same size as the frame. If you do :
#frame {
position: relative; /* so subelements can be positioned */
width: 460px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
It fixes the issue. You will just have to tweak the width to get the size you wanted.
EDIT2: I saw one of your comments saying that you want IE to behave like other browsers... this is not going to happen, this browser is just terrible. You might want to fully refactor your code to avoid the unnecessary wrappers that lead to issues in IE
Related
Here is my HTML code.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="width=device-width">
<style>
body {
margin: 0;
}
.a {
background: orange;
border: 2px solid black;
}
.b {
padding: 0 2em;
width: 100%;
background: lightblue;
border: 2px solid black;
}
</style>
</head>
<body>
<div class="a">Foo</div>
<div class="b">Bar</div>
</body>
</html>
Here is the output I see when I view the page with an Android mobile device with Chrome browser.
The issue here is that the orange div does not cover the whole width of the page.
My question is not how to fix it. I know how to fix it. If I remove width: 100% from .b, it fixes this issue.
My question is about why this issue occurs only with Chrome on a mobile device but not on any other browser or not on Chrome on Desktop?
The related question at Why does my navigation div not extend to the full width of the screen on mobile devices? does not answer my question because none of the answer there discusses the CSS or user agent rules that causes this issue. More importantly I am trying to understand why this issue occurs only on Chrome on a mobile device.
Your issue does indeed occur on Chrome on desktop, and is not restricted to just mobiles.
As for the cause of your problem, it's to do with the box model:
By default in the CSS box model, the width and height you assign to an element is applied only to the element's content box. If the element has any border or padding, this is then added to the width and height to arrive at the size of the box that's rendered on the screen. This means that when you set width and height you have to adjust the value you give to allow for any border or padding that may be added.
In order to ensure that your .b element is constrained within the width of the container is to apply box-sizing: border-box it, as is seen in the following:
body {
margin: 0;
}
.a {
background: orange;
border: 2px solid black;
}
.b {
padding: 0 2em;
width: 100%;
background: lightblue;
border: 2px solid black;
box-sizing: border-box;
}
<body>
<div class="a">Foo</div>
<div class="b">Bar</div>
</body>
box-sizing: border-box tells the browser to account for any border and padding in the values you specify for width and height. If you set an element's width to 100 pixels, that 100 pixels will include any border or padding you added, and the content box will shrink to absorb that extra width. This typically makes it much easier to size elements.
I am building a website to host an online gameserver list for the game Crysis Wars, and have just found out that it's by far easier just to develop the design in Adobe Fireworks, and add the relevant code after.
The current web page that I am designing has a signin box at the center of the page, and it works beautifully.
That is, until we change the size of the browser window.
This is the web page as it normally looks:
It is displayed correctly, but here's the screenshot of when the browser window was resized:
As can be seen, this is an issue with the page, since visitors will have different screen resolutions, and this problem could easily re-occur.
My question is, how can I force these two CSS objects to maintain their position, and never overlap?
This is troublesome since the signin box centers itself on the web page.
The web page can be viewed at crysis-or.eu (please don't berate me for developing on a live website).
HTML Code:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<html>
<head>
<title>Server Portal | Login</title>
<link href="./css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="navbar">
</div>
<div class="loginui">
</div>
</body>
</html>
CSS:
body {
width:100%;
margin-left:-0px;
background-color:07080A;
}
body > .loginui {
width:400px;
height:400px;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
background:url("http://crysis-or.eu/img/login_b_bg.png") repeat-x;
}
body > .navbar {
width:500px;
height:100px;
position: absolute;
margin-top:50px;
margin-left:100px;
background:url("http://crysis-or.eu/img/navbar.png") repeat-x;
}
I would recommend the following:
Put the nav bar and the login window in separate wrapper-divs that prevent them from overlapping. You can change your HTML to:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<html>
<head>
<title>Server Portal | Login</title>
<link href="./css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header id="top-bar">
<div class="navbar">
</div>
</header>
<section id="main">
<div class="loginui">
</div>
</section>
</body>
</html>
Header and Section act just like Div, the only difference is their semantic significance.
Because the .top-bar and .loginui are no longer direct children of the body, your selectors won't work anymore. Change the CSS selectors to just .top-bar and .loginui instead of body > .top-bar and body > .loginui.
The header needs a specified height, and needs its position to be either 'relative' or 'absolute'. An absolutely positioned child element will be positioned absolutely to whatever the closest parent is that is also absolute, or explicitly relative. The background color is for illustration purposes only, and would be removed for production.
header {
position: relative;
height: 200px;
background-color: red;
}
You want the section to fill as much as it can, so it will need absolute positioning. The trick here, the thing that will fix your problem, is adding a min-height attribute to prevent the section from becoming smaller than its contents, thus allowing overlap.
section {
position: absolute;
top: 200px;
left: 0;
right: 0;
bottom: 0;
min-height: 400px;
background-color: blue;
}
That should work for you. The one problem with this solution is that the login window will be centered with respect to its container, rather than the whole window. It will be 100 pixels lower (one half of the header height) than it is with your current design. In order to fix that, if that's important to you, you would need to use a different method of vertically centering it. Put the top as 50%, then use a negative top margin to compensate for half the height plus half of the height of the header, too. Because it has a fixed height, that's easy: (400px + 200px) / 2 = 300px.
.loginui {
width: 400px;
height: 400px;
position: absolute;
top: 50%;
left: 0;
right; 0;
margin: -300px auto 0;
background: url('path/to/login_b_bg.png');
}
If you add this, it will create a scrollbar when trying to resize the browser instead of laying the elements on top of eachother
body
{
width:100%;
min-width: 950px; //ADD THIS. It sets the minimum browser width before creating a scroll bar.
min-height: 550px; // This does the same thing for a vertical scroll bar.
margin-left:-0px;
background-color:07080A;
overflow-y: scroll; // vertical scroll bar
overflow-x: scroll; //horizontal scroll bar
}
EDIT: ---------------------------------
After looking at your site and playing around a bit, your min-width is not an important factor, just the min height, if you set the values like this, the menus will never overlap.
body
{
width:100%;
height: 100%;
min-height: 750px; // Stops the menus from touching eachother vertically, but they can still line up in the x-direction.
margin-left:-0px;
background-color:07080A;
overflow-y: scroll; // vertical scroll bar
}
I am using a layout similar to the one from Dynamic Drive here:
http://www.dynamicdrive.com/style/layouts/item/css-right-frame-layout/
The main content area (white) has overflow set to auto. I have given the innerTube inside this main content area a border. However if the contents within this innerTube are greater than the width of the main content area, a horizontal scroll bar will appear as expected, but in Firefox these contents will 'overlap' the border and go off screen (can be retrieved by scrolling horizontally). In other words, the right hand border remains in place, and the content just goes over the op of it, and disappears behind the right hand column.
In IE it behaves exactly as I want - the content pushes the border off screen to be visible only once you scroll over there.
I guess the easiest thing is to paste the source code here. If you copy it into a blank file you'll see what I mean. I've just used one really long word to replicate what happens if a wide image is there instead.
Thanks in advance to anyone who can help me out.
<!--Force IE6 into quirks mode with this comment tag-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body{
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
height: 100%;
max-height: 100%;
}
#framecontent{
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 200px; /*Width of frame div*/
height: 100%;
overflow: hidden; /*Disable scrollbars. Set to "scroll" to enable*/
background: #cccccc;
color: white;
}
#maincontent{
position: fixed;
top: 0;
left: 0;
right: 200px; /*Set right value to WidthOfFrameDiv*/
bottom: 0;
overflow: auto;
background: #fff;
}
.innertube{
margin: 15px; /*Margins for inner DIV inside each DIV (to provide padding)*/
}
.innertubeWithBorder {
margin: 15px;
border: solid 1px #666666;
}
* html body{ /*IE6 hack*/
padding: 0 200px 0 0; /*Set value to (0 WidthOfFrameDiv 0 0)*/
}
* html #maincontent{ /*IE6 hack*/
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="framecontent">
<div class="innertube">
<h1>CSS Right Frame Layout</h1>
<h3>Sample text here</h3>
</div>
</div>
<div id="maincontent">
<div class="innertubeWithBorder">
<h1>Dynamic Drive CSS Library</h1>
<p>AReallyLongWordWhichIsSimilarToHavingAnImageWithWidthGreaterThanTheWidthOfThisDivToShowOverFlowProblemWithBorderSoIfYouResizeThisWindowNarrowerYouWillSeeWhatIMeanWorksFineInIEButNotFirefox</p>
<p>So I want that border over there ------> to dissappear behind the right hand column like it does in IE, and be visible once you use the scrollbar below and scroll to the right</p>
<p style="text-align: center">Credits: Dynamic Drive CSS Library</p>
</div>
</div>
</body>
</html>
There are two things you can try.
<wbr> - This tag doesn't make a break in the text, but it will tell the browser that if the text needs to be broken, it should be broken here. You can use Javascript's substr function (http://www.quirksmode.org/js/strings.html#substr) to split the text apart, add the <wbr> tag in, and combine the text back together again.
width: auto This option is less preferable because it may break your layout and leave it looking less that perfect. However, if this is set on your div, it will make sure that the div is always large enough to contain its inner contents.
Hope this helps!
Figured it out. Set the innerTubeWithBorder to be fixed as well, and used the same IE CSS hack to make it 100% height & width, then set IT'S overflow to auto. To get the padding I used padding:5px in mainContent for IE, and set the top, bottom, right & left in by 5px for FF.
Thanks to anyone who put any thought into it.
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.
I've noticed that the <input> element in HTML ignores the CSS pair of "left" and "right" properties. Same for the pair "top" and "bottom". See the sample code below:
<html>
<head>
<style><!--
#someid {
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
}
--></style>
</head>
<body>
<input type="text" id="someid" value="something"/>
</body>
</html>
The <input> should take up almost all space in the browser (except a border of 10px around it). It works fine in Safari, but in FireFox and IE the <input> stays small in the top-left corner of the browser.
If I use "left" and "width", and "top" and "height", then everything works fine. However I don't know what is the width and the height, I want them adjusted depending of the size of the browser window.
Any ideas how to work around this?
Thanks.
You can Use a Wrapper DIV
<html>
<head>
<style><!--
#wrapper {
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
}
#someid {
/* position:relative; EDIT: see comments*/
height:100%;
width:100%
}
--></style>
</head>
<body>
<div id="wrapper">
<input type="text" id="someid" value="something"/>
</div>
</body>
</html>
It's not ignoring left or top, you'll see it does position 10px out. What's happening is that the right and the bottom are not being respected. Form elements are treated a little bit specially in layout engines, it's entirely possible FF/IE consider the width/maxlength of the input more important, I haven't really looked into why that might be.
It's a bit of a strange thing to do though. Perhaps what you'd be better off doing is looking at <textarea> which is designed to provide a large text input, which you can push to 100% dimensions by applying width: 100%; height: 100%; and take care of the 10px margin on a container div.
WFM:
<html>
<head>
<style>
body
{
margin: 0px;
}
div
{
position: absolute; margin: 2%; width: 96%; height: 96%;
}
textarea
{
position: absolute; width: 100%; height: 100%;
}
</style>
</head>
<body>
<div>
<textarea></textarea>
</div>
</body>
http://reference.sitepoint.com/css/bottom
say, regarding internet explorer (<= 6)
don’t support the specification of both the position and the dimensions of an absolutely positioned element using top, right, bottom, and left together; they’ll use the last vertical and horizontal position specified, and need the dimensions to be specified using width and height
The way it looks in Safari is not how it should display. Because you didn't specify a height value, the input will default to the size of the last inherited font size.
The right and bottom positioning will also be ignored because you're trying to set the top and left margins at the same time. Looks like they take precedence in this case.
If you need to use the input field and have it display inside the entire width and height of the browser window at the time it is seen, you need to redo the CSS like this:
body{
margin:10px;
}
#someid{
display:block;
margin:0 auto;
width:100%;
height:100%;
}
This will stretch the input field to as high and wide as the user has their browser window. It will also have a margin around each side of 10 pixels from the browser window.
If you have to have a margin, then set that in the body style or a wrapper DIV around the input field.