I have issues with understanding the div position (relative, absolute, fixed) properties. I basically have an absolute div centered. Inside the div it should be possible to scroll vertically and horizontally. Inside this div should be a fixed header with a width larger than to screen (overflow) and a content div which has an overflow vertically and horizontally as well.
html,
body {
height: 100%;
width: 100%;
background: #fff;
margin: 0px auto;
padding: 0px auto;
position: fixed;
}
.container {
width: calc(100% - 20px);
height: calc(100% - 20px);
top: 10px;
left: 10px;
background: #2924aa;
overflow: scroll;
display: flex;
position: absolute;
z-index: 20;
}
.container-header {
width: calc(100%);
height: calc(10%);
background: #2924aa;
overflow: visible;
z-index: 10;
position: fixed;
background: red;
}
.container-body {
width: calc(110%);
height: calc(110%);
background: #2924aa;
overflow: auto;
position: absolute;
background: green;
}
<div class="container">
<div class="container-header"></div>
<div class="container-body"></div>
</div>
Here is my plunker:
https://plnkr.co/edit/wCWvHPcuYmVMql5HulHy
So i think the main question you have is in regards to the Position Attribute in CSS3. Below is a brief summary of each possible value.
CSS Positioning
The CSS positioning attribute of position has four different values.
Static - Static is the default value for position. It keeps the element on the page in its place, and it scrolls up the page as you scroll.
Relative - Relative positioning is pretty much as the same as static; however, you can use the left, right, top, and bottom attributes to alter the placement of the element relative to its original position.
Fixed - A fixed element's position is in relation to the viewport (i.e. the browser) therefore, an element with a fixed position does not scroll with the page, because when you scroll the viewport does not change. However, if you resize the browser, the element will change position.
Absolute - A element with an absolute position, is positioned relative to its parent element (i.e. the element that contains it).
A good resource for more information, including some diagrams can be found here.
Related
In the context of the development of a menu, I have a fixed position div (sort of popin that contains level 3 and more menu items) which is contained by an absolute positioned div (that contains level 2 items).
Sometimes the absolute div has a scrollbar and in this case this scrollbar appears above the fixed div on Google Chrome (this doesn't happen on FF and IE).
Simplified jsfiddle example
.level-1 {
background: red;
height: 150px;
width: 200px;
position: absolute;
z-index: 1;
overflow-y: auto;
overflow-x: auto;
}
.level-1-content {
height: 200px;
}
.level-2 {
position: fixed;
left: 50px;
top: 50px;
width: 400px;
height: 200px;
z-index: 2;
background: blue;
}
<div class="level-1">
<div class="level-1-content"></div>
<div class="level-2"></div>
</div>
This issue happens only when the fixed and/or the absolute div have a z-index.
In the jsfiddle simple example, the z-index are not required, but in the context of my menu, I need them.
Does anybody know a CSS solution in order to Chrome not to display this scrollbar above the child div in this context (I mean, with my constraints, i.e. the parent div is absolute and has a z-index and the child div is fixed) ?
Thanks in advance.
How would I go about absolutely positioning the child to the right side of the parent (with margin on all sides of the child element)? Why does the child cause the parent (with a min-height) to generate a scrollbar when the child falls outside of the normal flow of the document? What must I do to get rid of that scrollbar?
Alternatively, how could I use the calc() function in the context of a relative position of the child so I get the same outcome?
* {
box-sizing: border-box;
}
.box {
width: 50%;
min-height: 400px;
margin: 50px auto;
background: hsl(220, 80%, 50%);
overflow: auto;
position: relative;
}
.child {
width: 200px;
margin: 20px;
min-height: inherit;
background: firebrick;
position: absolute;
right: 0;
}
<div class="box">
<div class="child"></div>
</div>
The min-height: inherit; on the child inherits the value from the parent which is 400px, and the margin: 20px; makes the total height over 100%, and you have overflow: auto; sets there, it means the scrollbar will appear if the container couldn't hold the content inside.
If they are in the normal content flow, the scrollbar won't appear, since it is min-height, the container will adjust the height to fit the content. However, in the relative and absolute positions, the absolute box is taken out the normal flow, the container won't able to adjust the height to fit automatically, and that will cause the overflow when the child's height exceeds.
To get rid of the scrollbar, you can use calc() function like you mentioned. You just need to set min-height: calc(100% - 40px); on the child. Or, change overflow value to hidden on the parent, the output will be different though.
By the way, since you have box-sizing: border-box; declared, but it does not do anything for margin.
I know that bottom, top, left, and right with position: absolute sets that edge of the element to some distance away from that edge of the parent element. But how is the edge of the parent defined? Where is it in the box model? Does it include the border or the margin? The padding?
It's within the border, but ignores the padding.
Let's show it with an example. View on JSFiddle
HTML
<div>
<span>absolute</span>
regular
</div>
CSS
div {
position: relative;
top: 50px;
left: 50px;
background: #eee;
padding: 15px;
width: 100px;
height: 100px;
border: 5px solid #222;
}
span {
position: absolute;
top: 0;
left: 0;
}
Of course, an absolutely positioned element is positioned in relation to the first parent it comes across that is positioned with anything other than static. If the div in my example had no position set, the body of the fiddle would be used as that parent.
I have one element below another and I am using position relative to drag the bottom element up just a bit so that it overlays the top element.
The paperOverlay element is the last element on the page, vertically speaking, and I want it to extend to the bottom of the browser window. However, the relative nudging of the element's position leaves an equal amount of whitespace at the bottom. Is there any way to avoid this?
The HTML looks like:
div class="container">
<div class="homePage">
<!-- some content -->
</div>
<div class="paperOverlay" style="position: relative; top: -70px;">
<!-- some more content -->
</div>
</div>
And the CSS looks like:
div.container
{
width: 960px;
margin: 0 auto;
}
div.homePage
{
width: 800px;
height: 500px;
}
div.paperOverlay
{
width: 960px;
min-height: 400px;
background: url('Images/Overlay.png') no-repeat top center;
}
Basically, the bottom layer is a white background with a torn paper edge effect at the top. The goal is to have the torn paper edge slightly overlay the bottom of the element above it. I did try margin-top: -70px as suggested below and it fixed the height, but now the elements in the top element lay on top of the overlay, and I want the overlay to be on top.
Could you try a negative margin rather than relative positioning? Also, could you explain a little bit more why you need to do this and post you css so that we can better suggest a solution?
Try setting the height of the paperOverlay element. It should be the actual height minus the amount moved relatively.
I did try margin-top: -70px as suggested below and it fixed the height, but now the elements in the top element lay on top of the overlay, and I want the overlay to be on top.
Try this:
div.container
{
margin: 0 auto;
width: 960px;
}
div.homePage
{
height: 500px;
position: relative;
width: 800px;
z-index: 1;
}
div.paperOverlay
{
background: url('Images/Overlay.png') no-repeat top center;
min-height: 400px;
position: relative;
top: -70px;
/* you can optionally use bottom: 70px; rather than top: -70px */
width: 960px;
z-index: 2;
}
Using position: relative; on both elements and setting the z-index should get the overlay on top of the top element, rather than the other way around.
You may also want to try using display: block; on all elements where you need fixed width/height (especially divs and other containers that need a fixed width/height, like anchors or list items), to prevent collapsing. It will usually resize non-block-level elements to fit their contents and ignore width and height rules otherwise.
Using the "vh" unit worked for me. I could not get it to work with height: calc(100%-50px)
#main-nav{
width: 55px;
background-color: white;
transition: 400ms;
height: calc(100vh - 50px);
}
First of all, have a look at this example of the layout I'm trying to achieve (below)
Basically, I have a standard center div (gray) with the typical margin: 0 auto. My problem is that I have a background image (on the white overflow area) that is <div id="stripes"> with the following CSS
background: url(foo) top center repeat;
position: fixed;
width: 100%;
height: 100%;
This background is applied BELOW the HTML level of the document to the #stripes div.
What I'm having trouble with is setting up the red div below. The plan is for it to stay visible at all times via position: fixed however, I can't use % based right: xx%; top: 0 because the pattern must line up with the striped pattern, so a few pixels offset will create a visible and obvious "seam" on the page.
Here is a look at the effect with the stripes included:
The way I ended up solving this was to create two divs. On the top layer, I used a standaard width: 960px; margin: 0 auto div and then at the end of the document I created another div with the same styles meant to act as a container for the photo (red div above). Inside of the second div I nested a <div id="photo_bg"> div. This div used the following styles:
#photo_bg{
background: url(foo.jpg) top right no-repeat;
overflow: visible;
position: fixed;
right: 50%;
top: 0;
width: 1014px;
z-index: 2;
}
the parent div was called #stripes
#stripes {
background: url("images/bg_striped_repeat.jpg") repeat scroll center top transparent;
height: 9999px;
left: 0;
overflow: visible;
position: fixed;
top: 0;
width: 100%;
z-index: 1;
}