How can I get my grid layout to scale properly? - html

I am trying to build a grid layout at the top of my page that will have a navigation bar and a picture that changes every day. I have this done.. But when I try to scale my webpage to a mobile layout, everything breaks.. The grid shrinks down so much that the columns start to go outside of the grid. I followed the bootstrap docs, and took this grid layout from the website and configured it to my own liking.
html, body, form, main {
height: 100%;
}
body{
background-color: #232A35;
}
.content{
width:90%;
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: auto auto auto auto;
grid-template-rows: auto auto;
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;
}
<div class="content">
<div class="container-fluid mainheader">
<div class="grid-container">
<div class="iotd">IOTD</div>
<div class="banner">Banner</div>
<div class="solutions">Solutions</div>
<div class="services">Services</div>
<div class="tud">The Unrecovery Difference</div>
<div class="resources">Resources</div>
</div>
</div>
</div>

Related

How can I get my grid column to stay the same size (height and width) when resizing viewports?

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).

Compatibility problem when resizing an image inside css grid layout

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.

Header Sticky Position in CSS Grid Layout

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>

Toggling rows in and out in CSS Grid Layout

I have the following layout with 2 headers and 3 footers:
.my-grid {
display: grid;
grid-template-areas:
"header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3"
;
grid-template-rows: 27px 27px 1fr 28px 28px 28px;
height: 100%;
}
The main area will expand to fill the gap left after showing the headers and footers.
I want to be able to toggle footers on and off (show / hide them) such that they collapse. With the code above, a gap will be left in place of the footer when we hide it.
How should I go about:
Having a main area that always expands
Having optional headers and footers which collapse, when hidden
Examples:
If header1 collapses, then header2 should take its place and mainAreaExpandMePlease should expand to where header2 used to be
If header2 collapses, then mainAreaExpandMePlease should expand up by another 27px
If footer3 collapses, then footer2 takes place of footer3, footer1 takes the place of footer2 and mainAreaExpandMePlease will stretch down another 28px
Thank you!
Fiddle: https://jsfiddle.net/jg6ho4wu/1/
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.my-grid {
display: grid;
grid-template-areas:
"header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3";
grid-template-rows: 27px 27px 1fr 28px 28px 28px;
height: 100%;
}
.header1 {
grid-area: header1;
background-color: yellow;
}
.header2 {
grid-area: header2;
background-color: magenta;
}
.mainAreaExpandMePlease {
grid-area: mainAreaExpandMePlease;
background-color: cyan;
}
.footer1 {
grid-area: footer1;
background-color: green;
}
.footer2 {
grid-area: footer2;
background-color: red;
}
.footer3 {
grid-area: footer3;
background-color: blue;
}
<div class="my-grid">
<div class="header1"></div>
<div class="header2"></div>
<div class="mainAreaExpandMePlease"></div>
<div class="footer1"></div>
<div class="footer2" style="display:none"></div>
<div class="footer3"></div>
</div>
Don't set the height of the header and footer rows at the container level.
Set their heights on the items, and set their container heights to auto.
.my-grid {
display: grid;
height: 100vh;
grid-template-rows: auto auto 1fr auto auto auto;
grid-template-areas: "header1"
"header2"
"mainAreaExpandMePlease"
"footer1"
"footer2"
"footer3";
}
.header1 {
height: 27px;
grid-area: header1;
background-color: yellow;
}
.header2 {
height: 27px;
grid-area: header2;
background-color: magenta;
}
.mainAreaExpandMePlease {
grid-area: mainAreaExpandMePlease;
background-color: cyan;
}
.footer1 {
height: 28px;
grid-area: footer1;
background-color: green;
}
.footer2 {
height: 28px;
grid-area: footer2;
background-color: red;
}
.footer3 {
height: 28px;
grid-area: footer3;
background-color: blue;
}
body {
margin: 0;
padding: 0;
}
<div class="my-grid">
<div class="header1"></div>
<div class="header2"></div>
<div class="mainAreaExpandMePlease"></div>
<div class="footer1"></div>
<div class="footer2" style="display:none"></div>
<div class="footer3"></div>
</div>

Allow one grid item to scroll with fixed header and sidebar

I have a grid layout with two columns and two rows. A sticky left nav, a sticky header, and content that will live in the bottom right corner of the grid.
What I have now is nearly there, but I would like the .content div to use scroll when content extends beyond the screen. I thought I would be able to just use overflow: auto, but that isn't working. Is what I have close?
body {
margin: 0;
overflow: hidden;
}
.page {
display: grid;
grid-template-rows: 55px auto;
grid-template-columns: 20vh auto;
grid-template-areas: "nav header" "nav content";
}
.nav {
grid-area: nav;
background-color: blue;
}
.header {
grid-area: header;
background-color: grey;
}
.content {
grid-area: content;
height: 1000px; // This is dynamic
background-color: red;
}
<div class="page">
<div class="nav">Side nav</div>
<div class="header">Header</div>
<div class="content">
<h1>title</h1>
</div>
<div>
JS fiddle
For overflow: auto to work (i.e., for scrollbars to render) browsers need a trigger. This trigger is usually a height / width limitation that forces an overflow condition, which launches the scrollbars.
Trigger conditions vary among browsers. They also vary among CSS technologies, such as flex, grid and block layouts.
In this particular case, there are several logical places to establish an overflow condition, but none of them work.
You could target the grid item, as you have tried:
.content {
height: 1000px
overflow: auto;
}
But it doesn't work. No scrollbar appears on the fluid item.
body {
margin: 0;
/* overflow: hidden; */
}
.page {
display: grid;
grid-template-rows: 55px auto;
grid-template-columns: 20vh auto;
grid-template-areas: "nav header"
"nav content";
}
.nav {
grid-area: nav;
background-color: aqua;
}
.header {
grid-area: header;
background-color: lightgrey;
}
.content {
grid-area: content;
height: 1000px;
overflow: auto;
background-color: red;
}
<div class="page">
<div class="nav">Side nav</div>
<div class="header">Header</div>
<div class="content">
<h1>title</h1>
</div>
<div>
You could target the row itself, as I tested:
.page {
display: grid;
grid-template-rows: 55px 1000px;
}
.content {
overflow: auto;
}
But that doesn't work either. Still no scrollbar on the fluid item.
body {
margin: 0;
/* overflow: hidden; */
}
.page {
display: grid;
grid-template-rows: 55px 1000px;
grid-template-columns: 20vh auto;
grid-template-areas:
"nav header"
"nav content";
}
.nav {
grid-area: nav;
background-color: aqua;
}
.header {
grid-area: header;
background-color: lightgrey;
}
.content {
overflow: auto;
grid-area: content;
background-color: red;
}
<div class="page">
<div class="nav">Side nav</div>
<div class="header">Header</div>
<div class="content">
<h1>title</h1>
</div>
<div>
So I targeted a child of the grid item. DING DING DING! That worked.
No need for fixed positioning. No need for sticky positioning. This works across all browsers that support Grid Layout.
body {
margin: 0;
}
.page {
display: grid;
grid-template-rows: 55px calc(100vh - 55px); /* height limitation on second row */
grid-template-columns: 20vh auto;
grid-template-areas: "nav header"
"nav content";
}
.nav {
grid-area: nav;
background-color: aqua;
}
.header {
grid-area: header;
background-color: lightgrey;
}
.content {
grid-area: content;
background-color: red;
overflow: auto; /* overflow condition on parent */
}
article {
height: 1000px; /* height set on child; triggers scroll */
}
<div class="page">
<div class="nav">Side nav</div>
<div class="header">Header</div>
<div class="content">
<article><!-- new section for content -->
<h1>title</h1>
</article>
</div>
<div>
jsFiddle demo
Browser support is not 100%, but what about actually using sticky instead of fixed positioning? (now tested in Chrome) You won't have to deal with hard-coded margins.
One of the issues you'll still have to deal with, what to do when the content in your sidebar (.nav > div) Is higher than your viewport.
body {
margin: 0;
}
.page {
display: grid;
grid-template-rows: 55px auto;
grid-template-columns: 3.5rem auto;
grid-template-areas: "nav header" "nav content";
}
.nav {
grid-area: nav;
background-color: blue;
}
.nav > div {
position: sticky;
top: 0;
}
.header {
grid-area: header;
background-color: grey;
position: sticky;
top: 0;
min-height: 3.5rem;
}
.content {
grid-area: content;
min-height: 1000px;
background-color: red;
}
<div class="page">
<div class="nav">
<div>Side nav</div>
</div>
<div class="header">Header</div>
<div class="content">
<h1>title</h1>
</div>
<div>
I have included the change log to see where the code needs to be change in order to get an understanding. Also the full code snippet is available below. Hope this is what you expect.
Change log
*Remove body { overflow: hidden; }
*Change .page { grid-template-columns: 3.5rem auto; }
*Added
.nav { position: fixed;
top: 0;
bottom:0;}
*Added
.header { position: fixed;
margin-left: 3.5rem;
width: 100%;
height: 3.5rem; }
Full Code
body {
margin: 0;
}
.page {
display: grid;
grid-template-rows: 55px auto;
grid-template-columns: 3.5rem auto;
grid-template-areas:
"nav header"
"nav content";
}
.nav {
position: fixed;
top: 0;
bottom:0;
grid-area: nav;
background-color: blue;
}
.header {
grid-area: header;
background-color: grey;
position: fixed;
margin-left: 3.5rem;
width: 100%;
height: 3.5rem;
}
.content {
grid-area: content;
height: 1000px;
background-color: red;
}
<div class="page">
<div class="nav">Side nav</div>
<div class="header">Header</div>
<div class="content">
<h1>title</h1>
</div>
<div>