I have a strange requirement for a web application (single page web app) in which the page shouldn't have a scrollbar. The header & footer stays sticky & the middle content part should adjust(keeping proportion) without scrollbar in any resolution. Following is a preview of the layout.
Live Demo - https://previewin.xyz/web/sree/layout/
CodePen Demo - https://codepen.io/DeCodeUI/pen/gZBXqa
CSS
header {
position: fixed;
width: 100%;
height: 50px;
background: #333;
z-index: 500;
left: 0;
top: 0;
}
footer {
position: fixed;
width: 100%;
height: 50px;
background: #333;
z-index: 500;
left: 0;
bottom: 0;
}
#content {
width: 80%;
height: 100vh;
padding: 60px 15px;
}
#grid {
max-width: 900px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
align-content: space-around;
}
.grid-item {
width: 300px;
height: 100px;
background: blue;
}
HTML Sample
<div id="page">
<header>Text</header>
<div id="content">
<div id="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</div>
<footer>Text</footer>
</div>
Those 9 grids in blue, always keep proportion in any resolution & no scrollbars. I have tried my best & the result is here - https://previewin.xyz/web/sree/layout/ but when the screen get smaller, the grids won't resize. Any ideas to solve this?
Just change the container width:100% and set max-width:1160px based on your requirement in your code. If you set width for container responsive and browser resize become problem. I hope this solution will work for you.
.container {
max-width: 1160px;
width: 100%;
}
header {
position: fixed;
width: 100%;
height: 50px;
background: #333;
z-index: 500;
left:0;
top: 0;
}
footer {
position: fixed;
width: 100%;
height: 50px;
background: #333;
z-index: 500;
left:0;
bottom: 0;
}
#content {
width: 80%;
height: 100vh;
padding: 60px 15px;
}
#grid {
max-width: 900px;
display: flex;
flex-wrap: wrap;
}
.grid-item {
width: 150px;
height: 100px;
background: blue;
margin: 10px;
padding:30px;
color:#fff;
text-align:center;
align-self: center;
}
<div id="page">
<div class="container">
<header>Text</header>
<div id="content">
<div id="grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
</div>
<footer>Text</footer>
</div>
</div>
Related
To keep things neat and short:
https://jsfiddle.net/m53ockLu/
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-x: scroll;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally? I'm totally out of ideas, I thought that overflow-x & overflow-y should do the trick, but no dice.
Thank you very much for any help.
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally?
No.
I tried Ethan's suggestion and couldn't get the purple box to visibly overflow the scrollbar:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-y: scroll;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
I don't think the browser will let you overflow the scrollbar, I even put z-index, explicitly said to visibly overflow, played around with the position property etc.
Consider this example of letting the content dictate the size:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: max-content;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
background: green;
}
.first {
display: block;
height: 20px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
You made the parent div sidebar have overflow-x: scroll;, overflow-y: auto;. Instead, make each child have its own overflow properties instead of the parent.
I'm in a bit of a pickle. Been searching and testing this out for a while but can't seem to get it it work.
Here's what I've got so far:
* {
box-sizing: border-box;
}
html, body {
margin: 0;
height: 100%;
font-family: Arial, sans-serif;
}
.container {
position: fixed;
top: 0;
right: 0;
height: 100%;
width: 30%;
background-color: #f9f9f9;
padding: 20px 30px;
}
.box-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
height: 100%;
overflow-y: auto;
}
.box {
display: flex;
justify-content: center;
align-items: center;
height: 150px;
width: 49%;
background-color: #FFDAC7;
margin-bottom: 5px;
font-size: 32px;
}
<div class="container">
<h2>lorem ipsum dolor sit amet</h2>
<h3>Some other stuff</h3>
<div class="box-container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
<h5>Maybe a button here</h5>
</div>
Now, I would expect the "box-container" div to only occupy 100% of the available space and having the children be scrollable but that doesn't seem to be the case.
Seems like I'm missing something obvious.
Here's a pen for those who prefer that, btw: https://codepen.io/georgiosApo/pen/gORxJwb
Thanks a bunch in advance for any pointers!
// G
Change you css like this:
.container {
height: 100vh;
width: 100%;
background-color: #f9f9f9;
padding: 20px 30px;
}
Working example
With my current code i have couple of problems.
The NavBar last item Menu Bottom is lower underneath the browser window, this is because of the headers height.
When scrolling and reaching the bottom, it still allows to scroll more because of that header then header bar disappears.
I'm sure I'm doing a poor job describing all this, but in nutshell:
The header needs to be always on top no matter of scroll position and it should not mess up other elements.
The contents from NavBar and Content page need to have their in-depended scrolling.
I'm sure I've tried a lot, using position fixed/sticky but i still cant get this right to work.
.main {
display: flex;
flex-direction: column;
}
header {
overflow: none;
position: sticky;
background-color: #af6363;
height: 70px;
width: 100%;
z-index: 30;
}
.container-content {
display: flex;
flex-direction: row;
}
.menu {
background-color: #6fc06c;
display: flex;
flex-direction: column;
height: 100vh;
min-width: 300px;
overflow: scroll;
position: sticky;
z-index: 10;
/* justify-content: space-between; */
}
.menu-item {
padding: 50px;
background-color: #5e9b79;
}
.menu-item_top {
flex-grow: 1;
}
.content {
/* position: relative; */
/* width: 100vmin; */
height: 100vh;
/* min-height: 100vh; */
overflow: scroll;
background-color: #9b5959;
}
.content-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 100px;
width: 100%;
}
.content-item {
width: 200px;
height: 200px;
padding: 50px;
background-color: #7c9cb6;
}
<div class="main">
<header>Header</header>
<div class="container">
<div class="container-content">
<div class="menu">
<div class="menu-item_top">
<div class="menu-item">Menu</div>
<div class="menu-item">Menu</div>
<div class="menu-item">Menu</div>
</div>
<div class="menu-item_bottom">
<div class="menu-item">Menu Bottom</div>
</div>
</div>
<div class="content">
<div class="content-container">
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
</div>
</div>
</div>
</div>
</div>
You were using viewport units which is a good practice but not everywhere if you're trying to achieve what you wanted, I left some comments on the css that was modified. Hope it's what you're looking for.
/*Fills height of the screen*/
body, .main {
max-height: 100vh;
overflow: hidden;
margin: 0;
}
.container {
max-height: 100%;
overflow: hidden
}
.main {
display: flex;
flex-direction: column;
}
/*Fills height of container*/
.container-content {
display: flex;
flex-direction: row;
max-height: 100%;
}
header {
position: sticky;
background-color: #af6363;
height: 70px;
width: 100%;
z-index: 30;
}
.menu {
background-color: #6fc06c;
display: flex;
flex-direction: column;
/*Would fill height of the screen not the container*/
/*height: 100vh;*/
min-width: 300px;
overflow: auto;
position: sticky;
z-index: 10;
}
.menu-item {
padding: 50px;
background-color: #5e9b79;
}
.menu-item_top {
flex-grow: 1;
}
.content {
/*Would fill height of the screen not the container*/
/*height: 100vh;*/
overflow: auto;
background-color: #9b5959;
}
.content-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 100px;
width: 100%;
}
.content-item {
width: 200px;
height: 200px;
padding: 50px;
background-color: #7c9cb6;
}
<div class="main">
<header>Header</header>
<div class="container">
<div class="container-content">
<div class="menu">
<div class="menu-item_top">
<div class="menu-item">Menu</div>
<div class="menu-item">Menu</div>
<div class="menu-item">Menu</div>
</div>
<div class="menu-item_bottom">
<div class="menu-item">Menu Bottom</div>
</div>
</div>
<div class="content">
<div class="content-container">
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
<div class="content-item">Content</div>
</div>
</div>
</div>
</div>
</div>
I am having a really difficult time trying to figure out why this is happening before I move further along in my development process of this page.
I have a very basic setup:
Fixed Footer
Fixed Header
A col-lg-3 nav bar
A col-lg-9 content box
The problem I am having is the div widths inside the nav col-lg-3 are not taking up the full width of the parent div. They appear to want to sit next to each other., even though I haven't declared a float -- and I have even tried clear:both between them. The div with ID of projects is supposed to be below the div with ID problem-div What am I doing wrong, or not understanding in order for this to happen?
NOTE The reason I am assuming this is a Bootstrap issue, is because if I remove the links to the CDN, the html / css functions as expected.
html,
body {
font-family: 'Montserrat', sans-serif;
margin: 0;
padding: 0;
height: 100%;
}
.main-wrapper {
height: 100%;
width: 100%;
background-color: #DDD;
}
#header {
position: fixed;
height: 70px;
top: 0;
left: 0;
width: 100%;
background-color: #FFF;
display: flex;
color: #ED6F2B;
text-align: center;
}
#footer {
position: fixed;
height: 70px;
bottom: 0;
left: 0;
width: 100%;
background-color: #FFF;
}
#info-column {
float: left;
display: flex;
background-color: #CCC;
margin-top: 70px;
overflow-x: hidden;
overflow-y: scroll;
height: calc(100% - 140px);
}
#map-column {
float: left;
display: flex;
background-color: #93E7ED;
margin-top: 70px;
overflow: hidden;
height: calc(100% - 140px);
}
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div id="header">
HEADER
</div>
<div class="main-wrapper">
<div id="info-column" class="col-lg-3">
<div id="problem-div" class="text-center">
<div>
<img style="width:45%" alt="" src="logo.png">
</div>
<div>
<h2>THIS PERSON'S COMPANY AND SERVICES</h2>
</div>
<div>(555) 555-5555</div>
<div>person#thispersonscompanyandservices.com</div>
<div>thispersonscompanyandservices.com</div>
</div>
<div id="projects">
PROJECTS
</div>
</div>
<div id="map-column" class="col-lg-9">
MAP CONTENT
</div>
</div>
<div id="footer">
FOOTER
</div>
This is not bootstrap related. If you remove it you will get the same issue:
html,
body {
font-family: 'Montserrat', sans-serif;
margin: 0;
padding: 0;
height: 100%;
}
.main-wrapper {
height: 100%;
width: 100%;
background-color: #DDD;
}
#header {
position: fixed;
height: 70px;
top: 0;
left: 0;
width: 100%;
background-color: #FFF;
display: flex;
color: #ED6F2B;
text-align: center;
}
#footer {
position: fixed;
height: 70px;
bottom: 0;
left: 0;
width: 100%;
background-color: #FFF;
}
#info-column {
float: left;
display: flex;
background-color: #CCC;
margin-top: 70px;
overflow-x: hidden;
overflow-y: scroll;
height: calc(100% - 140px);
}
#map-column {
float: left;
display: flex;
background-color: #93E7ED;
margin-top: 70px;
overflow: hidden;
height: calc(100% - 140px);
}
<div id="header">
HEADER
</div>
<div class="main-wrapper">
<div id="info-column" class="col-lg-3">
<div id="problem-div" class="text-center">
<div>
<img style="width:45%" alt="" src="logo.png">
</div>
<div>
<h2>THIS PERSON'S COMPANY AND SERVICES</h2>
</div>
<div>(555) 555-5555</div>
<div>person#thispersonscompanyandservices.com</div>
<div>thispersonscompanyandservices.com</div>
</div>
<div id="projects">
PROJECTS
</div>
</div>
<div id="map-column" class="col-lg-9">
MAP CONTENT
</div>
</div>
<div id="footer">
FOOTER
</div>
And this is due to the use of display:flex within #info-column. The default direction is row making both child divs next to each other. Switch to a column direction or simply remove display:flex
html,
body {
font-family: 'Montserrat', sans-serif;
margin: 0;
padding: 0;
height: 100%;
}
.main-wrapper {
height: 100%;
width: 100%;
background-color: #DDD;
}
#header {
position: fixed;
height: 70px;
top: 0;
left: 0;
width: 100%;
background-color: #FFF;
display: flex;
color: #ED6F2B;
text-align: center;
}
#footer {
position: fixed;
height: 70px;
bottom: 0;
left: 0;
width: 100%;
background-color: #FFF;
}
#info-column {
float: left;
display: flex;
flex-direction:column;
background-color: #CCC;
margin-top: 70px;
overflow-x: hidden;
overflow-y: scroll;
height: calc(100% - 140px);
}
#map-column {
float: left;
display: flex;
background-color: #93E7ED;
margin-top: 70px;
overflow: hidden;
height: calc(100% - 140px);
}
<div id="header">
HEADER
</div>
<div class="main-wrapper">
<div id="info-column" class="col-lg-3">
<div id="problem-div" class="text-center">
<div>
<img style="width:45%" alt="" src="logo.png">
</div>
<div>
<h2>THIS PERSON'S COMPANY AND SERVICES</h2>
</div>
<div>(555) 555-5555</div>
<div>person#thispersonscompanyandservices.com</div>
<div>thispersonscompanyandservices.com</div>
</div>
<div id="projects">
PROJECTS
</div>
</div>
<div id="map-column" class="col-lg-9">
MAP CONTENT
</div>
</div>
<div id="footer">
FOOTER
</div>
I have a CodePen Parallax example that works fine as is. But remove the display: none from line 9 in the CSS to show the header and footer and you get 2 scrollbars.
HTML:
<div class="outer">
<header><h1>Header</h1></header>
<div class="wrapper">
<div class="section parallax">
<h1>Heading</h1>
</div>
<div class="content">
<h1>Site Content</h1>
</div>
</div>
<footer><h1>Footer</h1></footer>
</div>
CSS:
body, html {
margin: 0;
padding:0;
}
/* remove the following to see the problem: */
header, footer {
display: none;
}
.wrapper {
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 1px;
}
.section {
position: relative;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
color: white;
}
.parallax::after {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: translateZ(-1px) scale(2);
background-size: 100%;
z-index: -1;
background-image: url('http://www.shainblumphoto.com/wp-
content/uploads/2016/02/dubai_1.jpg');
}
.content {
height: 200vh;
display: flex;
justify-content: center;
background: red;
}
Does anyone know what change to make to have one scrollbar that includes scrolling of the header and footer, without moving the header and footer to the wrapper, without JavaScript, and still maintain the parallax effect?
Please follow structure.
<div class="outer">
<div class="wrapper">
<header><h1>Header</h1></header>
<div class="section parallax">
<h1>Heading</h1>
</div>
<div class="content">
<h1>Site Content</h1>
</div>
<footer><h1>Footer</h1></footer>
</div>
</div>
Updated answer:
body,
html {
margin: 0;
padding: 0;
}
/* remove the following to see
the problem: */
.outer {
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 1px;
}
.section {
position: relative;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
color: white;
}
.parallax::after {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: translateZ(-1px) scale(2);
background-size: 100%;
z-index: -1;
background-image: url('https://via.placeholder.com/800');
}
.content {
height: 200vh;
display: flex;
justify-content: center;
background: red;
}
<div class="outer">
<header>
<h1>Header</h1>
</header>
<div class="wrapper">
<div class="section parallax">
<h1>Heading</h1>
</div>
<div class="content">
<h1>Site Content</h1>
</div>
</div>
<footer>
<h1>Footer</h1>
</footer>
</div>