how to use css grid to display components at particular area - html

here's my html code
<div>
<div id="navbar" class="box">Navbar</div>
<div id="sidenav " class="box">Side Navbar</div>
<div id="main " class="box">Main</div>
<div id="footer " class="box">Footer</div>
</div>
and here's my scss code
div{
display: grid;
width:100%;
height: 100%;
grid-template-columns: 25% 75% 25%;
grid-gap: 15px;
grid-template-rows:25% 50% 25% ;
// grid-gap: 15px;
grid-template-areas:
"hd hd hd "
"sd ma ma "
"ft ft ft ";
.box{
display: flex;
// text-align: center;
border: 3px solid red;
/* width:150px;
height: 150px; */
margin: auto;
align-items: center;
justify-content: center;
}
#navbar{
grid-area: hd;
}
#sidenav{
grid-area: sd;
}
#main{
grid-area: ma;
}
#footer{
grid-area: ft;
}
}
the problem is the footer div doesn't display in the bottom here's a screenshot
what i want is to make the footer display at the bottom so what seems to be the problem here

There are some issues that I found in your code which makes the layout little wonky.
grid-template-columns: 25% 75% 25%;
The column total is more than 100%, so it will not work perfectly.
I would highly recommend you to use a CSS grid generator online like https://grid.layoutit.com/
For your layout, I would also not recommend structure 3x3 (columns and rows) - As from the image you shared above it looks like the following
1 row - For "Navbar" (this doesnt need any sub columns)
1 row - For Content -> this has 2 columns 1 for "SideNav" and 1 for "Main"
1 row - For "Footer" (again you dont need sub columns)
Based on this your HTML structure will end up looking like
<div class="container">
<div class="navbar">Navbar</div>
<div class="Content">
<div class="SideNav">Side Nav</div>
<div class="Main">Main</div>
</div>
<div class="Footer">Footer</div>
</div>
And your CSS will look like this
body{
padding: 0;
margin: 0;
}
.container {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 25% 50% 25%;
gap: 0px 0px;
grid-template-areas:
"navbar"
"Content"
"Footer";
}
.navbar {
grid-area: navbar;
background-color: #f5f5f5;
padding: 16px;
text-align: center;
}
.Content {
display: grid;
grid-template-columns: 360px 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-template-areas:
"SideNav Main";
grid-area: Content;
}
.SideNav {
grid-area: SideNav;
background-color: #e5e5e5;
padding: 16px;
}
.Main {
grid-area: Main;
background-color: salmon;
padding: 16px;
}
.Footer {
grid-area: Footer;
background-color: #d5d5d5;
padding: 16px;
text-align: center;
}
Here, if you check the code well, the container has 3 rows (25% - navbar, 50% - content, 25% - footer)
And then content has 2 columns (360px - Sidenav, 1fr - Main)
Hope this helps :)
You can also see the code live on my codepen : https://codepen.io/raunaqpatel/pen/WNyQqmm
Or here:
body{
padding: 0;
margin: 0;
}
.container {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 25% 50% 25%;
gap: 0px 0px;
grid-template-areas:
"navbar"
"Content"
"Footer";
}
.navbar {
grid-area: navbar;
background-color: #f5f5f5;
padding: 16px;
text-align: center;
}
.Content {
display: grid;
grid-template-columns: 360px 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-template-areas:
"SideNav Main";
grid-area: Content;
}
.SideNav {
grid-area: SideNav;
background-color: #e5e5e5;
padding: 16px;
}
.Main {
grid-area: Main;
background-color: salmon;
padding: 16px;
}
.Footer {
grid-area: Footer;
background-color: #d5d5d5;
padding: 16px;
text-align: center;
}
<div class="container">
<div class="navbar">Navbar</div>
<div class="Content">
<div class="SideNav">Side Nav</div>
<div class="Main">Main</div>
</div>
<div class="Footer">Footer</div>
</div>

Related

How to center the elements of specific CSS grid's row without horizontal gap and additional wrappers?

Below image has been created by the graphics editor. The target is get the same view by CSS grid.
Currently, the middle row fills the viewport's width:
html, body {
height: 100%;
}
.TwoColumnsLayout {
display: grid;
grid-template-areas:
"UPPER_FIXED_CONTENT UPPER_FIXED_CONTENT"
"SIDEBAR SPECIFIC_CONTENT"
"BOTTOM_FIXED_CONTENT BOTTOM_FIXED_CONTENT";
grid-template-columns: 100px 1fr;
grid-template-rows: auto 1fr auto;
height: 100%;
}
.TwoColumnsLayout-UpperFixedContent {
height: 30px;
grid-area: UPPER_FIXED_CONTENT;
background-color: lightpink;
}
.TwoColumnsLayout-Sidebar {
overflow-y: auto;
grid-area: SIDEBAR;
background-color: gold;
width: 100px;
}
.TwoColumnsLayout-SpecificContent {
overflow-y: auto;
grid-area: SPECIFIC_CONTENT;
background-color: aquamarine;
}
.TwoColumnsLayout-BottomFixedContent {
height: 30px;
grid-area: BOTTOM_FIXED_CONTENT;
background: deepskyblue;
}
<div class="TwoColumnsLayout">
<div class="TwoColumnsLayout-UpperFixedContent"></div>
<div class="TwoColumnsLayout-Sidebar"></div>
<main class="TwoColumnsLayout-SpecificContent"></main>
<div class="TwoColumnsLayout-BottomFixedContent"></div>
</div>
In this case, justify-content: center; will change nothing.
If to apply justify-items: center; to grid container and also justify-self: stretch; to first and last element, we'll get:
html, body {
height: 100%;
}
.TwoColumnsLayout {
display: grid;
grid-template-areas:
"UPPER_FIXED_CONTENT UPPER_FIXED_CONTENT"
"SIDEBAR SPECIFIC_CONTENT"
"BOTTOM_FIXED_CONTENT BOTTOM_FIXED_CONTENT";
grid-template-columns: 100px 1fr;
grid-template-rows: auto 1fr auto;
justify-items: center;
height: 100%;
}
.TwoColumnsLayout-UpperFixedContent {
height: 30px;
grid-area: UPPER_FIXED_CONTENT;
background-color: lightpink;
justify-self: stretch;
}
.TwoColumnsLayout-Sidebar {
overflow-y: auto;
grid-area: SIDEBAR;
background-color: gold;
width: 100px;
}
.TwoColumnsLayout-SpecificContent {
overflow-y: auto;
grid-area: SPECIFIC_CONTENT;
background-color: aquamarine;
}
.TwoColumnsLayout-BottomFixedContent {
height: 30px;
grid-area: BOTTOM_FIXED_CONTENT;
background: deepskyblue;
justify-self: stretch;
}
<div class="TwoColumnsLayout">
<div class="TwoColumnsLayout-UpperFixedContent"></div>
<div class="TwoColumnsLayout-Sidebar"></div>
<main class="TwoColumnsLayout-SpecificContent"></main>
<div class="TwoColumnsLayout-BottomFixedContent"></div>
</div>
I expected it will be simple with CSS grid...
It there the solutions without adding of extra HTML elements?
You can do it like below. The 600px will simulate the max-width which is the area for the sidebar and content
body {
margin:0;
}
.TwoColumnsLayout {
--max: 600px; /* your max-width */
min-height: 100vh;
display: grid;
grid-template-columns:
calc((100% - var(--max))/2) 100px 1fr calc((100% - var(--max))/2);
grid-template-rows: auto 1fr auto;
}
.TwoColumnsLayout-UpperFixedContent,
.TwoColumnsLayout-BottomFixedContent{
height: 30px;
grid-column:1/-1;
background-color: lightpink;
}
.TwoColumnsLayout-Sidebar {
overflow-y: auto;
grid-column: 2;
background-color: gold;
}
.TwoColumnsLayout-SpecificContent {
overflow-y: auto;
background-color: aquamarine;
}
.TwoColumnsLayout-BottomFixedContent {
background: deepskyblue;
}
<div class="TwoColumnsLayout">
<div class="TwoColumnsLayout-UpperFixedContent"></div>
<div class="TwoColumnsLayout-Sidebar"></div>
<main class="TwoColumnsLayout-SpecificContent"></main>
<div class="TwoColumnsLayout-BottomFixedContent"></div>
</div>

HTML button displays very differently on 2 pages with same CSS

I have two web pages - one is a Product Listings Page:
/*BUTTON STYLE*/
button {
background-color: #132257;
color: white;
border: 0.25em solid white;
cursor: pointer;
width: 100%;
height: 90%;
}
/*PRODUCT LISTINGS PAGE*/
.shoplayout {
grid-area: MC;
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-areas: "filters listing";
}
.filters {
grid-area: filters;
}
.listing {
grid-area: listing;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75em;
}
.product {
width: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(6, auto);
border: 0.125em solid #1b2493;
}
.product>* {
height: 8vh;
line-height: 8vh;
border-bottom: solid 0.02em #1b2493;
padding-left: 0.25em;
}
.product div:nth-child(even) {
/*Every second div within a product has the same background*/
background-color: lightsteelblue;
}
.productbuy {
display: grid;
grid-template-columns: repeat(4, 1fr);
text-align: center;
border: none;
}
.productpic {
grid-row: 1;
padding: 0;
border: none;
display: flex;
justify-items: center;
height: 20vh;
}
.productpic>img {
/*https: //stackoverflow.com/questions/3029422/how-do-i-auto-resize-an-image-to-fit-a-div-container*/
max-width: 100%;
max-height: 100%;
}
/*PRODUCT DETAILS PAGE*/
.productdetails {
grid-area: MC;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(6, auto);
gap: 1em;
}
.productdetails>* {
border-bottom: solid 0.02em #1b2493;
padding-left: 0.25em;
}
.picdetail {
grid-column: 1 / span 2;
grid-row: 1;
background-color: cornsilk;
justify-items: center;
border: none;
}
.picdetail img {
max-width: 100%;
max-height: 100%;
}
.productnumbers {
display: grid;
grid-template-columns: repeat(4, 1fr);
text-align: center;
}
<!-- CONTENT -->
<div class="content" id="elemToSlide">
<div class="shoplayout">
<div class="listing">
<!--ALL PRODUCTS IN HERE-->
<div class="product">
<div>Ch. BonPlonque, 2019</div>
<div>Bordeaux, France</div>
<div>Crisp fresh white</div>
<div>3.21/5, 3 reviews</div>
<!--DISPLAY AS A 4 COL INNER GRID-->
<div class="productbuy">
<div>€15.95</div>
<div>Stock: 5</div>
<div><button>Buy</button></div>
<div>Qty</div>
</div>
</div>
<!--END LISTING COLUMNS-->
</div>
<!--END SHOP CONTENT-->
</div>
One is a Products Details Page:
/*BUTTON STYLE*/
button {
background-color: #132257;
color: white;
border: 0.25em solid white;
cursor: pointer;
width: 100%;
height: 90%;
}
/*PRODUCT LISTINGS PAGE*/
.shoplayout {
grid-area: MC;
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-areas: "filters listing";
}
.filters {
grid-area: filters;
}
.listing {
grid-area: listing;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75em;
}
.product {
width: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(6, auto);
border: 0.125em solid #1b2493;
}
.product>* {
height: 8vh;
line-height: 8vh;
border-bottom: solid 0.02em #1b2493;
padding-left: 0.25em;
}
.product div:nth-child(even) {
/*Every second div within a product has the same background*/
background-color: lightsteelblue;
}
.productbuy {
display: grid;
grid-template-columns: repeat(4, 1fr);
text-align: center;
border: none;
}
.productpic {
grid-row: 1;
padding: 0;
border: none;
display: flex;
justify-items: center;
height: 20vh;
}
.productpic>img {
/*https: //stackoverflow.com/questions/3029422/how-do-i-auto-resize-an-image-to-fit-a-div-container*/
max-width: 100%;
max-height: 100%;
}
/*PRODUCT DETAILS PAGE*/
.productdetails {
grid-area: MC;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(6, auto);
gap: 1em;
}
.productdetails>* {
border-bottom: solid 0.02em #1b2493;
padding-left: 0.25em;
}
.picdetail {
grid-column: 1 / span 2;
grid-row: 1;
background-color: cornsilk;
justify-items: center;
border: none;
}
.picdetail img {
max-width: 100%;
max-height: 100%;
}
<!--,GRID CELL 5, 2 - DISPLAYS AS A 4 COL INNER GRID-->
<div class="productbuy">
<div>€15.95</div>
<div>Stock: 5</div>
<div><button>Buy</button></div>
<div>Qty</div>
</div>
Pretty much everything displays as I want with the exception of the button captioned BUY:
The HTML for the .productbuy element is identical in both cases, the CSS is identical in both cases 9with the exception of the nth child background-color), the button style applies across the entire website, so I am puzzled as to why this is happening.
Any and all suggestions gratefully received.
Thanks to both MD Code and Andrea who spotted that there must have been a problem with the parent containers. In the second case, the product details page, there was a div missing from the page structure, and the CSS for both pages was somewhat messy.
So I tidied things up and it works perfectly now.
Product Details Page HTML is now:
<!-- CONTENT -->
<div class="content" id="elemToSlide">
<!--DETAIL LAYOUT-->
<div class="detailslayout">
<!--A WINE-->
<div class="detailspic">
<img src="images/products/winehorizontallarge.png" />
</div>
<div>Name and vintage</div>
<div>Origin</div>
<div>Description</div>
<div>Reviews</div>
<div>Grapes</div>
<div>Producer</div>
<div class="detailsnumbers">
<div>TA</div>
<div>pH</div>
<div>RS</div>
<div>ABV</div>
</div>
<div class="productbuy">
<div>€15.95</div>
<div>Stock: 5</div>
<div><button>Buy</button></div>
<div>Qty</div>
</div>
<!--END WINE-->
</div>
<!--END DETAIL LAYOUT-->
</div>
<!--END CONTENT-->
Putting in the div "DetailsLayout" meant the page structure was correct; I then tidied up the CSS:
/*LAYOUT FOR THE PLP*/
.shoplayout {
grid-area: MC;
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-areas: "filters listing";
}
/*LAYOUT FOR THE PDP - THIS WAS MISSING PREVIOUSLY*/
.detailslayout {
grid-area: MC;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(6, auto);
gap: 1em;
}
.detailslayout > * {
height: 8vh;
line-height: 8vh;
}
.products {
width: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(6, auto);
border: 0.125em solid #1b2493;
}
.products > * {
height: 8vh;
line-height: 8vh;
border-bottom: solid 0.02em #1b2493;
padding-left: 0.25em;
}
.products div:nth-child(even) {
background-color: lightsteelblue;
}
.productbuy {
display: grid;
grid-template-columns: repeat(4, 1fr);
text-align: center;
border: none;
background-color: lightsteelblue;
}
.productpic {
grid-row: 1;
padding: 0;
border: none;
display: flex;
justify-items: center;
height: 20vh;
}
.productpic img, .detailspic img {
max-width: 100%;
max-height: 100%;
}
.detailspic {
grid-column: 1 / span 2;
grid-row: 1 ;
background-color: cornsilk;
justify-items: center;
border: none;
height: 20vh;
}
.detailsnumbers {
display: grid;
grid-template-columns: repeat(4, 1fr);
text-align: center;
}
Now, on both pages the buttons render in the same way on the PLP:
And on the PDP:
Thanks to all for your help,
Dermot
The problem is not your style, button is working good but on details page your button's styles is according to the div parent change div parent style

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>

Avoiding dead DIVs in an HTML grid

The objective is to insert side margins for wider screens, while keeping the header span the entire width.
Normally we'd write
.inner {
margin: 0 5%;
}
to get such margins, but it turns out that HTML grids are so flexible that they make side margins possible through dead grid DIVs.
But somehow using dead DIVs does not seem quite right. Is there a way to obtain side margins within a grid. I see how this can be done with a blend of flex and grid. Here I'm wondering if it can be done with grids alone.
body {
height: 100vh; margin: 0; display: flex;
}
.outer{
margin: 5px; border: 5px; padding: 5px;
display: flex;
flex-grow: 1;
}
.inner {
flex-grow: 1;
margin: 5px; border: 5px; padding: 5px; grid-gap: 5px;
display: grid;
grid-template-rows: 100px 5fr 100px;
grid-template-columns: 1fr;
grid-template-areas: "header" "content" "side";
}
#media screen and (min-width: 600px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5fr 100px;
grid-template-areas:
"header header"
"content side";
}
}
#media screen and (min-width: 800px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 1fr 5fr 100px 1fr;
grid-template-areas:
"header header header header"
"leftmargin content side rightmargin";
}
}
.box {
padding: 10px; margin: 5px;
border: 5px solid #444;
background-color: #eee;
font-size: 150%;
position: relative;
}
.header { grid-area: header; }
.content { grid-area: content; }
.side { grid-area: side; }
.leftmargin { grid-area: leftmargin; }
.rightmargin { grid-area: rightmargin; }
<div class="outer">
<div class="inner">
<div class="box header">Header</div>
<div class="box content">Content</div>
<div class="box side">Side</div>
</div>
</div>
Use dots (.) to declare empty grid areas:
grid-template-areas:
"header header header header"
". content side .";
Example:
body {
height: 100vh;
margin: 10px;
}
.inner {
display: grid;
grid-template-rows: 100px 5fr 100px;
grid-template-columns: 1fr;
grid-template-areas: "header" "content" "side";
grid-gap: 5px;
}
#media screen and (min-width: 600px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5fr 100px;
grid-template-areas:
"header header"
"content side";
}
}
#media screen and (min-width: 800px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5% 5fr 100px 5%;
grid-template-areas:
"header header header header"
". content side .";
}
}
.box {
padding: 10px; margin: 5px;
border: 5px solid #444;
background-color: #eee;
font-size: 150%;
position: relative;
}
.header { grid-area: header; }
.content { grid-area: content; }
.side { grid-area: side; }
<div class="inner">
<div class="box header">Header</div>
<div class="box content">Content</div>
<div class="box side">Side</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>