CSS Grid hiding text on mobile (mobile first) - html

I am building a navigation bar and using CSS grid.
Here is the html:
<nav class="nav">
<div class="menu">
<div class="header">
HEADER
</div>
</div>
<span class="space"></span>
<div class="breadcrumb">
<div class="bcrumb">
Breadcrumbs
</div>
</div>
</nav>
<div class="content">
</div>
And here is my CSS:
body {
font-family: sans-serif;
margin:0;
}
.nav {
height: 100px;
position: fixed;
right: 0;
left: 0;
top: 0;
display:grid;
grid-template-rows: 1fr 5px 1fr;
grid-template-areas:
"Menu"
"Space"
"Breadcrumb"
}
.content{
height:1000px;
background-color:gray;
margin-top:100px;
}
.menu {
grid-area: Menu;
background-color: #333333;
display: grid;
grid-template-columns: 1.5em 80px 1fr auto;
grid-template-areas: ". . . MenuItems";
}
.menu-items {
grid-area: MenuItems;
}
.space {
grid-area: Space;
background-color: #c20418;
}
.breadcrumb {
grid-area: Breadcrumb;
background-color: white;
}
#media only screen and (min-width : 1224px) {
.menu {
display:inline-grid;
grid-template-columns: 1.5em 80px auto 1fr auto auto;
grid-template-areas: ". . Header . . MenuItems";
align-content: end;
}
.header {
grid-area: Header;
color: white;
font-size: 1.2em;
}
.breadcrumb {
display: grid;
grid-template-columns: 1.5em 80px 1fr;
grid-template-areas: ". . Bcrumb";
}
.bcrumb {
grid-area: Bcrumb;
align-self: center;
font-size: 1.2em;
}
}
I have made it with an header text and text place for breadcrumbs that should only be there when on larger screens.
I've made it work by adding:
.header, .bcrumb{
visibility:hidden;
}
and then set it to visible in the media queries.
But surely there must be a better way to do this?
Here is a Fiddle with the same code.

Here is the CSS for mobile screens
#media all and (max-width: 767px) {
.header, .bcrumb {
visibility: hidden;
}
}

Related

how to use css grid to display components at particular area

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>

How to make content take up the aside area as well using grid-template-areas?

The grid-template-areas is being used here. However, the main area is not taking up the rest of the area, and I dont need aside for my project.
How can I make the main area take up the rest of the area?
.container {
display: grid;
grid-template-areas: "header header header" "nav content side" "footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-gap: 10px;
height: 100vh;
}
header {
grid-area: header;
border: 1px solid #61dafb;
}
nav {
grid-area: nav;
margin-left: 0.5rem;
border: 1px solid red;
}
main {
grid-area: content;
border: 1px solid blue;
}
footer {
grid-area: footer;
border: 1px solid black;
}
#media (max-width: 768px) {
.container {
grid-template-areas: "header" "nav" "content" "side" "footer";
grid-template-columns: 1fr;
grid-template-rows: auto/* Header */
minmax(75px, auto)/* Nav */
1fr/* Content */
minmax(75px, auto)/* Sidebar */
auto;
/* Footer */
}
nav,
aside {
margin: 0;
}
}
header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
}
<div class="container">
<header>
<div>Header</div>
</header>
<nav>
<div>nav</div>
</nav>
<main>
</main>
<footer>
<div>Footer</div>
</footer>
</div>
Attaching JSfiddle https://jsfiddle.net/fgmwe281/2/
I am trying to use grid-template-areas for my boilerplate code for layout. However, unable to get the main content to take up the space on right(the area for aside).
I would skip grid-template-areas completely. It is nice for beginners as it visually displays the areas but overall it increases the size of necessary code. On top of that, it is easier to just skip it and letting the header and the footer span the entire with by using grid-column: 1 / -1;.
If you change the grid-template-columns to min-content auto min-content then the sidebar and the navigation will only consume as much space as needed. In this case, I sued the width on the containing div. If it exist then it will consume 200px width, if it doesn't, then it will consume no space:
body {
margin: 0;
}
.container {
display: grid;
grid-template-columns: min-content auto min-content;
grid-gap: 10px;
min-height: 100vh;
}
header,
footer {
grid-column: 1 / -1;
}
nav > div,
aside > div {
width: 200px;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
}
#media only screen
and (max-width: 768px) {
.container {
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr auto auto;
}
}
#media only screen
and (min-width: 769px) {
.container {
grid-template-rows: auto 1fr auto;
}
}
header {
border: 1px solid #61dafb;
}
nav {
border: 1px solid red;
}
main {
border: 1px solid blue;
}
footer {
border: 1px solid black;
}
<div class="container">
<header>
<div>Header</div>
</header>
<nav>
<div>nav</div>
</nav>
<main>
<div>main</div>
</main>
<aside></aside>
<footer>
<div>Footer</div>
</footer>
</div>

CSS Grid: Make nav bar collapsible in mobile

Trying my best to learn CSS Grid...
I have made a nav menu but cannot get it to collapse for mobile view ('hamburger' menu style). I have tried using the 'checkbox hack' seen in several videos and online tutorials.
I also can't seem to get all of the links to list (list begins at 'Products' in my mobile view, but should begin at 'About Us').
Been working on this for days with no luck.
If anyone could help me out in getting this to work I would be very grateful.
Here's the HTML & CSS:
html, body{
margin: 0;
padding: 0;
font-family: Roboto, sans-serif;
font-size: 100%;
}
header{
/* grid-column-start: 1;
grid-column-end: 3;
grid-row:1;
*/
grid-area: header;
background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral.jpg);
display: grid;
grid-template-columns: repeat (4, 1fr);
/* 100px, 1fr 1fr 1fr;
*/
/**** Change to 10% and 90% otherwise it takes up the full viewport ****/
grid-template-rows: 100px auto;
grid-template-areas: "logo topbar-nav topbar-nav topbar-nav" ". hero-text hero-text . ";
}
.logo{
grid-area: logo;
background-image:url(../img/logo-mobile.png);
background-repeat: no-repeat;
margin-left: 10px;
}
.topbar-nav{
grid-area: topbar-nav;
color:white;
background-color: lightblue;
justify-self: end;
align-self: center;
}
.topbar-nav, ul, li{
list-style-type: none;
float: left;
padding: 0px 5px 0px 5px;
}
.hero-text{
grid-area: hero-text;
color:white;
justify-self: center;
align-self: center;
}
.hero-text h1{
font-size: 600%;
}
.hero-text p{
font-size: 200%;
text-align: center;
}
nav{
grid-area: nav;
}
.grid-about{
/* grid-column-start: 1;
grid-column-end: 4;
grid-row:2;
*/
grid-area: about;
}
.grid-products{
/* grid-column-start: 1;
grid-column-end: 4;
grid-row:3;
*/
grid-area: products;
}
.grid-services{
/* grid-column-start: 1;
grid-column-end: 4;
grid-row:4;
*/
grid-area: services;
}
.grid-contact{
grid-area: contact;
}
.grid-location{
grid-area: location;
}
.grid-phone-social{
grid-area: phone;
}
footer{
/* grid-column-start: 1;
grid-column-end: 4;
grid-row:6;
*/
grid-area: footer;
}
/****Grid for mobile screens****/
#media (max-width: 767px){
.grid-container{
display: grid;
background-color: aqua;
grid-auto-rows: 50vh;
grid-gap: 10px;
grid-template-areas: "header"
/* "nav"*/
"about" "products" "services" "contact" "location" "phone" "footer";
}
header{
background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral-mobile.jpg);
background-repeat: no-repeat;
/* Change to: grid-template-columns: 110px auto;
*/
grid-template-columns: 110px auto;
grid-template-rows: 50px auto;
grid-template-areas: "logo topbar-nav" "hero-text hero-text";
}
.topbar-nav ul, li{
display: grid;
grid-template-rows: 10px;
grid-gap: 5px;
font-size:75%;
float:left;
}
.hero-text h1{
font-size: 300%;
text-align: center;
}
.hero-text p{
font-size: 150%;
text-align: center;
}
}
/****Grid for tablet screens****/
#media (min-width: 768px){
.grid-container{
display: grid;
grid-auto-rows: 100vh;
grid-gap: 10px;
background-color: red;
grid-template-areas: "header"
/* "nav" */
"about" "products" "services" "contact" "location" "phone" "footer";
}
header{
grid-area: header;
background-image:linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url(../img/rockspiral.jpg);
display: grid;
/* changed: column size 260px 1fr 1fr 1fr*/
grid-template-columns: 260px 1fr 1fr 1fr;
grid-template-rows: 100px auto;
grid-template-areas: "logo topbar-nav topbar-nav topbar-nav" "hero-text hero-text hero-text hero-text";
}
.logo{
grid-area: logo;
background-image:url(../img/logo.png);
background-repeat: no-repeat;
margin-left: 10px;
}
}
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/layout.css">
<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
<title>CSS Grid Sandbox</title>
</head>
<body>
<div class="grid-container">
<header>
<div class="logo"></div>
<div class="topbar-nav">
<ul>
<li>About</li>
<li>Products</li>
<li>Services</li>
<li>Contact</li>
<li>Location & Hours</li>
<li>Phone & Social Media</li>
</ul>
</div>
<div class="hero-text">
<h1>Big Rock Sale</h1>
<p>All rocks 50% off. Offer ends soon!</p>
</div>
</header>
<!-- <nav>Nav</nav> -->
<section class="grid-about">About Us</section>
<section class="grid-products">Products</section>
<section class="grid-services">Services</section>
<section class="grid-contact">Contact</section>
<section class="grid-location">Location & Hours</section>
<section class="grid-phone-social">Phone & Social Media</section>
<footer>Footer</footer>
</div>
</body>
</html>
While I personally recommend using Javascript for this a pure CSS version can be achieved through multiple methods, one of which is by using a checkbox paired with the :checked selector.
.hamburger-menu-content {
display: none;
}
#hamburger-menu-trigger:checked+.hamburger-menu-content {
/* '+' means all elements that have the first element preceding it */
display: block;
}
<input type="checkbox" id="hamburger-menu-trigger">
<div class="hamburger-menu-content">
<p>Foo</p>
<p>Foo</p>
<p>Foo</p>
</div>
The downside of this approach is that you need to click the input again to close it.
To mitigate this we could use a pair of radio button.
.hamburger-menu-content {
display: none;
}
#hamburger-menu-trigger:checked {
display: none;
}
#hamburger-menu-trigger:checked+.hamburger-menu-content {
/* '+' means all elements that have the first element preceding it */
display: block;
}
<input type="radio" name="menuToggle" id="hamburger-menu-trigger">
<div class="hamburger-menu-content">
<input type="radio" name="menuToggle">
<p>Foo</p>
<p>Foo</p>
<p>Foo</p>
</div>
edit: In case you want to change the looks of the buttons you can reference this guide https://www.w3schools.com/howto/howto_css_custom_checkbox.asp

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>

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>