I need to setup the following DIV structure (See image below. It tells more than a 1000 words)
The structure consists of 2 colums. The main column (left) has a variable width and 100% height.
The right colums has a FIXED width of 380px and 100% height.
Then inside the right column I need 3 DIVS.
The top DIV has a fixed height of 200px and must be aligned to the top.
The bottom DIV has a fixed height of 150px and must be aligned to the bottom.
The middle DIV has a variable height and must fill up the space vertically.
This is the DIV setup And the CSS I have:
.main-content {
width: 100%;
padding: 0px;
}
.col-1 {
width: calc(100% - 380px);
min-height: calc(var(--vh, 1vh)*100);
background-color: #2693FF;
float: left;
}
.col-2 {
width: 380px;
min-height: calc(var(--vh, 1vh)*100);
float: right;
}
.col-2-top {
height: 200px;
background-color: #00B200;
}
.col-2-middle {
height: 100%;
background-color: #FF8000;
}
.col-2-bottom {
height: 100px;
background-color: #B25900;
}
<div class="main-content">
<div class="col-1"></div>
<div class="col-2">
<div class="col-2-top"></div>
<div class="col-2-middle"></div>
<div class="col-2-bottom"></div>
</div>
</div>
Then... Column 1 and 2 should stack when the viewport width becomes less than 768px.
Column 1 on top and Column 2 below it.
Like this:
I think I'm almost there, but I'm having problems with the height of the Main DIV and the heights and aligning of the DIV col-2 middle DIV. I also need a bit helpt to get these divs stack nicely above each each other.
I would suggest that you use grid layout instead of floating around your <div>s, grid layout allows you to structure your layout and separate them in columns and rows, and areas using grid-template-areas.
for max-width:748 just add media query, here is how it might be implemented:
body {
padding: 0;
margin: 0;
}
.main-content {
display: grid;
background-color: #2196F3;
grid-template-areas:
'main fixed-top'
'main variable-mid-area'
'main fixed-bottom';
background-color: #2196F3;
height: 100vh;
grid-template-columns: 1fr 380px;
grid-template-rows: 200px 1fr 150px;
}
.main-content > div {
color: #fff;
font-size: 30px;
vertical-align: middle;
display: flex;
justify-content: center;
align-items: center;
}
.main {
grid-area: main;
background-color: #2693FC;
}
.variable-mid-area {
grid-area: variable-mid-area;
background-color: #FF8015;
}
.fixed-top {
grid-area: fixed-top;
background-color:#00B21F;
}
.fixed-bottom {
grid-area: fixed-bottom;
background-color: #B2590B;
}
#media only screen and (max-width: 768px) {
.main-content {
grid-template-areas:
'main'
'fixed-top'
'variable-mid-area'
'fixed-bottom';
grid-template-rows: 300px 200px 1fr 150px;
grid-template-columns: 100%;
height: auto;
}
}
<div class="main-content">
<div class="main"> main </div>
<div class="fixed-top"> 200 </div>
<div class="variable-mid-area"> auto </div>
<div class="fixed-bottom"> 150 </div>
</div>
If you have any questions how the css works, feel free to ask them in the comments.
I know the background-colors are irrelevant but they help to visualize it.
.container {
min-width: 768px;
width: 100%;
display: grid;
grid-template-columns: calc(100% - 380px) 1fr;
min-height: 100vh;
}
.col1 {
background-color: dodgerblue;
}
.col2 {
display: flex;
flex-direction: column;
}
.col2-row1 {
height: 200px;
background-color: orange;
}
.col2-row2 {
background-color: forestgreen;
height: 100%;
}
.col2-row3 {
height: 150px;
background-color: red;
}
#media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
}
<div class="container">
<div class="col1">1</div>
<div class="col2">
<div class="col2-row1">2</div>
<div class="col2-row2">3</div>
<div class="col2-row3">4</div>
</div>
</div>
Related
I have a container that will have a picture of the day. When changing viewport sizes (mobile screen size) the container gets squashed so much that the image is not readable.. How can I get the containers in my grid system to stay the exact same size relative to the viewport? Thank you!!
html,
body,
form,
main {
height: 100%;
}
body {
background-color: #232A35;
padding: 10px;
}
.content {
height: 100%;
margin-left: auto;
margin-right: auto;
}
.mainheader {
border: 1px red solid;
width: 100%;
}
.iotd {
grid-area: iotd;
}
.banner {
grid-area: banner;
}
.solutions {
grid-area: solutions;
}
.services {
grid-area: services;
}
.tud {
grid-area: tud;
}
.resources {
grid-area: resources;
}
.grid-container {
display: grid;
grid-template-areas: 'iotd banner banner banner banner banner' 'iotd solutions services resources tud tud';
gap: 10px;
background-color: #2196F3;
padding: 10px;
height: 100%;
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
#media screen and (max-width: 900px) {
.grid-container>div {
font-size: 10px;
}
}
<div class="content">
<div class="container-fluid mainheader">
<div class="grid-container">
<div class="iotd col">IOTD</div>
<div class="banner col">Banner</div>
<div class="solutions col">Solutions</div>
<div class="services col">Services</div>
<div class="tud col">The Unrecovery Difference</div>
<div class="resources col">Resources</div>
</div>
</div>
</div>
The container that will hold the image is labeled as "IOTD"
Any help is appreciated
resolved the issue by changing the image size rather than the container size when the viewport reaches 900px. I also change the font size to a smaller size which in turn makes all of the containers smaller
One approach might be to include a grid-template-columns rule to specify how you want the horizontal space apportioned, this can include a minimum absolute (px) width for the first column with the option of allowing it to grow when more space is available using minmax.
For example, I've added the following rule to your css:
grid-template-columns: minmax(150px, 1fr) repeat(5, 1fr);
This divides the grid into 6 columns to be consistent with your area template (which remains in operation) but makes the first column at least 150px wide with the option of expanding with the other columns when extra width is available. The remaining five columns are allocated 1/5 of the available space by specifying 5 1fr fractions.
Here's the rule added to your example:
html,
body,
form,
main {
height: 100%;
}
body {
background-color: #232A35;
padding: 10px;
}
.content {
height: 100%;
margin-left: auto;
margin-right: auto;
}
.mainheader {
border: 1px red solid;
width: 100%;
}
.iotd {
grid-area: iotd;
}
.banner {
grid-area: banner;
}
.solutions {
grid-area: solutions;
}
.services {
grid-area: services;
}
.tud {
grid-area: tud;
}
.resources {
grid-area: resources;
}
.grid-container {
display: grid;
grid-template-areas: 'iotd banner banner banner banner banner' 'iotd solutions services resources tud tud';
grid-template-columns: minmax(150px, 1fr) repeat(5, 1fr);
gap: 10px;
background-color: #2196F3;
padding: 10px;
height: 100%;
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
#media screen and (max-width: 900px) {
.grid-container>div {
font-size: 10px;
}
}
<div class="content">
<div class="container-fluid mainheader">
<div class="grid-container">
<div class="iotd col">IOTD</div>
<div class="banner col">Banner</div>
<div class="solutions col">Solutions</div>
<div class="services col">Services</div>
<div class="tud col">The Unrecovery Difference</div>
<div class="resources col">Resources</div>
</div>
</div>
</div>
This page https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Grid_Template_Areas has examples where grid-template-areas are combined with grid-template-columns (it also has some ideas on using media queries to suit different view ports).
I have a very simple grid layout of the menu, header, and content.
I would like the content (blue box) to stretch vertically. As you can see, the grid element (yellow box) already stretches vertically, but the blue element inside of it (which should be dynamic content) does not.
Is there a way to achieve this 1) without switching the whole grid structure to flexbox and 2) without using calc to give the blue content 100vh minus the header height?
.container {
height: 100vh;
display: grid;
grid-template-rows: min-content 1fr;
grid-template-columns: min-content 1fr;
grid-template-areas: "menu header" "menu content";
box-sizing: border-box;
overflow: hidden;
}
.mainMenuWrapper {
grid-area: menu;
height: auto;
}
.headerWrapper {
grid-area: header;
height: auto;
}
.contentWrapper {
grid-area: content;
overflow-y: auto;
height: auto;
background-color: yellow;
}
.menu {
height: 100vh;
background-color: red;
width: 50px;
}
.header {
height: 80px;
background-color: green;
}
.content {
background-color: blue;
width: 100%;
height: ???
}
<div class="container">
<div class="mainMenuWrapper">
<div class="menu">
menu
</div>
</div>
<div class="headerWrapper">
<div class="header">
header
</div>
</div>
<div class="contentWrapper">
<div class="content">
content
</div>
</div>
</div>
Image:
JSFiddle link: https://jsfiddle.net/the2sj1n/3/
You can apply height: 100% on that blue box .content
body {
margin: 0; /*Removed unexpected margins from browsers' default styles*/
}
.container {
height: 100vh;
display: grid;
grid-template-rows: min-content 1fr;
grid-template-columns: min-content 1fr;
grid-template-areas: "menu header" "menu content";
box-sizing: border-box;
overflow: hidden;
}
.mainMenuWrapper {
grid-area: menu;
height: auto;
}
.headerWrapper {
grid-area: header;
height: auto;
}
.contentWrapper {
grid-area: content;
overflow-y: auto;
height: auto;
background-color: yellow;
}
.menu {
height: 100vh;
background-color: red;
width: 50px;
}
.header {
height: 80px;
background-color: green;
}
.content {
background-color: blue;
width: 100%;
height: 100%; /*The change here*/
}
<div class="container">
<div class="mainMenuWrapper">
<div class="menu">
menu
</div>
</div>
<div class="headerWrapper">
<div class="header">
header
</div>
</div>
<div class="contentWrapper">
<div class="content">
content
</div>
</div>
</div>
Im trying to make a simple flex layout with a header, 2x2 grid of content, then sidebar. It is supposed to move the sidebar to the bottom of the screen when the width of the window is smaller than a certain size.
Currently, once that size is reached, if you make the height of the window too small then the grid content will overlap the header, but im not sure why. The screen should also just be the size of the view height, but moving the sidebar extends its for some reason.
#media (max-width:960px) {
.main-screen {
height: 100vh;
display: flex;
flex-direction: column-reverse;
.toolbar {
padding: 10px;
height: 90px;
width: auto;
}
.body {
display: flex;
.grid {
flex: 1;
max-height: 36vh;
}
.row1, .row2 {
flex: 1;
height: 10%;
max-width: 100%;
}
}
}
}
here is the full code in jsfiddle
(just drag the window size down to see how grids overlap header)
Good day ^^
I've built this for you. Is this what you're looking for?
*{margin: 0px; padding: 0px;}
html{height: 100%; width: 100%;}
body{background-color: lightblue;}
/* Header, Main Content, Nav/Sidebar */
header{background-color: lightgray; height: 50px;}
.Main{background-color: darkblue; display: grid; grid-template-columns: 1fr 80px;}
nav{background-color: pink; width: 100%; outline: 5px solid white;}
/* Rows */
.Main .Row1, .Main .Row2{display: grid; grid-template-columns: 50% 50%; height: 120px;}
/* Row 1 */
.Main .Row1 .Div1{margin: 5px; background-color: lightgreen;}
.Main .Row1 .Div2{margin: 5px; background-color: forestgreen;}
/* Row 2 */
.Main .Row2 .Div3{margin: 5px; background-color: forestgreen;}
.Main .Row2 .Div4{margin: 5px; background-color: lightgreen;}
/* Smaller Size */
#media (max-width:960px) {
.Main{background-color: blue; grid-template-columns: auto;}
nav{height: 50px;}
}
<body>
<header>
<h1>Header</h1>
</header>
<section class="Main">
<div>
<div class="Row1">
<div class="Div1">Div1</div>
<div class="Div2">Div2</div>
</div>
<div class="Row2">
<div class="Div3">Div3</div>
<div class="Div4">Div4</div>
</div>
</div>
<nav>
<h1>Sidebar</h1>
</nav>
</section>
</body>
Here my page layout, the image should vertically fit into the first row:
<div id="main">
<div id="header" class="vcenter">
<img src="https://source.unsplash.com/random/200x200" id="logo">
</div>
<div id="e1"></div>
</div>
css:
* {
margin: 0px;
padding: 0px;
}
body {
background-color: #001018;
}
#main {
display: grid;
grid-template-columns: 200px;
grid-template-rows: 100px auto;
grid-template-areas:
"header"
"e1";
gap: 20px;
}
#header { grid-area: header; }
#e1 { grid-area: e1; }
#main > div {
background-color: #334455;
padding: 5px;
}
#logo {
max-width: auto;
max-height: 80%;
border: 1px solid red;
}
.vcenter {
display: grid;
align-items: center;
}
Firefox successfully centers the image after resizing but Chrome shifts the image down, like so:
Is there a simple way to make this compatible in both browsers with minimal changes to the css/html, keeping the current grid layout?
Thank you!
https://jsfiddle.net/tfoller/pnmjvq58/32/
There is not enough height. Add height: 100% to #logo. Like that:
#logo {
...
height: 100%;
}
This will work in both browsers.
I'm learning CSS Grid layout and i have a problem about positioning.
What i want is to create a page layout composed by a left-side menu, top-bar menu and a main content page like the image below:
I have been able to achieve the goal, but now i want to fix the position of the top bar and sidebar while main content is scrolling.
I set position:sticky to both containers but it does not working.
How can i fix?
Here is my code:
* {
margin: 0 !important;
padding: 0 !important;
box-sizing: border-box !important;
}
.grid-container {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: 10% 100vh;
grid-template-areas:
"LeftMenu TopMenu"
"LeftMenu Main";
}
.LeftMenu {
background-color: #a4a4a4;
grid-area: LeftMenu;
width: 200px;
height: 100%;
}
.TopMenu {
background-color: #d49494;
grid-area: TopMenu;
width: 100%;
height: 100%;
display: flex;
}
.Main {
background-color: #8990eb;
grid-area: Main;
width: 100%;
height: 100vh;
}
<div class="xdg-component-appnav-menu">
<div class="grid-container">
<div class="LeftMenu">left menu</div>
<div class="TopMenu">top menu</div>
<div class="Main">
<p style="padding-bottom: 1000px;">Content</p>
</div>
</div>
</div>
You don't need position: sticky. It's extra complication and still isn't fully supported by some browsers.
Just use overflow: auto on the main container.
.grid-container {
display: grid;
height: 100vh;
grid-template-columns: 200px 1fr;
grid-template-rows: 10% 90%;
grid-template-areas:
"LeftMenu TopMenu"
" LeftMenu Main ";
}
.LeftMenu {
grid-area: LeftMenu;
background-color: #a4a4a4;
}
.TopMenu {
grid-area: TopMenu;
background-color: #d49494;
}
.Main {
grid-area: Main;
overflow: auto; /* key adjustment */
background-color: #8990eb;
}
body {
margin: 0;
}
<div class="xdg-component-appnav-menu">
<div class="grid-container">
<div class="LeftMenu">left menu</div>
<div class="TopMenu">top menu</div>
<div class="Main">
<p style="height: 1000px;">Content</p>
</div>
</div>
</div>