Stop two objects overlapping - html

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
}

Related

Absolute Positioning without overflowing into another div

I am trying to create a full screen slider with a footer on the bottom. Making the slider full screen is easy, but adding a "footer" to it doesn't seem to be (for me). For instance the slider will have a photo and the div below it will have details about the photo, which all should be shown as the "landing page" without scrolling at all, on all devices.
My brain is telling me to create a wrapper container that is 100vh to fill 100% of the views height, and then create the footer - for this example - at a set height of 150px and then have the slider fill the remaining difference left over in the wrapper container, which in theory seems to be right, but I just can't seem to figure out how to actually do it without using scripting. I'm ok with scripts, just wondering if there is a pure css way of doing what I am trying to accomplish.
In this specific example I've tried absolute positioning on the footer div with bottom 0 to hug to the bottom of the main wrapper, which works, sort of (wonky on mobile especially iPhone due to the bottom navigational bar), but naturally due to the way position absolute seems to work, setting 100% height on the slider div will ignore the footer div and set its height to 100% of the wrapper container.
Is it possible to set bottom: 0, yet have the slider div to not overlap the absolute positioned footer div?
Is there a better way to do this all together using pure css? Have I lost my mind?
Here is a diagram of what I am trying to accomplish
Original Code before suggestions
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>test page</title>
<meta name="description" content="test page">
<meta name="author" content="Test">
<style>
body {
margin: 0px;
}
.page-wrapper {
height: 100vh;
background-color: red;
}
.slider {
height: 100%;
background-color: blue;
}
.slider-footer {
height: 150px;
background-color: green;
position: absolute;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div class="page-wrapper">
<div class="slider">
</div>
<div class="slider-footer">
</div>
</div>
</body>
</html>
UPDATE / EDIT
Additionally, as suggested below, calc(100vh -150px) on the .slider works better. It works perfectly well on the desktop, but when pulled up on my iPhone, not so much.
Updated Style Code
<style>
body {
margin: 0px;
}
.page-wrapper {
height: 100vh;
max-height: 100vh;
background-color: red;
}
.slider {
background-color: blue;
height: calc(100vh - 150px);
max-height: calc(100vh - 150px);
}
.slider-footer {
height: 150px;
background-color: green;
position: absolute;
bottom: 0;
width: 100%;
}
</style>
The iPhone seems to be automatically adjusting the view because of the lower navigation buttons of safari on the device. It looks like it stretches the .page-wrapper down further than it should. I tried to prevent this by adding a max-height: 100vh to the .page-wrapper, but that didn't seem to do anything at all
Here is what the page looks like on the iPhone
Things look perfectly fine, just the way they should...
Until you scroll down
Thats when things get a little weird...
It seems like, on safari on iPhone at least, 100vh is taking into account the bottom navigation bar, yet the absolute positioning of the slider.footer is ignoring it and setting it self to the top of safari's bottom navigation bar. I get why apple would do that, because the navigation bar is always there by default until you scroll down, but it is clearly causing an issue with what I am trying to accomplish...
Am I correct to think this is an iPhone / Safari problem, or are my html/css skills just that far off?
I'd do something like:
.slider {
height: calc(100vh - 150px);
}
Hope this helps :)
You could try this:
body {
margin: 0px;
margin-bottom: 150px;
}
Another approach would be:
.page-wrapper { position: relative }
.slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 150px;
}
Hope this (finally) helps :)

Full width within 980 container

I am trying to alter a websites header, footer and its carousel area on the homepage. But because the site was designed to start the 980 container in the header, go throughout the entire site and end in the footer, it therefore constrains all elements throughout the entire site. But I need the header, menu, homepage carousel and footer, to be 100% width.
I know to try break out of the container, but because this site is so large, breaking the container and putting it back in wrapping around just the content on every element (of which are included all over the templates) will take so long because of how many pages the container right now is effecting just isn't great for me right now, is there any other way to do this?
Here's a live preview of the site: http://bit.ly/1kpGc2G
Might not be best practice but just something to get me by for now.
It's opencart encase it helps.
Are you asking for the entire site to fill the screen width?
It seems like you just need to give the 980 container a width of 100%. Then style all the other elements to suit, giving them padding left and right to bring them back into line.
Edit Example
You said you didn't mind if it was messy I have this...
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Width Test</title>
<style>
.wrapper {
width:100%;
overflow: hidden;
}
p {
color: #ccc;
text-align: left;
}
.header, .article, .footer {
display: inline-block;
text-align: center;
background-color: #444;
width: 100%;
max-width: 600px;
padding: 0 30%;
margin: 0;
}
.article {
background-color: #666;
}
.footer {
background-color: #999;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="header"><p>Header</p></div>
<div class="article"><p>Article</p></div>
<div class="footer"><p>Footer</p></div>
</div>
</body>
</html>
Basically I have made this so the padding overflows the wrapper, then used text-align:center to centre the content divs. It isn't perfect but I think this achieves what you are asking for.
There are a few issues in your code:
There is a text-align:left on the sitewide container
Most elements have a width:100% directly on the element, meaning they won't be centred. They should have a set width, and max-width:100%;
I.E. I set #category{ width: 1024px; margin: 0 auto;} to get it centered.
Your carousel image does not have a set width, meaning it goes beyond the screen if it is below 1300px.
Set img{max-width: 100%;}.
#footer:
margin: 26px auto; should center it.
I might have forgotten a few things, but this made the site centered for me, including if I zoom in and out, and excludes a potential hoizontal scrollbar.

<!DOCTYPE> affects <body> size, can't get <body> to fill entire window

I'm designing a webpage which has a footer at the end of the page. Naturally, you'd want the footer to stick to the bottom of the page even if the length of the contents is less than the actual height of the page. After some searching I found out the way to go was to absolutely position the footer at bottom: 0px of the body and make the body fill the entire page. Right? Wrong. No matter what I tried, the body of the page would scale down to fit the elements within it (I tried both CSS and JS, no use) and just when I was about to give up, I found a sample on the internet which did the exact same thing. After yet another two hours of head-banging, I found out that the difference between that page and mine was that mine had a tag at the beginning (put there by Visual Studio).
I did some further researching, but I couldn't find any explanation as to why this happens, or, more importantly, what are the consequences of not including a doctype? Will this lead to problems later on? If so, what can I do about the height of the body element?
EDIT: This is my body's CSS:
body {
background-image: url("images/back.png");
margin: 0;
padding: 0;
min-height: 100%;
height: 100%;
}
and this is the HTML (it's ASP, in fact):
<%# Page Language="C#" %>
<!DOCTYPE HTML> <!-- this line (included by default by Visual Studio) causes the body's height to snap to its contents, as height: auto does -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script src="header.js"></script>
</head>
<body>
.
.
.
</body>
</html>
I also tried various other doctypes I found on the net, and I still got the same results.
Here is a simple example of how to position on the screen with css. Check this fiddle.
<div class="bottom"></div>
.bottom {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
height: 20px;
background-color: black;
}
You are probably looking for a solution to stick your website footer to the bottom. This becomes a real problem where you load your content through ajax and during load times your entire web content goes blank.
The solution that I eventually found to be better than any other is to give height a 100% to both your body and html and all your content except your footer in another div and give it some padding. The padding helps clearing room for your footer at the bottom using absolute position, otherwise your content would overlap your footer as well.
Here's an example:
html, body {
height: 100%;
}
.container {
padding-bottom: 20px; /* if your footer height is 20px including paddings and margins */
}
.footer {
position: absolute;
bottom: 0px;
}
and you can just make your footer's width 100% and text-align center if you want it in the center of your page.
--
As far as Doctypes are concerned, most of us use the standard - its better to keep it that way as it makes it easy for your browser to understand what kind of html it is.

Is there a reliable way to position content off to the sides of a div, and have it only appear if the user's resolution allows it?

I have my markup like this (for argument's sake)
<div id="content"></div>
<div id="layout"></div>
<div id="layout2"></<div>
Then I use this CSS
#content {
width: 800px;
height: 600px;
margin: 0 auto;
} /* place this attached to the top of the page */
#sidebar,
#sidebar2 {
display: block;
width: 139px;
height: 100%;
position: absolute;
top: 0;
background: url(../images/layout/pretty.png) repeat-y;
}
#sidebar {
left: 50%;
margin-left: -700px;
} /* at this point, it appears to the left, and does not trigger scrolling when the window is resized.. it just slides off to the left */
#sidebar2 {
right: 50%;
margin-right: -700px;
} /* now, when you resize, the scrollbar appears as if the content stretches from #sidebar to #sidebar2 */
Is there a reliable way to do this? My only other option is to have a large background image, thats say 1200px wide with my repeating design on the left and right.. but this seems cumbersome if I could get this to work.
So my question is, is there a way to position 2 divs which won't affect the browser's interpretation of the width of the page (i.e. as you resize narrower, or smaller resolution, the divs are just hidden out of the viewport?)
Thanks!
EDIT
Thanks for the answers guys, but none are able to give me quite what I want. What's important is these divs that appear outside must be relative to the #content div. They need to appear to the left and right side, and butt up against #content. However, once the browser window is resized to not accommodate them, they should disappear under the viewport. I'd rather not use overflow-x: hidden as I'd like people with small resolutions/windows to be able to scroll left and right to see all the content.
It is possible, because I've done it.
The trick was using negative margins on absolutely positioned divs. For some reason the browser does not attempt to provide scrolling for objects pulled out of the page in this manner.
You can also use overflow:hidden. This will begin cropping your divs contents as the div itself shrinks (make sure the div uses a percentage or auto width so it will actually shrink).
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Cropped sides (no scrollbars)</title>
<style>
div.decor {
border: 3px solid red;
overflow: hidden;
position: absolute;
width: 48%;
height: 500px;
top: 2%;
}
div.content {
width: 60%;
height: 300px;
margin: 100px auto;
padding: 10px;
background-color: #DDF;
opacity: 0.7;
position: relative; /*hmmm.. without this content goes behind decor regardless of z-index... why?*/
}
</style>
</head>
<body>
<div class="decor" style="right:50%"><img src="images/teacher.jpg" width=400 style="position:absolute;right:0px;"></div>
<div class="decor" style="left:50%"><img src="images/teacher.jpg" width=400></div>
<div class="content">lorem ipsum</div>
</body>
</html>
Demo: http://test.dev.arc.net.au/cropped_sides.html
Key points:
overflow:hidden on absolutely
positioned decor divs
right:0 on content of left decor div
(forces cropping from left side)
unpositioned content goes behind the
decor regardless of z-index, but I
don't know why. Simple workaround is
to use position relative on your
content wrapper.
Very simple with absolute positioning. You can absolutely position the background and assign it a lower z-index than the main content. Example of just the right side - background color added for clarity:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>Absolute Test</title>
<style type="text/css">
#content {
position: relative;
width: 800px;
height: 600px;
margin: 0 auto;
background-color: blue;
z-index: 100;
} /* place this attached to the top of the page */
#layout2 {
height: 100px;
width: 100px;
z-index: 1;
position: absolute;
right: 50px;
top: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="content"></div>
<div id="layout"></div>
<div id="layout2"></<div>
</body>
</html>
Works with a picture as well:
#layout2 {
height: 600px;
width: 100px;
z-index: 1;
position: absolute;
right: 50px;
top: 0;
background: url(right-side.gif) repeat-y;
The absolute positioning removes it from the flow, so the browser won't add the width of your background to the window size. Since your content is a fixed width, this will even work with IE6.
You can use JavaScript to make the extra divs visible when the browser window is wide enough to handle both. There's no way that I know of to have the browser ignore the div for layout without actually making it hidden.
Yes you can do this but only on the left side of the screen.
If you have any content on the right (outside of the viewport) the browser will add horizontal scroll bars. The only exception to this is if you turn off the scroll bars but this cannot be done only horizontally across all browsers.
Back to the left side idea... Elements positioned off the left side of the viewport do not cause a horizontal scrollbar. You can have a fixed width layout that is centered on the screen (auto margins on either side) then from within this area you can absolutely position a new column in the left space. If the browser viewport is narrow you won't see it, if it's wide it will be completely visible and usable. The only problem is if it's half-way in the middle - your left column will be chopped off - this could look a bit messy!
Another alternative is to detect the width of the viewport with JavaScript and only show the column if there is room?
Alternately, you could place the two "floating" divs in a container div set to the max width, and set the "overflow" to "hidden".
That's the easiest way!
ie. Something to this effect:
<div id="wrap">
<div id="left></div>
<div id="center"></div>
<div id="right"></div>
</div>
css:
#wrap{
width:800px;
overflow:hidden;
}

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.