I'm building a responsive template with CSS Grid Layout (still learning) and thanks to a few of you on here, I've got most of it working.
mobile (max-width: 767px)
- everything should appear on its own row
tablet (min-width: 768px)
- nav is on the first row
- aside and main on the second
desktop (min-width: 992px)
- same as tablet but with 10% of spacing horizontally
xl desktop (min-width: 1920px)
- same as desktop but has a max-width of 1920px
The thing is I'm using a header
tag to color the spacing to the left and right of the nav
. Whether I use a header or a div, it doesn't seem right having an empty container just for coloring the empty space.
Is there a way of doing this in a way that lets me apply position: fixed
on the entire top section?
* {
margin: 0;
padding: 0;
}
body {
display: grid;
font-family: sans-serif;
}
a {
text-decoration: none;
color: white;
}
header,
nav {
background: blue;
color: #fff;
}
nav {
display: flex;
flex-wrap: wrap;
align-items: center;
}
nav span {
margin-right: auto;
}
header {
display: none;
}
aside {
background: lightgreen;
}
main {
background: pink;
}
/* mobile */
@media (max-width: 767px) {
body {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
nav,
aside,
main {
grid-column: 1 / 1;
padding: 0 15px;
}
}
/* tablets */
@media (min-width: 768px) {
body {
grid-template-columns: 275px 1fr;
grid-template-rows: 1fr 1fr;
}
nav {
grid-column: 1 / 4;
grid-row: 1;
height: 50px;
grid-row: 1;
}
aside {
grid-column: 1;
}
main {
grid-column: 2;
}
nav,
aside,
main {
padding: 0 15px;
}
}
/* desktops */
@media (min-width: 992px) {
body {
grid-template-columns: 10% 275px 1fr 10%;
grid-template-rows: 1fr 1fr;
}
header {
display: block;
grid-column: 1 / -1;
grid-row: 1;
}
nav {
grid-column: 2 / 4;
grid-row: 1;
}
aside {
grid-column: 2 / 3;
}
main {
grid-column: 3 / 4;
}
}
/* xl desktops */
@media (min-width: 1920px) {
body {
grid-template-columns: 1fr minmax(auto, 300px) minmax(auto, 1620px) 1fr;
grid-template-rows: 1fr 1fr;
}
}
<header></header>
<nav>
<span>Logo</span>
<a href="#">login</a>
</nav>
<aside>aside</aside>
<main>main</main>
https://jsfiddle.net/90kotz8d/1/
If I understand your intent, you are not really using header for spacing, you are really using it to get the blue background to cover all the space.
Since you seem also wanting the logo and login to vertically align with the boundaries, I don't think that there is any posible solution to do this with the nav.
So, the only solution that I could find involves using a pseudo element. At least this is more semantic. I got rid of the media queries, since now they don't play a role here:
* {
margin: 0;
padding: 0;
}
.container {
display: grid;
grid-template-columns: 10% 275px 1fr 10%;
grid-template-rows: 1fr 1fr;
}
.container::after {
content: "";
background-color: blue;
grid-column: 1 / 5;
grid-row: 1;
z-index: -1;
}
a {
text-decoration: none;
color: white;
}
nav {
background: blue;
color: #fff;
display: flex;
flex-wrap: wrap;
align-items: center;
}
nav span {
margin-right: auto;
}
header {
display: none;
}
aside {
background: lightgreen;
}
main {
background: pink;
}
nav {
grid-column: 2 / 4;
grid-row: 1;
}
aside {
grid-column: 2 / 3;
}
main {
grid-column: 3 / 4;
}
<div class="container">
<nav>
<span>Logo</span>
<a href="#">login</a>
</nav>
<aside>aside</aside>
<main>main</main>
</div>
I guess, this is something, what you want. I have used grid-column: 1 / 8;
in the @media (min-width: 992px)
and added manual padding on both sides. I hope, without this solution, till now no more options you are having without using extra <div>
, <header>
or any other containers.
* {
margin: 0;
padding: 0;
}
body {
display: grid;
font-family: sans-serif;
}
a {
text-decoration: none;
color: white;
}
header,
nav {
background: blue;
color: #fff;
}
nav {
display: flex;
flex-wrap: wrap;
align-items: center;
}
nav span {
margin-right: auto;
}
header {
display: none;
}
aside {
background: lightgreen;
}
main {
background: pink;
}
/* mobile */
@media (max-width: 767px) {
body {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
nav,
aside,
main {
grid-column: 1 / 1;
padding: 0 15px;
}
}
/* tablets */
@media (min-width: 768px) {
body {
grid-template-columns: 275px 1fr;
grid-template-rows: 1fr 1fr;
}
nav {
grid-column: 1 / 4;
grid-row: 1;
height: 50px;
grid-row: 1;
}
aside {
grid-column: 1;
}
main {
grid-column: 2;
}
nav,
aside,
main {
padding: 0 15px;
}
}
/* desktops */
@media (min-width: 992px) {
body {
grid-template-columns: 10% 275px 1fr 10%;
grid-template-rows: 1fr 1fr;
}
nav {
grid-column: 1 / 8;
grid-row: 1;
padding-right: 11.3vw;
padding-left: 11.3vw;
}
aside {
grid-column: 2 / 3;
}
main {
grid-column: 3 / 4;
}
}
/* xl desktops */
@media (min-width: 1920px) {
body {
grid-template-columns: 1fr minmax(auto, 300px) minmax(auto, 1620px) 1fr;
grid-template-rows: 1fr 1fr;
}
}
<nav>
<span>Logo</span>
<a href="#">login</a>
</nav>
<aside>aside</aside>
<main>main</main>
From what I can see, you might need to add a rule saying it is display: block;
before you can add the position: fixed
rule, because I am pretty sure <header>
s are inline elements.
You could also try and add media queries, linking to different stylesheets, that display different tables, using the display: tableRow;
, tableCell
and table
values.
Hope this works