I have a layout with a content column and a sticky sidebar. Scrolling down the page I need to stop the sidebar at the end of the content column.
Here the HTML and CSS I'm using:
<div class="container">
<div class="content">Content</div>
<div class="sidebar">Sidebar (sticky)</div>
<div style="clear:both"></div>
</div>
.content{
float: right;
width: 80%;
margin-left: 20%;
}
.sidebar {
float: left;
width: 20%;
position: -webkit-sticky;
position: sticky;
bottom: 30px;
}
Also on https://codepen.io/anon/pen/awNorj
Where I'm wrong?
Your initial problem is that css tricks work fine for top elements but not for bottom elements. Because tricks rely on the top-left corner position. To do so with the bottom-left corner, you'd need to know the height of your sidebar.
With sticky top element, you could just:
put your sidebar div first
then your content div
finally set your sidebar float:left so the container adjusts its height to the content
Demo: https://jsfiddle.net/1owyqtcn/1/
With sticky bottom element, the float:left trick does not work: it will get your sidebar overflow the container at the bottom.
Demo: https://jsfiddle.net/d1byrhp6/4/
If you don't know the height of your sidebar.
An approach can be to use the negative margin-left trick: you put the sidebar div into the content div and display it outside. Both sidebar and content are now aligned. But the sidebar leaves blank space in the content.
.content{
background: purple;
width: 80%;
margin-left: 20%;
}
.sidebar {
position: sticky;
width: 25%; /* Adjust: 25% of 80% of container is 20% of container */
background: #ff6347;
bottom: 30px;
margin-left: -25%;
}
Demo: https://jsfiddle.net/zg9g3134/
If you know the height of your sidebar.
Another approach is to suppress the height with a negative margin-top trick, instead of a float: left.
.content{
background: purple;
width: 80%;
margin-left: 20%;
}
.sidebar {
height: 200px;
overflow-y: hidden;
margin-top: -200px;
position: sticky;
width: 20%;
background: #ff6347;
bottom: 30px;
}
Demo: https://jsfiddle.net/rLs8dLba/2/
Related
I have four DIVs :
The first div has a fixed height and located on top (header).
The second div also has a fixed height and located below the first div.
The fourth div has a fixed height located on bottom.
The third div will have a variable height: it will expand to make the total of four divs are full to vertical space in browser IF the content is less than that. But it will follow the content's height if the content's height is larger than that. So at all times, I want the first div (the header) to stick at the top of the page, and the fourth div (the footer) to stick at the bottom of the page. I have no way to know how tall the content will be.
header
header
header
header
the CSS file:
#container { width:800px; height:*; }
#header { height:200px; }
#menu { height:50px; }
#content { height:*; }
#footer { height:150px; }
can I actually do this? how is the correct css way to do this? I get the feeling this should be not too hard, but I can't find relatable answers anywhere. Thank you.
What you could do is something like this:
#content { height: 100vh; /*100% of viewport height*/
margin-top: 250px;
margin-bottom: 150px; }
This way it will always be 100% of the screen height in total.
Well that turned out looking cool, JSBin
HTML
<div class="header">Header !</div>
<div class="menu">Menu !</div>
<div class="content">Content !</div>
<div class="footer">Footer !</div>
CSS
body { margin: 0; }
.header { width: 100%; height: 200px; position: fixed; top: 0; }
.menu { width: 100%; height: 50px; position: fixed; top: 200px; }
.footer { width: 100%; height: 150px; position: fixed; bottom: 0; }
.content { width: 100%; position: fixed; top: 250px; bottom: 150px;
overflow: auto; }
I'm trying to achieve a particular layout for a website I'm working on, but I'm not sure how to about it. The layout will look like this:
The header has nothing special about it. The footer has position: fixed and bottom: 0px. The main body content needs to be centred vertically within the space from the bottom of the header down to the top of the footer. If the window height is adjusted, the body content should remain centred between these two points. Also note that the website will be responsive, but only from 960px up to about 1600px (so the minimum width it will ever be is 960px).
My only idea on how to achieve this is to have the div containing the body content somehow automatically expand to always be the full height from the bottom of the header down to the bottom of the browser window (and then add some padding at the bottom to account for the footer), then use display: table on this containing div, and use display: table-cell and vertical-align: middle on a child div.
Are there any other (preferably CSS-only) ways I could potentially do this? If not, how can I get the containing div for the body content expand to always be the full height from the bottom of the header down to the bottom of the browser window?
Here is one solution, for a header with a fixed height.
Your HTML needs to have the following pattern:
<div class="header">Header</div>
<div class="main-wrap">
<div class="container">
<div class="content">Content...</div>
</div>
</div>
<div class="footer">Footer</div>
and the CSS:
html, body {
height: 100%;
}
body {
margin: 0;
}
.header {
height: 50px;
background-color: beige;
}
.main-wrap {
position: absolute;
top: 50px;
bottom: 50px;
width: 100%;
background-color: silver;
overflow: auto;
}
.container {
display: table;
height: 100%;
width: 100%;
}
.content {
border: 1px solid blue;
display: table-cell;
height: 100%;
width: 100%;
vertical-align: middle;
}
.footer {
height: 50px;
width: 100%;
background-color: lightblue;
position: fixed;
bottom: 0;
}
See demo at: http://jsfiddle.net/audetwebdesign/aGTKs/
It is possible to adapt this to a header of flexible height.
The .main-wrap container defines the space between the header and footer.
The .container block uses display: table and inherits the height from .main-wrap.
Finally, .content uses display: table-cell, which allows you to use vertical-align: middle (default value) to center the content vertically.
You need to set the height of body and htmlto be 100% to capture the height of the view port.
You can hack it by doing {position: absolute; bottom: 0} !
I have what is a fairly common page layout where the content div is centralised on the page using margin:auto 0. The width of the div itself varies depending on available page width.
I want another div featuring a logo to 'stick' to the outside left hand side of this div (ie no gap or overlap between the two) at a fixed height. What CSS should I use for this?
something like
html:
<html>
<div id='content'>
<div id='stickything'>a</div>
</div>
</html>
css:
html {
width: 100%;
}
#content {
position: relative;
width: 100px;
height: 600px;
margin: auto;
background-color: green;
}
#stickything {
position: fixed;
width: 25px;
height: 30px;
top: 0px;
margin-left: -25px;
background-color: red;
}
http://jsfiddle.net/Kkcnn/
Use position:absolute. It must help:
.container-div{
position: relative
}
.outer-div{
position:absolute;
top: 0 (your choice)
left: -/outer div's width/
}
I've 3 divs, each of them has position: absolute.
First is header, and its working.
Header has constant height, and second div "content" also works.
Third div is "footer".
"Content" has changeable height and when "content" is higher than web-browser window the "footer" is ON "content". I want to "footer" under "content" irrespective of content height.
My header is 300px height, content has margin-top: 300px. I can't use the same for the footer, because content hasn't got constant height.
I don't want to set one div with position: absolute, and these 3 divs place inside this one.
div#header{
width: 960px;
height: 200px;
left: 50%;
margin-left: -480px;
position: absolute;
}
div#content{
width: 960px;
border: 1px solid black;
left: 50%;
margin-left: -480px;
position: absolute;
margin-top: 200px;
}
div#footer{
width: 960px;
height: 30px;
left: 50%;
margin-left: -480px;
position: absolute;
bottom: 10px; /*with this i've div fixed to the bottom of web-browsers' window */
clear: both;
}
You're over positioning.
You do not need to position everything absolutely unless there's something you aren't sharing.
JSBin Example
If you are willing to use position : relative which is a tad better than position : absolute in cases like this, http://jsfiddle.net/vFTXg/1/ - Try editing the value of your content's height here and your footer will be automatically adjusted.
CSS
.header {
position : relative;
width : 100%;
height : 90px;
background-color : #000;
}
.content{
position:relative;
width : 100%;
min-height : 200px;
background-color : #f00;
}
.footer{
position:relative;
width : 100%;
height : 50px;
background-color : #0f0;
}
HTML
<div class='header'></div>
<div class='content'></div>
<div class='footer'></div>
I would recommend using CSS floats
Do something like this:
<div id="wrapper">
<div id="header">...</div>
<div id="content">...</div>
<div id="footer">...</div>
<div class="clear"></div>
</div>
Set the site-width on the wrapper and let the other divs have the same width.
Use float:left on header, content and footer
Set clear:both on the clear-div.
Now you can set the height on the elements you want to have a fixed hight - and you don't have to bother with absolute positioning.. If you insist on using positioning, you could just position the wrapper.
In the future browser can calculate. For your example this could be nice to calculate the min-height for the content to set the foorter to the bottom if content height is low and to set the footer after the content if it has a heigh value. E.g.:
HTML:
<div id="header" class="content">header</div>
<div id="content" class="content">content</div>
<div id="footer" class="content">footer</div>
CSS:
html, body {
height: 100%;
}
.content {
position: relative;
width: 960px;
}
#header {
height: 200px;
}
#content {
border: 1px solid black;
min-height: -moz-calc(100% - 302px);
min-height: -webkit-calc(100% - 302px);
min-height: calc(100% - 302px);
}
#footer {
height: 100px;
}
Unfortunately only firefox and IE9 and higher support calc at the moment, so this is more theoretically. If you want to test it, see this jsfiddle.
If you want to do this with all current browser you need to use javascript.
If you want something to be of constant width and centered try this
#footer,
#header,
#footer {
width: 960px;
margin: 0 auto;
}
and forget about
left: 50%;
margin-left: -480px;
position: absolute;
I am trying to align vertically a modal box. But the margin-top:50% did not work as i expect. Basically i want a square centered on another square.
<style type="text/css">
#modal {
width: 300px;
height: 300px;
z-index: 100;
background-color: red;
margin: 0 auto;
position:relative;
margin-top:50%; //problem here
}
#content {
position: absolute;
width:950px;
height: 950px;
margin: 0 auto;
background-color: green;
}
#replace {
width:950px;
height:500px;
}
</style>
<div id="replace">
<div id = "content"></div>
<div id="modal"></div>
</div>
thanks
demo
Instead of margin you need to use top:325px; for #modal
If it's not too much trouble to have the modal inside the content div, you might want to try this HTML:
<div id = "content">
<div id="modal"></div>
</div>
...with this CSS:
#modal {
width: 300px;
height: 300px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -150px;
}
#content {
position: absolute;
width: 550px;
height: 550px;
background-color: green;
}
Demo
Basically you're absolutely-positioning the modal div inside the content div, and telling it to go start at 50% from the top and 50% from the left. This will center the top-left corner of the modal, but not the div as a whole. To center the div as a whole, you then have to add a negative margin to move it back up and to the left. The amount of the negative margin is half the height/width of the modal div.
If you want to keep the same HTML, you can still accomplish the same thing using this technique, just make sure to do position: relative on your replace div so that any absolutely-position children are positioned relative to it.
Add position: relative; to your container if you want absolutely positioned elements inside it to be positioned relative to it:
#replace {
position: relative;
width: 950px;
height: 500px;
}
Then set to top value of the item you want to position. One thing to note here, your #replace div is the container here, but it's smaller than the #content div, so when you position #modal, you're going to have to give it specific pixel values to get it centered over #content.