I have an element (in my case a HR tag) that needs to be as wide as the browser but which is also wider than it's parent container. However, it still needs to maintain relative positioning so that it scrolls vertically with the page. The problem is that my parent div has to have relative positioning as well (due to other layouts that are working).
The only way I have been able to solve this is to set the width of the HR tag to 3000px with a left position of -1000px. This works, but it adds a horizontal scrollbar to the page (to display the 3000px width). Is there any way to accomplish this cleanly (without the horizontal scroll bar)? You can see my fiddle at http://jsfiddle.net/UGwst/.
Here's the HTML:
<div id="layout-wrapper">
<p>Above Content</p>
<div id="content-wrapper">
<p>Top Content Here</p>
<hr class="rule" />
<p>Bottom Content Here</p>
</div>
</div>
Here's the CSS:
#content-wrapper {
width: 400px;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
background-color: #ddd;
position: relative;
}
.rule {
background-color: #dbb328;
height: 5px;
position: relative;
left: -1000px;
width: 3000px;
}
I realize that there are a couple of other questions here that are similar, but don't quite seem to fix this issue.
Use position:relative on the parent.
Use position:absolute on the HR, that way the HR is bound to the parent and will scroll with it.
To hide scroll bars use overflow:hidden on your outer wrapper, or BODY.
Try
body {overflow-x: hidden;}
to eliminate the horizontal scrollbar. According to this answer, it even works in IE6 - CSS - Only Horizontal Overflow?
Related
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'm trying to publish my portfolio site and I'm almost done, but I'm having a problem with my sticky footer covering content when there's enough content to need to scroll down. I've tried messing with padding and margins all afternoon but I still can't seem to get it the way I want it.
Basic HTML skeleton:
<body>
<header>
<nav>
</nav>
</header>
<div id="wrapper">
<section>
<ul id="gallery">
<li>
</li>
</ul>
</section>
</div>
<footer>
</footer>
</body>
Footer:
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
font-size: 0.425em;
text-align: center;
clear: both;
padding-top: 10px;
color: #ccc;
border-top: 5px solid #cc7a00;
}
Any help would be appreciated!
After inspecting the HTML on the page you mentioned above, it looks like you might have some un-cleared floats. You can read more about floats and why they need to be cleared here: https://css-tricks.com/the-how-and-why-of-clearing-floats/.
The short answer is the wrapper isn't increasing its dimensions to encompass its children because of those floats. If you inspect your page using dev tools, you can see the wrapper essentially has no height. That means adding a margin to it isn't really going to do anything.
If you were trying to add margin and padding to the footer itself, that won't work either since you're using position:fixed. You've told it to stick to the bottom of the page and not affect the other content on the page. It wouldn't make sense to let content scroll underneath the footer and still let it have a margin that pushes away other content, right?
There are a bunch of ways to solve this problem. Here's one-
To solve your float problem, you can use the overflow:auto trick:
#wrapper {
overflow:auto;
}
Read more about overflow:auto and floats here: Why does 'overflow: auto' clear floats? And why are clear floats needed? Please note this doesn't really clear the floats but the effect is that the wrapper height will respond to its children which is what we really need here.
Then adding some extra margin on the bottom of the wrapper div to account for the height of the footer should work:
#wrapper {
overflow:auto;
margin: 0 auto 100px auto;
}
The margin property above sets the margin-top to 0px, margin-right to auto, margin-bottom to 100px, and margin -left to auto. I suggested this becuase the page you linked to already had margin: 0 auto; (margin top and bottom 0, and margin left and right auto) to center the wrapper in the page. Otherwise, if you only needed to adjust the space at the bottom you would use margin-bottom: 100px;
Try adding
padding-bottom: 97px;
to your HTML element
EDIT
html { padding-bottom: 97px; }
97px is the height of your footer.
On your <div id="wrapper"> add to the CSS: bottom : someValueMatchingTheFooterHeight;
I've a fixed width <div> positionned inside the body element with float:right. When I resize the window and the width of the <div> is below the width of the window no scrollbar appears.
HTML
<body>
<div>Some text content inside.</div>
</body>
CSS
div{
background : blue;
width : 400px;
float : right;
}
It's the same if I change float:right by position:absolute; right:0;.
If I add body{overflow:auto;} it's still the same.
My questions are : Why this behavior? and How can I change it?
http://jsfiddle.net/Sk7Qh/
You can never scroll further to the left than the left edge of the document (or further up then the top edge).
Content, however, can be positioned there.
This is what is happening and you can't change it.
The closest you could come would be to set a minimum width on a containing element so that the content is never positioned off the left or top edges.
e.g.
body {
position: relative;
min-width: 300px;
}
Update after comment from OP:
Then you just use an outside box around your div
<div id="outside">
<div id="inside">
Text
</div>
</div>
And CSS:
#outside {
max-width: 100%;
overflow-x: auto;
float: right;
}
#inside {
background:blue;
width: 300px;
}
See http://jsfiddle.net/Sk7Qh/6/
Better?
So. My code is something along the lines of
<html>
<body>
<div id="header" style="width:100%;min-height:0;display:block;background-color:#000">
<img src="header_image.svg" />
</div>
<div id="content" style"display:block">
Some content
</div>
</body>
</html>
I have an svg in the header that I have set so that it matches the width of the window and the height scales to preserve the svg. Then I have the rest of the page in another div. I would like it so that the page doesn't scroll and this content div fills to fit the rest of the window. The problem is that since the height of the header changes with the width of the window, I can't set the content div in pixels or percentage or anything concrete.
How can I set the height of the content div to change dynamically with the height of the header?
I don't know Javascript or JQuery (I know, I know - I should), but ideally the height of the content div would be set to be something like height:(height of viewport)-(height of header), but I haven't a clue how to do this.
you don't have to use a script for that.
and also: I recommend you to separate your styling from your markup.
HTML
<div id="wrapper">
<div id="header">
<img src="header_image.svg" alt="the img is empty"/>
</div>
<div id="content">Some content</div>
</div>
add this to your CSS
html, body {
height: 100%;
margin: 0px;
}
/* this is the big trick*/
#wrapper:before {
content:'';
float: left;
height: 100%;
}
#wrapper {
height: 100%;
background-color: black;
color: white;
}
#header {
background-color:#000;
}
#content {
background-color: gray;
}
/* this is the big trick*/
#content:after {
content:'';
display: block;
clear: both;
}
Working Fiddle
Tested on: IE10, IE9, IE8, FF, Chrome.
didn't use absolute positioning
didn't use Script (Pure CSS solution)
fluid layout
cross-browser
Explanation:
with pseudo element, I'm creating a floating element (without content or width, so he's invisible)
that has 100% of the container height.
and with another pseudo element I'm creating a div just after the content div. (also without content, so he's also invisible) that has the clear attribute. so he has to be below the floated one I've created earlier. making the content to go all the way down.
Can anyone help me with position my content block?
It looks good if there are a lot of content, but not when window higher than content block.
Actualy I need that "content" block on my picture teked all free space (height) and thats why footer stick to the bottom.
I have next HTML markup:
<div>
<header></header>
<nav class="breadcrumbing"></nav>
<section class="left_nav"></section>
<section class="content"></section>
<footer></footer>
</div>
With this CSS:
html,body{width:100%;margin:0;padding:0;}
body{background-color:#629302}
body>div{width:400px;height:100%;margin:0 auto;background-color:#FFF;}
body>div>header{height:50px;background-color:#9dc155}
body>div>nav.breadcrumbing{display:block;height:10px;margin:0;padding:0;}
body>div>section.left_nav{width:172px;margin:8px 20px;float:left;background-color:#cdef88}
body>div>section.content{width:168px;float:left;}
body>div>footer{padding:19px 19px 22px;background-color: #e58b04;clear:left;}
I allready tried answers from Is it possible to get a div's height to be 100% of an available area? and some same questions but with no luck.
ALso my live HTML has backgroun-images, so I can't just put footer to the bottom with position:absolute.
There I post my HTML to preview: jsfiddle.
UPD: scaled live preview:
You will have to set the html and body height property to 100%; then you can set the footer height to 100%; this will tell the main container elements the real meaning of 100% and it will work.
Your updated fiddle
Basically, these are the rules you have to add:
html, body {
height: 100%;
}
footer {
height: 100%;
}
Update
Ok, I might have misunderstood your requirements, here is a cleaner example:
Working example
Basically, what you additionally do in this example is having your wrapper element display:table with an height: 100%, then you make your footer display as table-row.
Important note: This solution uses display-table which is compatible only for IE8+. If supporting IE7 is an issue for you, then you have two solutions that I can think of out of my head:
Either you use a fixed-width footer, push it below the content and then pull it back with a combination of negative margin and padding.
Or you fallback to support of older browser by putting your footer in position using some javascript.
This the breakdown of the code:
HTML
<div class="wrapper">
<header></header>
<section class="main-content">
{child elements of your main-content area}
</section>
<footer></footer>
</div>
CSS
html, body {
height: 100%;
margin: 0;
}
.wrapper {
display: table;
margin: 0 auto;
height: 100%;
}
.main-content {
display: table-row;
height: 100%;
}
footer {
display: table-row;
}
Here's an updated fiddle
The crux of this is setting the body to be absolutely positioned to the viewport. From there, if you wanted to allow it to scroll as you normally would, then you would change the footer's position to fixed and the content div's CSS to this:
body>div>div{width:400px;height:100%;margin:0 auto;background-color:#FFF;
position:absolute; top: 0; bottom: 0; overflow-y:auto;}
I've wrapped your content div in another to allow for the automatic margins to center your page, and then defined the footer's box sizing as border-box to account for the padding you're adding to it as well.