Two full height column layout with sticky footer using pure CSS - sticky-footer

I am struggling which seems to be a rather simple challenge.
I need to design simple layout which requirements are:
pure CSS (no flex-box, no grid, just CSS - no libraries)
fixed body/wrapper width (1024px, centered)
fixed column width
columns stretched 100% height, even if there is no content
sticky footer (bottom attached)
tabels can't be used
I came across a lot of answers here on Stack overflow, but nothing seems to work fully like I want.
Here is the scheme:

This is what I came up so far:
body {
height: 100%;
background-color: #FFF;
}
.wrapper {
overflow: hidden;
margin: 0 auto;
height: 100%;
width: 1024px;
background-color: #000000;
}
.header {
padding: 10px;
background-color: #33cc33;
height: 100px;
}
.col-left {
padding: 10px;
float: left;
height: calc(100vh - 174px);
width: 300px;
background-color: #ff0066;
}
.col-right {
padding: 10px;
float: left;
height: calc(100vh - 174px);
width: 684px;
background-color: #0066ff;
}
.footer {
padding: 10px;
background-color: #99ff33;
height: 50px;
position: absolute;
bottom: 0;
width: 1004px;
}
<div class="wrapper">
<div class="header">
<p>test</p>
</div>
<div class="col-left">
<p>test</p>
<p>test</p>
<p>test</p>
<p>test</p>
<p>test</p>
<p>test</p>
</div>
<div class="col-right">
<p>test</p>
</div>
<div class="footer">
<p>test</p>
</div>
</div>
Code on JSFiddle:
https://jsfiddle.net/adorek/8kecq9pw/22/

Try adding position: relative to the parent element of the footer. position: absolute needs this as a reference point.

Related

Position sticky not working for horizontal scrolling when element width increases

I am trying to keep an element from scrolling past left: 0 using position: sticky. This works fine in some cases, but I have noticed that if the element width increases it stops working. For example, the following works:
#header {
position: sticky;
left: 0;
width: 50%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
But if I increase the witdth of header element to 100% it stops working.
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
Why does this happen? And is there any way to use position: sticky to prevent the header element from scrolling when it's width is 100%? I prefer not to use position: fixed in this case.
I now understand what is happening. The issue is the different way the browser treats the width and height of a <div>. The default values of auto mean that the width of the <div> is 100% while the height is set by the content. If the content is wider than 100%, then on horizontal scroll the sticky element hits the end of the container <div> and, since it cannot leave the confines of the container, begins to scroll. This doesn't happen in the same situation for vertical scrolling since the container <div> is as tall as the content by default.
To prevent this happening, we have to ensure that the container <div> is as wide as its content. This can be done in most browsers (not Edge or Explorer) by including width: max-content in the container style. Alternatively, as proposed in mfluehr's answer, putting overflow: auto creates a new block formatting context that is as wide as the content. Another option is to use display: inline-block or inline-flex etc. to cause the container <div> to base its width on the content.
For example, using two of these techniques, you can create headers, sidebars and footers that stick for a page that can scroll vertically and horizontally:
body {
padding: 0;
margin: 0;
}
#app {
overflow: auto;
height: 100vh;
}
#header {
background: blue;
width: 100%;
height: 40px;
position: sticky;
top: 0;
left: 0;
z-index: 10;
color: white;
}
#sidebar {
position: sticky;
background: green;
width: 200px;
height: calc(100vh - 40px);
top: 40px;
left: 0;
color: white;
flex-grow: 0;
flex-shrink: 0;
}
#container {
display: inline-flex;
}
#content {
background: #555;
height: 200vh;
width: 200vw;
background: linear-gradient(135deg, #cc2, #a37);
flex-grow: 0;
flex-shrink: 0;
}
#footer {
background: #000;
height: 100px;
z-index: 100;
left: 0;
position: sticky;
color: white;
}
<div id="app">
<div id="header" ref="header">
Header content
</div>
<div id="container">
<div id="sidebar" ref="sidebar">
Sidebar content
</div>
<div id="content" ref="content">
Page content
</div>
</div>
<div id="footer" ref="footer">
Footer content
</div>
</div>
This is an interesting problem. I don't know why, but putting overflow: auto on the container around the <div>s seems to fix the issue.
You can add height: 100vh to the container to let the content inside overflow with scrollbars.
body {
margin: 0;
}
#container {
overflow: auto;
height: 100vh;
}
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 200vh;
width: 120vw;
background: linear-gradient(135deg, #cc2, #a37);
}
<body>
<div id="container">
<div id="header">
This is the header.
</div>
<div id="page">
Page content goes here.
</div>
</div>
</body>

Page changes when clicking a div link

I will explain my problem.
For school I have to make a website, but it is not working how it should be.
I have a border made of divs around the screen, and the page in the middle. When I first open the page, everything is in place, but when I click on one of the nav items (#link) the page suddenly loses its margin top and left. So it goes outside of the borders. I pasted all the code in the snippet, as I believe it will be too much for a post.
To see the full page and problem, please copy the code in a file to open it in the browser itself. I used vw and vh because it want it to be the same on different screens. I will do the inside elements mostly with percentages
So my questions:
How do I prevent this from happening, and an example?
Is there a way to set #Home as the usual landing space? without adding #Home in the link (and without changing its position)?
And my last question regarding CSS animation, how do I add a transition so it looks like the page is scrolling to the #div.
body{
top: 0;
margin: 0;
padding: 0;
left: 0;
}
.wrapper{
width: 100vw;
height: 100vh;
overflow: hidden;
}
.container{
width: 300vw;
height: 200vh;
background-image: url("../img/background.png");
background-size: cover;
}
/* simple nav*/
ul{
display: inline;
z-index: 99;
position: fixed;
}
ul li{
list-style-type: none;
display: inline;
}
ul li a{
text-decoration: none;
}
/*pages*/
.page{
margin: 10vh 10vw;
width: 80vw;
height: 80vh;
transition: 2s;
}
#Interactive{
background: blue;
float: left;
}
#Graphical{
float: left;
}
#Company{
float: left;
}
#Conclusion{
float: left;
}
#Home{
float: left;
}
/*header borders*/
.borders{
position: fixed;
z-index: 30;
}
.border-top{
height: 10vh;
width: 100vw;
top:0;
background: #007CFF;
}
.border-left{
height: 100vh;
width: 10vw;
top: 0;
background: #007CFF;
position: absolute;
}
.border-right{
height: 100vh;
width: 10vw;
top: 0;
background: #007CFF;
float: right;
margin-top: -10vh;
}
.border-bottom{
height: 10vh;
width: 100vw;
bottom: 0;
background: #007CFF;
position: absolute;
}
<div class="header">
<ul>
<li>Home</li>
<li>Interactive</li>
<li>Graphical</li>
<li>Company</li>
<li>Conclusion</li>
</ul>
</div>
<div class="borders">
<div class="border-top">
</div>
<div class="border-left">
</div>
<div class="border-right">
</div>
<div class="border-bottom">
</div>
</div>
<div class="wrapper">
<div class="container">
<div id="Interactive" class="page">
</div>
<div id="Graphical"class="page">
</div>
<div id="Company"class="page">
</div>
<div id="conclusion"class="page">
</div>
<div id="home"class="page">
</div>
</div>
</div>
Thanks for thinking with me, any help is appreciated.
I didn't really know how to call this post, so the search for it was difficult.
Please remove this div
#Interactive{
background: blue;
float: left;}
I think this only you are expecting.
I have made changes to your HTML code and CSS code on the basis of what i thought you wanted to achieve. Below is the code.
* {
padding: 0;
margin: 0;
}
body{
display: flex;
flex-direction: column;
}
.header {
padding: 10px 50px;
}
ul li{
list-style-type: none;
display: inline-block;
padding: 10px;
}
.wrapper {
flex-grow: 1;
padding: 50px 150px;
}
.page{
transition: 2s;
width: 100%;
height: 100%;
}
#Home{
background-color: pink;
}
#Interactive{
background: blue;
}
#Graphical{
background-color: green;
}
#Company{
background-color: yellow;
}
#Conclusion{
background-color: orange;
}
<div class="header">
<ul>
<li>Home</li>
<li>Interactive</li>
<li>Graphical</li>
<li>Company</li>
<li>Conclusion</li>
</ul>
</div>
<div class="wrapper">
<div id="Home" class="page">
</div>
<div id="Interactive" class="page">
</div>
<div id="Graphical" class="page">
</div>
<div id="Company" class="page">
</div>
<div id="Conclusion" class="page">
</div>
</div>
If you want to use transition for smooth scrolling. Refer to
this
article, you will have to use jQuery.
Also do not use fixed width or height until necessarily required.
Use document.getElementById('Home').focus() in document.ready() of js to bydefault show the Home Page.
Always focus on making responsive solutions with relative content rather than absolute content.
Let me know if you need more help :)

One page website basic layout

I have the following layout for my onepage site, I've never made one before so it is very much a learning curve.
The only issue I can currently see with this is when I shrink the height of the page, the div size also shrinks, even when I add min-height: 800px;. What can I do to get around this issue? (If I didn't explain this properly, use my code and shrink the height of your page so you can only just see the background-colors, then scroll, you will notice that in fact, the height is not 800px),
div.top,
div.mid,
div.bottom {
height: 100vh;
min-height: 800px;
width: 100%;
position: absolute;
left: 0;
right: 0;
}
div.top {
background-color: red;
top: 0;
}
div.mid {
background-color: blue;
top: 100vh;
}
div.bottom {
background-color: yellow;
top: 200vh;
}
<div class="top">
<h1>Top</h1>
</div>
<div class="mid">
<h1>Mid</h1>
</div>
<div class="bottom">
<h1>Bottom</h1>
</div>
EDIT: To explain why I am using position: absolute
I use position: absolute so that I am able to use top left and right so that I don't have the margin around each div.
Without absolute
With absolute
body {
margin: 0;
}
.top, .mid, .bot {
height: 100vh;
min-height: 800px;
width: 100%;
}
.top {
background: red;
}
.mid {
background: blue;
}
.bot {
background: green;
}
<div class="top">
<span>top</span>
</div>
<div class="mid">
<span>mid</span>
</div>
<div class="bot">
<span>bot</span>
</div>
Your 'margin' is coming from the H1 tag, removed that and the gap disappears from between the divs. I've removed the absolute positioning and left / right / top values because they are redundant with the removal of the margin:
div.top,
div.mid,
div.bottom {
height: 100vh;
min-height: 800px;
width: 100%;
}
h1 {
margin-top: 0;
}
div.top {
background-color: red;
}
div.mid {
background-color: blue;
}
div.bottom {
background-color: yellow;
}
<div class="top">
<h1>Top</h1>
</div>
<div class="mid">
<h1>Mid</h1>
</div>
<div class="bottom">
<h1>Bottom</h1>
</div>

getting floating divs to width inside an absolute positioned container container

So I'm working on some html/css stuff
I can't seem to get these two floating div's and the footer to be correctly sized inside the parent div.
the content div is positioned absolutely to get header and footer to show respectively.
HTML:
<div id="Content">
<div id="Header">header</div>
<div id="Container">
<div id="leftTable">
<div>left content</div>
</div>
<div id="rightTable">
<div>right content</div>
</div>
</div>
<div id="Footer">
<div>footer</div>
</div>
</div>
CSS:
html, body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
#Content {
padding: 0 15px;
height: 100%;
background-color: honeydew;
position: relative;
height: 100%;
}
#Header {
height: 60px;
background-color: aliceblue;
}
#Footer {
position: absolute;
bottom: 0;
background-color: purple;
height: 70px;
}
#Container {
background-color: green;
position: absolute;
top: 60px;
bottom: 70px;
margin-right: 15px;
}
#Container:after {
clear:both;
}
#leftTable {
float: left;
width: 50%;
height: 100%;
background-color: grey;
}
#rightTable {
float: left;
width: 50%;
background-color: blue;
}
http://jsfiddle.net/4CabB/12/
I was hoping to no position the Container div or footer div on the left and right sides and just have it take up the remaining space.
I'm a bit unclear as to what needs to be achieved, but perhaps this solves your issue: JSFiddle.
Essentially, I just needed to add
width: 100%;
to your container to allow its children to take up the space. Parent containers, when absolutely positioned, must have their widths specified.

Centered fixed/anchored footer?

I've looked at some questions posted here but everything seems overly complicated for what should be such a simple task? I just want a footer that stays fixed at the bottom of the screen no matter how long the page is vertically. Everything works, except I can't get the footer centered, it always aligns left..? Thanks! http://jsfiddle.net/n4xxj/
<body>
<div id="content"></div>
<div id="footer"></div>
</body>
div {
width: 960px;
margin: auto;
}
#content {
background-color: beige;
border: 1px solid;
height: 1200px;
margin-top: 100px;
margin-bottom: 150px;
}
#footer {
background-color: lightgray;
border: solid 1px;
height: 100px;
position: fixed;
bottom: 0px;
}
Update your HTML to wrap in a wrapper div
<div>
<div id="content"></div>
<div id="footer"></div>
</div>
DEMO
Here you go, you will need to encapsulate the interior div's into a big #container div and add to it margin: 0 auto; to align it.
Please note for a complete fix you should also add this (it's a simple IE fix):
body { text-align: center; }
#container { text-align: left; margin: 0 auto; }
And of course the #footer will need to have width: 100%;
Also the fiddle:
http://jsfiddle.net/n4xxj/3/