I need to create a HTML page that is composed of two main parts: a fixed header part (a selection bar) and a second part that displays some text. I have tryed the code below, but as I am new to CSS this doesn't work as I wanted to:
9 <style type=\"text/css\">
10 #header {
11 position:fixed;
12 top:0px;
13 margin:auto;
14 width: 100%;
15 background:#F0F0F0;
16 }
17 #content {
18 position:absolute;
19 top:90px;
20 }
21 </style>
22 </head>
23
24 <body>
25 <div id=header>
26 <h1> HEADER: Long header................................................................... </h1>
27 </div>
28 <div id=content>
29 <p> Content...</p>
30 </div>
31 </body>
The "content" part goes under "header" but I am having two issues with this code:
when scrolling, the "content" text goes over the "header" text. I
need to hide the scrolled "content" text under the header.
when resizing, if the header contains a long text, after resizing that text goes on the next line and this affects the "content" part, which starts at 90px from the top. How can I position my content part so taht it is displayed below the "header" when resizing, but when scrolling goes under.
Thanks in advance for your help!
Try Following:
#header {
position:fixed;
top:0px;
left:0px;
margin:auto;
width: 100%;
height:90px; /* To make Underlying #Content visible */
overflow:hidden; /* This will hide extra content after resizing */
z-index:10; /* This is Important */
background:#F0F0F0;
}
#content {
position:absolute;
top:90px;
left:0px;
z-index:1; /* Any value <10 */
}
Adding z-index and overflow will solve your problem.
DEMO
Z-index:
The z-index property in CSS controls the vertical stacking order of elements that overlap. As in, which one appears as if it is physically closer to you.
Overflow:
Every single element on a page is a rectangular box. The sizing, positioning, and behavior of these boxes can all be controlled via CSS. By behavior, I mean how the box handles it when the content inside and around it changes. For example, if you don't set the height of a box, the height of that box will grow as large as it needs to be to accommodate the content. But what happens when you do set a specific height or width on a box, and the content inside cannot fit? That is where the CSS overflow property comes in, allowing you to specify how you would like that handled.
There are four values for the overflow property: visible (default), hidden, scroll, and auto. There are also sister properties overflow-y and overflow-x, which enjoy less widespread adoption.
CSS positioning:
Static.: This is the default for every single page element. Different elements don't have different default values for positioning, they all start out as static. Static doesn't mean much, it just means that the element will flow into the page as it normally would. The only reason you would ever set an element to position: static is to forcefully-remove some positioning that got applied to an element outside of your control. This is fairly rare, as positioning doesn't cascade.
Relative.: This type of positioning is probably the most confusing and misused. What it really means is "relative to itself". If you set position: relative; on an element but no other positioning attributes (top, left, bottom or right), it will no effect on it's positioning at all, it will be exactly as it would be if you left it as position: static; But if you DO give it some other positioning attribute, say, top: 10px;, it will shift it's position 10 pixels DOWN from where it would NORMALLY be. I'm sure you can imagine, the ability to shift an element around based on it's regular position is pretty useful. I find myself using this to line up form elements many times that have a tendency to not want to line up how I want them to.
There are two other things that happen when you set position: relative; on an element that you should be aware of. One is that it introduces the ability to use z-index on that element, which doesn't really work with statically positioned elements. Even if you don't set a z-index value, this element will now appear on top of any other statically positioned element. You can't fight it by setting a higher z-index value on a statically positioned element. The other thing that happens is it limits the scope of absolutely positioned child elements. Any element that is a child of the relatively positioned element can be absolutely positioned within that block. This brings up some powerful opportunities which I talk about here.
Absolute.: This is a very powerful type of positioning that allows you to literally place any page element exactly where you want it. You use the positioning attributes top, left bottom and right to set the location. Remember that these values will be relative to the next parent element with relative (or absolute) positioning. If there is no such parent, it will default all the way back up to the element itself meaning it will be placed relatively to the page itself.
The trade-off, and most important thing to remember, about absolute positioning is that these elements are removed from the flow of elements on the page. An element with this type of positioning is not affected by other elements and it doesn't affect other elements. This is a serious thing to consider every time you use absolute positioning. It's overuse or improper use can limit the flexibility of your site.
Fixed.: This type of positioning is fairly rare but certainly has its uses. A fixed position element is positioned relative to the viewport, or the browser window itself. The viewport doesn't change when the window is scrolled, so a fixed positioned element will stay right where it is when the page is scrolled, creating an effect a bit like the old school "frames" days. Take a look at this site (update: dead link, sorry), where the left sidebar is fixed. This site is a perfect example for since it exhibits both good and bad traits of fixed positioning. The good is that it keeps the navigation present at all times on the page and it creates and interested effect on the page. The bad is that there are some usability concerns. On my smallish laptop, the content in the sidebar is cut off and there is no way from me to scroll down to see the rest of that content. Also if I scroll all the way down to the footer, it overlaps the footer content not allowing me to see all of that. Cool effect, can be useful, but needs to be thoroughly tested.
Dont Only Write The Code. Understand It before writing.
By courtesy of: http://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/
Hope it helps.
For More: http://css-tricks.com
Try this in your header CSS. The z-index changed.
#header {
position:fixed;
top:0px;
margin:auto;
width: 100%;
background:#F0F0F0;
z-index: 1;
}
You should create a http://jsfiddle.net/ including your markup and css.
Some things I can point out right now.
Fix your syntax errors (missing quotes)
Your header is fixed thats correct. You don't need the margin: auto. no effect.
I think you don't need a position absolute on your content. You can add a z-index to the header to ensure it's always over the other elements to hide the other element under the header.
Just remove
position:absolute;
top:90px;
from #content.
Here is the demo
Full code:
<style>
#header {
position:fixed;
top:0px;
background:#F0F0F0;
}
</style>
<body>
<div id=header>
<h1> HEADER: Long header................................................................... </h1>
</div>
<div id=content>
<p> Content...</p>
</div>
</body>
Z-index on both header and content fix your problem!
Here an example http://jsfiddle.net/52Z7L/
#header {
position:fixed;
top:10px;
margin:auto;
width: 100%;
background:red;
z-index:100;
}
#content {
position:absolute;
top:90px;
z-index:0;
}
Related
I have a navbar at the top of the page that I want to be fixed. The problem is that if I make it fixed as opposed to absolute or something, stuff that would normally be below it takes its place and it sits on top making the content invisible. Any way I can get them to notice the fixed element and position accordingly without having to position:absolute or position:relative all of them?
nav{
width: 100%;
position: fixed;
top:0;
}
Apply a margin-top or padding-top to the first non-fixed element on the page, with a value as high as the height of the fixed-position navbar. Typically that element would be main, the first section or similar, possibly also simply the first (non-fixed) div, depending on your page structure.
I am trying to put an absolute div inside a relatively positioned div. But I don't want to define a height for the relative div.
The relative div has a background colour and when I don't define a height the absolute div goes 'outside' the relative div. I can't control how many lines the text will be so the height of the divs change
HTML
<div class="row top-footer">
<div class="top-footer-text text-center">
<div class="test">
<h1>title</h1>
<div class="footer-btn-wrap">
<div class="footer-btn">button</div>
<div class="footer-btn">button</div>
</div>
</div>
</div>
</div><!-- /top-footer -->
CSS
.top-footer {
position: relative;
background-color: #686a6f;
width: 100%;
padding-top: 40px; margin: 0;
}
.test {
position: absolute;
top: 0px; margin: 0;
}
EDIT
I want .top-footer (position: relative) to contain .test (position: absolute) with space/padding/margin on the top and bottom of .test. the height of the div is unknown because the content may take up more than one line depending on screen size
Adding whitespace around the child div is fairly trivial. However preventing the parent div from collapsing is more tricky and is the thing you need to tackle first. The problem you are having is that with the parent relatively positioned and the child absolutely positioned, the only element on the entire page that actually "knows" where the child is is the parent... and even then it's a fairly bad parent because it won't even make enough space for the child! The rest of the DOM will behave as if the element isn't even there - other non-positioned elements will float over or above it - even text will be obscured by your child div. Assuming you want to put other content in the parent div using absolute positioning in this way only means you're going to have to use absolute positioning all around the place... which can get a bit heavy on the brain debugging layout problems later on.
The only possible solutions I can think of offhand are:
Use javaascript to sniff out the height of the child div and apply that to the parent. A fairly simple job if you use a library like jQuery but that requires extra downloaded files and makes your site unnecessarily bulky if this is the only task you're using it for. THis also wouldn't solve the problem of the child div obscuring other elements on the page.
Rework your CSS (and it might take a lot of reworking depending on how far you've got and the complexity of the styling) to use display:inline-block on the child... this will stop the parent from collapsing but might give you additional layout issues.
Rework your CSS (ditto) to float:left the child div. You would then need to use a CSS "clear hack" in order to prevent the parent divv from collapsing, although this is a tiny piece of CSS you can cut and paste from elsewhere... an easy job.
If you're determined to use absolute positioning like this my preferred solution would be to use jQuery (option 1) because most of my work tends to use a degree of it anyway... it's a tool I would have handy and the code to perform this task would be quite trivial.
EDIT - Here's a little fiddle to get you started. https://jsfiddle.net/fo8mq1vf/
This is how the output of your code looks like: https://jsfiddle.net/s3zLa54t/2/. The parent div (.top-footer) does contain the .test div. What browser are you using to view the output?
As for the padding, I guess you don't see any effect of changing padding-top. Try removing the top: 0px property in the .test div.
If this is not what you were looking for, do clarify the question here.
The answer to your question is simply remove
position:absolute from your absolute div (.test)
position:relative from your relative div (.top-footer)
height:300px from your relative div (.top-footer)
This is the tested version of https://jsfiddle.net/s3zLa54t/3/ with multiple number of divs under your main div. You can check that it is not going beyond the grey background.
.top-footer {
position: absolute;
background-color: #686a6f;
width: 100%;
padding:0px;
margin: 0;
}
.test h1{
padding-left:20px;
position: relative;
top: 5px; margin: 0;
float:left;
color:#FFF;
}
.footer-btn,.footer-btn-wrap
{
padding-left:200px;
color:#FFF;
}
.footer-btn a{
padding:5px 10px;
float:left;
color:#ffffff;
text-transform:capitalize;
text-decoration:none;
}
I have always used margin to move a floating div to the correct position in a parent div (say the logo div within a header div). This has always worked but that meant you have to play with the individual height of the elements else it will affect the remainder of the layout downwards.
I found another method today and that is to make the logo div position: relative; and then use example top: 20px; to move the element around, and this does not appear to affect the layout.
I don't want to adapt to this without knowing that there may be other implications, so can anyone point out common flaws in either of the above methods or possibly suggest a better solution?
// Sample HTML
<div id='header'>
<div id='logo'>
LOGO GOES HERE
</div>
</div>
// Sample CSS
#header {
height: 100px;
}
// Version 1
#logo {
float: left;
margin-top: 20px;
}
// Version 2
#logo {
float: left;
position: relative;
top: 20px;
}
From Mozilla developer:
relative
Lay out all elements as though the element were not
positioned, and then adjust the element's position, without changing
layout (and thus leaving a gap for the element where it would have
been had it not been positioned). The effect of position:relative on
table-*-group, table-row, table-column, table-cell, and table-caption
elements is undefined.
I hope this answers your question.
Sometimes it might be the right thing to use, other times not. It really depends on your layout, if you want to make a responsive design, it might be better to have the margin there.
In your case you have a fixed height on the header, so you can use relative. I think it is a more common practice to use margin. I am only aware on issues concerning position: fixed on mobile devices.
You can learn more about CSS and positioning here.
In postion absolute and fix when u use top or bottom or right or left,you must not use float, you must for its parent use this style
postion:relative;
best regards
I have a container div, conteining 3 divs, a sidebar, a content and a header while all the elements inside are rendered as they should (they are positioned as "relative" if this may influence in my problem), the sidebar and the content render min-height: 100% as I need, the div containing them won't adapt to those 3 elements, acting like overflow: visible, while I don't want the content to overflow, I want the whole page to scroll and the div to adapt to the content size...
I tried to put my code here : http://jsfiddle.net/vhZV6/
I also cut out some of the graphical tweeks wich should not influence at all... here is a screen of my problem too:
I don't need old broweser integration on this matter (as IE 5/6).
Try adding overflow:auto; to your .container div.
I would try this. 'height: auto' is no longer set once any of the height elements are messed with.
min-height:100% !important;
height:auto !important;
It's a very simple problem: your inner divs are floating. The solution is very simple, just add to your css the following (this is the best solution whenever you have floating divs):
.container:before {
content:".";
display:block;
height:0;
clear:both;
visibility:hidden;
}
I'm trying to understand CSS positioning and I'm having trouble figuring out why a simple change that apparently should have no effect on the layout is causing a very disruptive change. I'm obviously missing something.
The initial objective was to place an inner div
vertically and horizontally within another div. That was fairly simple:
html, body {
margin:0;
padding:0;
height:100%;
}
div#container {
position:relative;
background:#4444ff;
margin: 0 auto; /* center, not in IE5 */
height:80%;
min-height:80%;
}
div#childDiv {
position:absolute;
background:#ff5555;
/* next we center it vertically and horizontally */
width:900px;
height:600px;
top:50%;
margin-top:-300px;
left:50%;
margin-left:-450px;
}
...and in the HTML page I used:
<body>
<div id=container>
<div id=childDiv>
test
</div>
</div>
</body>
which worked fine.
The curious part is what happens when I change the position attribute of the #childDiv div from absolute to relative.
My understanding is that first is should not affect the #container div at all since I'm changing only the position of the child element, and second that it should not change the layout since it is the only child element, its parent uses relative position and third I have not specified any offsets (tp, left, etc).
Instead, when I make this change, the parent #container is messed up (shows only up to the half of the viewport instead of 80% height as previously), and the position of #childDiv changes accordingly (also upwards, half outside the viewport).
My questions is: why does that happen? What concepts I'm not taking into account and why was the parent div affected by a change in the children's position setting?
If I remove #childDiv from within #container and place it inside body, then #container is no longer affected by that change so it seems something is propagating up in the DOM, which is odd to me. I've seen the same in firefox, opera, IE and chrome.
I have read W3C's spec on this topic but I haven't been able to figure this one out so far...
UPDATE: I created examples in JS fiddle to show the problem. You can see the original is here: jsfiddle.net/7Pr9y/1 and the affected one is here: jsfiddle.net/7Pr9y/3
Thank you!
Eduardo
When something is absolutely positioned, it is taken out of normal flow so its size, margins, etc. do not affect the things around it.
When something is relatively positioned, it is placed in normal flow (so its size, margins, etc. do affect the things around it) and layout is initially handled as if it were position: static, then it is moved according to the left, right, top and bottom properties.
It looks like your CSS got complex quickly because as soon as you positioned the child div absolutely, your container div would have disappeared, and putting percentage-based widths and heights on it wouldn't work.
The reason for this is that once you position something absolutely, it's taken out of the document flow, so your container div is now acting as if it contains nothing. If it contains nothing, unless you give it absolute dimensions (say, in pixels), you're saying "size yourself to a certain percentage of your container", which in this case, is the body element, which also acts as if it contains nothing.
When you start tossing heights and widths and min-heights on every element to compensate, especially when they are relative values, the results can become unpredictable very quickly. My advice would be to check out this reference on the box model by Chris Coyier: http://css-tricks.com/the-css-box-model/
It's super straightforward and uses some great diagrams to help visualize the different aspects of CSS positioning.
OK, I figured out why it becomes smaller when I change the size to relative.
Happens that because I have set the margins of the #childDiv to a negative value in order to center it, when I change it to relative that negative margin is taken into account when calculating the height of #container, resulting in a smaller #container.
I'm obviously a beginner in this, but seriously, it looks like CSS made it as complicated as possible to lay things out. No surprise most folks coming from table layouts start frustrated. :(
You don't need all these negative margin settings. Do the following:
html, body {
margin:0;
padding:0;
height:100%;
}
div#container {
background:#4444ff;
margin: 0 auto; /* center, not in IE5 */
text-align: center;
height:80%;
min-height:80%;
}
div#container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
div#childDiv {
display: inline-block;
text-align: left;
vertical-align: middle;
background:#ff5555;
width:500px;
height:200px;
}
I have used your code you provided and changed it around a little, to make the ghost spacer (the div#container:before) work.