I have a "fixed" DIV on the very top of my page:
<div id="banner-wrapper">
<div id="banner"></div>
</div>
with the following CSS:
#banner-wrapper {
width:300px;
height:500px;
}
#banner {
width:300px;
height:500px;
position:fixed;
top:0;
left:0;
background:orange;
}
This "fixed" DIV is followed by a "content-wrapper" DIV:
<div id="content-wrapper">
<div id="content-left">
content left
</div>
<div id="content-right">
content right or sidebar
</div>
</div>
with the following CSS:
#content-wrapper {
width:300px;
background:red;
position:absolute;
top:500px;
bottom:0;
}
#content-left {
width:150px;
float:left;
}
#content-right {
width:150px;
float:right;
}
The issue I'm having is that the "content-wrapper" DIV does not fully cover the "fixed" DIV. The top of the "content-wrapper" covers the "fixed" DIV and the bottom of "content-wrapper" becomes transparent, showing the "fixed" DIV beneath.
I was able to solve the problem by giving the "body" a height in CSS. However, I do not want to give the "body" a height as I do not know the true hight of the content and would like it to remain flexible. I've also have tried inserting
<div style="clear:both;"></div>
before the closing tags but it does not force the "content-wrapper" down.
Here is an example of the issue on JSFiddle.
As you can see, the "red" box does not reach the "blue" box even though it is set to absolute, bottom 0. From what I can tell it reaches the bottom if it does not contain any DIVs inside of it. But once I add the "content-x" DIVs, it no longer reaches the bottom of the page.
Thank you for any help.
You could relatively position the element #content-wrapper rather than absolutely positioning it. Then you can omit the top/bottom positioning and it will behave as expected.
The reason it wasn't working in the first place was because you were giving the absolutely positioned element a height of 100%. Therefore it will have the same height is the window, which is not what you wanted.
Updated Example
Change the following:
#content-wrapper {
width: 300px;
height: 100%;
background: red;
position: absolute;
top: 500px;
bottom: 0;
}
to:
#content-wrapper {
width: 300px;
background: red;
position: relative;
}
Related
I am trying to fix a div with a 50vw width. However, when I fix the div, 50vw acts as if it's 100vw.
In the example below, to get the effect I want, I have to make the target 25vw instead of 50vw. 100vw is wider than the screen.
Here is the jsfiddle. the blue .target container should be half the width of the yellow container.
<div class="main">
.
<div class="content">
<div class="content-wrapper">
<div class="target-containers">
<div class="target">. </div>
</div>
</div>
</div>
</div>
CSS
html, body {
margin: 0;
width:100%;
height: 100%;
}
body {
background-color:gray;
}
.main {
background-color: yellow;
min-height:100vw;
position:relative;
margin-left: 25%;
margin-right:25%;
}
.content-wrappers {
position:relative;
}
.target-containers {
position:relative;
}
.target {
min-width:50%;
width:50%;
position:fixed;
float:left;
background-color:blue;
}
Please read about position: fixed.
It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none
Who is the initial containing block? (EDIT to clearify this comment)
Please read about identifying the containing block
Note: The containing block in which the root element () resides is a rectangle called the initial containing block. It has the dimensions of the viewport (for continuous media) or the page area (for paged media).
Please read about position: sticky
A stickily positioned box is positioned similarly to a relatively positioned box, but the offset is computed with reference to the nearest ancestor with a scrolling box, or the viewport if no ancestor has a scrolling box.
You could change the position value to sticky like this
.main {
background-color: yellow;
max-height:100vh;
min-height: 100vh;
margin-left: 25%;
margin-right:25%;
overflow-y: auto
}
.target{
min-width:50%;
width:50%;
position:sticky;
background-color:blue;
top: 0;
}
Fiddle Example
If you make an element position:fixed it will break it out of the document flow.
If you remove position: fixed it works as expected as it is inheriting from the parent element.
https://jsfiddle.net/k460abmv/
Say I have three divs like following:
<div class="wrapper">
<div class="container">
container1
<div class="element">
fixed
</div>
</div>
<div class="container2">
container2
</div>
</div>
I want div: element to be fixed when it is inside div: container, but its position should become absolute when div: container2 becomes visible, it should not overlap with div - container2, but scroll away at that time with div: container.
A pure CSS solution is preferable, but if not possible I may go for a JS or jquery solution. I have created a fiddle for this, and tried some solution suggested here, which are not working.
What I would suggest is to use javascript to recognize when the scrolling is at a certain point with window.pageYOffset
When it reaches your desired window Y Offset you can start an event that modifies the css value of the positioning from fixed to absolute (by setting the parent container to relative) and bottom at 0.
Check out this jsfiddle https://jsfiddle.net/zq0kkkcx/2/
Also, this is the code that I'm talking about:
document.addEventListener("scroll", function(event) {
if(window.pageYOffset >= 1200){
console.log("1200");
// this is where you want your element to become absolute
// positioned to his parent container
// write your css changes here and apply them to elements
// add relative to container and absolute with bottom 0 to element
} if (window.pageYOffset <= 1200){
console.log("<1200");
}
});
If you want a CSS solution, here is a trick that you can do using z-index. Other than this there is a JS solution.
.wrapper {
width:100%
}
.container {
width:300px;
margin:0 auto;
height:1200px;
background:#ccc;
position: relative;
z-index: -1;
}
.container2{
width:300px;
margin:0 auto;
height:1200px;
background:#fcf;
z-index: 1;
}
.element {
background:#f2f2f2;
position:fixed;
width:50px;
height:70px;
margin-left:250px;
border:0px solid #d6d6d6;
}
<div class="wrapper">
<div class="container">
container1
<div class="element">
fixed
</div>
</div>
<div class="container2">
container2
</div>
</div>
You're looking for a sticky header. There is currently no way to make a header sticky at an arbitrary scroll position using pure CSS - you'll have to look into a JavaScript solution to accomplish that.
Yes, it is 100% possible to do this without any JavaScript
I updated your fiddle
Markup should be like this
<div class="wrapper">
<div class="outer-scroller">
<div class="scroll-container">
container1
<div class="fixed-header">
fixed
</div>
</div>
</div>
<div class="last-container">
container2
</div>
</div>
and css
.wrapper {
width: 100%;
height: 300px;
}
.outer-scroller {
height: 140px;
overflow-y: scroll;
}
.scroll-container {
padding-top: 70px;
width: 300px;
height: 1200px;
background: #CCC;
}
.last-container {
width: 300px;
height: 600px;
background: #FCF;
}
.fixed-header {
background: #F2F2F2;
position: absolute;
width: 300px;
height: 70px;
top: 0;
pointer-events: none;
}
You'll see I've added an outer-scroller div.
The next bit is changing your CSS slightly
The new outer-scroller div is double the height of your fixed-header (for the purposes of this example) and it has an overflow-y: scroll on it.
The container inside there is still the same.
The next change is turning your position: fixed into a position: absolute and then adding padding to the top part of the div you want to scroll in order to push its content "below" the new "fixed" header.
Scrolling over the outer-scroller div then makes its content scroll, and because its height is set with an absolute element on top it then scrolls "under" the fixed header.
Once the bottom of its child content scroll-container is reached, the whole page then continues scrolling, and you get the illusion of the header disappearing.
The last bit is pointer-events: none on the header so that it doesn't scroll away when the cursor is over it (but the div below does)
I want to create a div that's wider than its parent, and i found many solutions.
Almost all of them say something that looks like this:
position:absolute;
left:0;
right:0;
(for example: How to expand child <div> with 100% of body width?)
This is indeed a solution, but there is only one little problem.
situation:
(jsfiddle)
<style>
.parent
{
width:70%;
padding: 1%;
}
.fullwidth
{
position:absolute;
left:0;
right:0;
}
</style>
<div class="parent">
<div>
<h1>
This is a normal div.
This text is visible
</h1>
</div>
<div class="fullwidth">
<h1>
This is a full width div.
</h1>
</div>
<div class="normal-div">
<h1>
This is a normal div
This text is hiding behind fullwidth div
</h1>
</div>
</div>
In this example, the second normal div is hiding behind the fullwidth div, because the fullwidth is absolute positioned.
So, how can you do this without having the divs hide behind the fullwidth div?
You need to make two changes to the "normal div":
Position relative (the default is static)
Set z-index below that of the absolute positioned div
And one change to the absolute div (set its z-index below the "normal" div).
http://jsfiddle.net/gx4p2red/3/
.fullwidth
{
position:absolute;
left:0;
right:0;
/*Testing only*/
background-color: green;
z-index: 0;
}
/*Testing only*/
.normal-div
{
background-color:red;
position: relative;
z-index: 1;
}
I made this:
HTML:
<body>
<div id="header" >
</div>
<div id="main" >
</div>
<div id="footer" >
</div>
</body>
CSS:
body
{
margin:0px;
}
#header
{
width:100%;
background-color:black;
height:60px;
}
#main
{
width:300px;
border:1px dotted black;
margin:0 auto;
}
#footer
{
width:100%;
background-color:black;
height:40px;
position:absolute;
bottom:0px;
}
http://jsfiddle.net/VpwQQ/2/
But as you can see, the main div doesn't have a height.
Then I replaced my css by that:
body
{
margin:0px;
}
#header
{
width:100%;
background-color:black;
height:60px;
}
#main
{
width:300px;
border:1px dotted black;
position:absolute;
margin:0 auto;
bottom:60px;
top:80px;
}
#footer
{
width:100%;
background-color:black;
height:40px;
position:absolute;
bottom:0px;
}
http://jsfiddle.net/VpwQQ/1/
But then, the horizontal center doesn't work.
How can I do this design (div centered and that takes all the page in height between the header and footer with a 20 px magin) ?
I'm not sure what you're trying to do, but I'll give my explaination of what's going to happen with your code:
Your #main div doesn't have a height because it doesn't have a height CSS property, nor does it have any content.
You should add either a height: 100px or just add some content and you will see it gets a height.
The reason why I ask what you want to do is because you're not very clear as to what you want your final product to look like.
You're going to have another problem with the footer. If you use position absolute it sticks to the bottom at the moment. Set the height of the #main div to something ridiculously high and you'll see that when you have to scroll down the page the footer stays where it is. See http://jsfiddle.net/VpwQQ/3/
You should use position: fixed but this will keep it on the bottom of the WINDOW and not the DOCUMENT. So then you get into the problem of having to use Javascript in order to measure the document height and setting positions appropriately. Not sure what you're trying to do, but if you're just trying to lay out a website then use standard relative positioning to push the footer down naturally below the #main div.
Edit:
See http://jsfiddle.net/VpwQQ/4/ if you're just trying to set up a normal website layout.
If you want the footer to "stick" to the bottom of the page all the time then you will need to use position: fixed but I don't think this works across all browsers. See http://jsfiddle.net/VpwQQ/6/
Lastly, to get both footer and header to "stick" see http://jsfiddle.net/VpwQQ/8/
I added a div inside #main.
Main now has a 100% width.
Inside, put a div of 300px, with no absolute position.
I forked your fiddle: http://jsfiddle.net/8U9P6/
Personnally I prefer the javascript solution and not using the absolute position. But this solution seems to work.
Add and overflow to contain the content in the inside div: http://jsfiddle.net/M2nZc/
Note that the page will not grow as it is absolute position.
You can't use automatic margins on an absolutely positioned element, as it's not in the document flow any more.
Use width: 100% on the #main div, then put another element inside it that you center using automatic margins.
Demo: http://jsfiddle.net/Guffa/VpwQQ/9/
Note: You may need to use height: 100% on the body and html elements for the bottom sizing to work on the #main element.
Once you fill your #main div with content, it will automatically gain height according to the content. You can simply fill it with a few paragraphs of lorem ispum to simulate content. You can now remove the absolute position and positioning CSS.
Centering a div using the "0 auto" shorthand only works when the parent element (which, for the #main div, is the body element) has a defined width. To do this, try giving your body element a width of 100%. Doing this is something that you might want to make a habit of in you CSS.
To have your #main div always be 20px below the #header div, simply add 20px of margin-bottom to your #header div. Do the same below the #main div to space the footer.
Summed up (without the footer at the bottom, for now) your CSS might read something like this:
body {
width: 100%
margin: 0px;
}
#header {
width: 100%;
height: 60px;
margin-bottom: 20px; /*here we space the header 20px from the next element*/
background-color: black;
}
#main {
width: 300px;
margin: 0 auto 20px auto; /*we append the margin to include 20px of spacing at the bottom*/
border:1px dotted black;
}
#footer {
width:100%;
height:40px;
background-color:black;
}
Example: http://jsfiddle.net/WEx3j/
If you want the footer to be 'sticky' (always be at the very bottom of your website), I advise you to employ this method.
I hope this clarified a few things.
Boxes are some objects(button, label, textarea). Green's size is dynamic. Especially I have a problem with the blue box stick to bottom.
Place a holder around it and it will take the height from the 'green' one, and give them only absolute and bottom 0, it won't matter what width you give your elements.
Edit: hopefully this works for you, with floating the elements, the green one to the right, and the rest left.
<div id="divHolder">
<label id="red">Label</label>
<button id="blue">Button</button>
<div id="green">
a
</div>
<br class="clearFloat" />
</div>
#divHolder {
width:300px;
position:relative;
}
#green {
height:300px;
background-color: green;
float:right;
}
#red {
background-color:red;
float:left;
position:absolute;
}
#blue {
background-color: blue;
bottom: 0;
position:absolute;
}
.clearFloat {
clear:both;
}
check it out here:
http://jsfiddle.net/YA9yD/32/
Here's my solution →
The main problem here is that the left-hand column doesn't know how tall the right-hand column is.
You can put them in a parent together (which will wrap both columns), but the left-hand column will not know the height of the parent because a child element can only expand to the height of a parent element if the parent element's height is explicitly set.
Also, there are two distinct columns here, so I wanted to try and group them as close to the way they appear as possible. Putting the left column inside the right column (the green box) doesn't accurately represent how this is structured.
HTML:
<div id="container">
<div id="labelDiv">
<label>I'm a label.</label>
<p>Text area, whatevs.</p>
</div>
<button>Hello</button>
<div id="greenBox">
<p>Green box text.</p>
</div>
</div>
CSS:
#container {
width: 610px;
overflow: hidden;
position: relative;
}
#labelDiv {
width: 300px;
float: left;
}
button {
position: absolute;
bottom: 0;
left: 0;
}
#greenBox {
width: 310px;
float: left;
}
So everything on the left (other than the button) is floated left, and the green box is also floated left. Great so far, but the the button needs to know how tall the entire box is so that it can attach itself to the bottom. So, we set overflow to hidden on the outer container so that it wraps around the floated elements, and absolutely positioning the button to the bottom of this aligns it exactly with the bottom of the tallest inner element (the green box).
I'd also recommend setting some margin-bottom on #labelDiv so that it doesn't cover up the button.
See example of the following →
As long as the blue and red widths are specified, you could use relative and absolute position as follows:
<div id="green">
<label id="red">Label</label>
<button id="blue">Button</button>
</div>
#green {
position:relative;
}
#red {
width:100px;
position:absolute; left:-110px; top:0px;
}
#blue {
width:100px;
position:absolute; left:-110px; bottom:0px;
}