Reputation: 1004
I have a simple problem that made me waste two days without any success. I am a beginner with CSS, so excuse me if I am asking silly questions.
JSFiddle
Problem
I have a webpage with three main divs 'header', 'contentContainer' and 'footer'. In the contentContainer there is one div called "content". The content div should contains multiple sections (I use purecss to represent each section in the grid)
A section should contain two divs 'divA' and 'divB'. Now 'divA' should have dynamic height and divB should be have fixed height. Meaning if I resize the browser, 'divA' should be resized along with the section ofc. The screenshot below visually shows what I described.
Now what I don't understand is the following:
Why can't I position 'divA' with top/bottom? It didn't work so I had to position it with height property.
.divA{
position: relative;
top: 0;
bottom: 100px;
............
}
instead of
.divA{
position: relative;
height: 85%;
...........
}
Note_1 I read somewhere that I can use absolute positioning instead of relative positioning for both divs: 'divA' and 'divB'. However with absolute positioning I won't have dynamic height for 'divA'
Note_2 I won't have elements in 'divA' and 'divB'. Just a background color or image. So basically I want the 'section' div to fill the 'content' area although it has no children with a specified height.
Please, I would really appreciate if someone explains to me the reason behind this behavior. I thought positioning elements with CSS will be logical but it turned out that its not ^^ (I am missing something for sure)
UPDATE
Thanks @Florian for your answers. I found one problem with your suggestion. After I added
overflow:hidden;
to the contentContainer like you suggested, 'divB' is going under the 'section' div. The behaviuor that I want to achive is that 'divB' should stay in the same position with the same height "100px" in the section. And 'divA' should just resize with the container. http://jsfiddle.net/oqe3bjxe/
How can this be fixed?
Regarding your answers,
Sorry for asking many questions. I just really want to understand.
If using relative position is not recommended, then I guess there is for sure a better way to achieve this. Could someone please show me using JSFiddle the best practice how to do it?
Thanks in Advance, Tefa
Upvotes: 4
Views: 9210
Reputation: 438
I've found a solution.
When you have position: relative;
on .section
, every position: absolute;
inside it will be positioned relative to it, not to page.
From MDN:
relative:
This keyword lays 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.
absolute:
Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block. Absolutely positioned boxes can have margins, they do not collapse with any other margins.
I've done a fiddle.
.section {
background-color: red;
position: relative;
bottom: 0;
top: 0;
height: 100%;
/*put this uncommented if youll want the black box to minimize with the whole thing
overflow: hidden*/
}
.divA {
background-color: green;
height: 85%;
width: 100%;
/*width: calc(100% - 14px); optional, works in some browsers, use with margin*/
position: absolute;
top: 0px;
/*you can remove this if you don't want red visible
margin: 0 7px;*/
}
.divB {
background-color: black;
position: absolute;
bottom: 0px;
height: 100px;
width: 100%;
/*width: calc(100% - 14px); optional, works in some browsers, use with margin*/
background-color: black;
/*you can remove this if you don't want red visible
margin: 0 7px;*/
}
You have two options, uncommenting
overflow: hidden;
will minimize the black box when .section becomes smaller than 100px;width: calc(...); margin: 7px 0px;
will make the boxes smaller so the red is visible.Test it out. I hope that i've answered your question.
EDIT: Oh, I totally forgot the height: 85%;
property and of course, as @RMo pointed out, it doesn't work when .section
is more than 666px high.
Replace height: 85%;
with bottom: 100px
or use calc(): height: calc(100% - 100px);
.
I'm a big fan of calc(). Although, it isn't supported in all browsers, but almost.
Let me know, @TeFa, if it helped you understand some css. :)
Upvotes: 3
Reputation: 874
As I understand your question you want to display divB inside of section. For that you need to make some change in css.
.divA {
background-color: green;
max-width: 1000px;
max-height: 1080px;
height: 100%;
position: relative;
top: 0;
margin: 0 7px 0 7px;
}
add new css
.divA{
margin-bottom: -100px;
}
.divB,
.divA:after {
height: 100px;
}
Upvotes: 3
Reputation: 21
there is lots of answers.
My answer isnt true answer, but tip that helps me a lot, when i started. Did you try something like reset.css
? Every broswer has different default values and it sets all properties of css to zero, so after that you can finaly write your own css.
You simply include it before your css file.
It looks like that
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
The original website is here.
Hope to help you a little bit.. ^^
Upvotes: 2
Reputation: 5144
I kind of started from scratch again. I used fixed positions based on top, bottom, right, left, height and width -values. For the yellow div I only used a top and bottom value. This will result in the container adapting on resizing the browser. The other containers all have a fixed height. Note that it does not matter at all where the divs are in the html for fixed positions. Finally I placed the content using margins to avoid the fixed elements. Check out the code and you should be able to figure it out: JSFiddle
I hope this is what you are looking for (because I wasn't 100% about sure what you wanted). I guess I ll hear that soon :).
Simpliefied HTML
<div id="header"></div>
<div id="content">
<div id="dummytext"></div>
</div>
<div id="divA"></div>
<div id="divB"></div>
<div id="footer"></div>
CSS
#header{/*changed closing tags in html to: <div id="header"></div>*/
position: fixed;
top: 0px;
height: 50px;
left: 0px;
right: 0px;
background-color: blue;
border-bottom: white solid 20px;
}
#divA{
position: fixed;
bottom: 170px; /*no height but top/bottom values so containers height changes based on browsersize*/
top: 70px;
left: 0px;
right: 50%;
background-color: yellow;
}
#divB{
position: fixed;
bottom: 70px;
height: 100px;
left: 0px;
right: 50%;
background-color: red;
}
#footer{
position: fixed;
bottom: 0px;
height: 50px;
left: 0px;
right: 0px;
background-color: blue;
border-top: white solid 20px;
}
#content{
margin: 70px 2% 70px 55%; /*margins to place scrollable content avoiding fixed content to appear on top of the content*/
}
#dummytext{/*Just some dummy text to see what happens with scrollbar*/
height: 1000px;
width: 100%;
background: linear-gradient(red, orange, yellow, green, blue);/*all colors of the rainbow, just because..*/
}
Upvotes: 2
Reputation: 5135
The problem is that you don't have a height to the contentContainer class.
You can fix this with adding the following CSS:
.contentContainer{
overflow:hidden;
}
There are a lot of mistakes.
1. Margin: 0 auto, doesn't work if you have position fixed.
2. Position: relative only takes top and left property that means that bottom and right won't affect it.
3. Make sure that you have a height of the container (for example 1500px) if you want to give a height of % of the child elements. The % will calculate from the height of the parent, and if you have no height for the parent that won't work.
4. I wouldn't recommend using that much position:relative. What you want to achieve is easier with margin-top
of the container.
5. If you have a fixed footer, make sure you add some padding-bottom
to the body.
Upvotes: 3