I have a simple CSS grid.
I would like to have the #right and the main element under each other on a mobile view (800px width).
I thought that adding this:
main,
#right {
grid-column: 2 / span 2;
}
would put the main and #right element under each other, but no such luck. It seems they both have a 100% height causing them to overlap.
So what I would like to see is:
main {
margin-top: 90%;
height: 50%;
}
#right {
height: 50%;
}
But then of course caused by the CSS grid.
https://plnkr.co/edit/J0gZRP9LUak4n6eebnhh?p=preview
body,
html {
height: 100%;
}
#grid-wrapper {
height: 100vh;
display: grid;
grid-template: "header header header" 66px "subheader subheader subheader" 55px "left main right" auto / 18.75% auto 25%;
}
header {
grid-area: header;
display: grid;
grid-template: "logo searchbar hamburgermenu" auto / 18.75% auto 25%;
}
header #logo {
grid-area: logo;
background: red;
}
header #searchbar {
grid-area: searchbar;
background: yellow;
}
header #hamburgermenu {
grid-area: hamburgermenu;
background: teal;
}
.subheader {
grid-area: subheader;
display: grid;
grid-template: ". telephone-content ." auto / 18.75% auto 25%;
background: wheat;
}
.subheader .telephone-content {
grid-area: telephone-content;
background: lightcoral;
}
#left {
grid-area: left;
background: darkgray;
}
main {
grid-area: main;
background: lightskyblue;
}
#right {
grid-area: right;
background: lightsalmon;
}
/* TABLET VIEW */
#media screen and (max-width: 1024px) {
header {
grid-template: "logo searchbar hamburgermenu" auto / 6.75% auto 25%;
}
.subheader {
grid-template: ". telephone-content ." auto / 6.75% auto 25%;
}
#grid-wrapper {
grid-template: "header header header" 66px "subheader subheader subheader" 55px "left main right" auto / 6.75% auto 25%;
}
}
/* MOBILE VIEW */
#media screen and (max-width: 800px) {
header {
grid-template: "logo searchbar hamburgermenu" auto / 66px auto 66px;
}
.subheader {
grid-template: "telephone-content telephone-content telephone-content" auto / 66px auto 66px;
}
#grid-wrapper {
grid-template: "header header header" 66px "subheader subheader subheader" 55px "left main right" auto / 6.75% auto 25%;
}
#left {
/* grid-row: 1 / span 2; */
}
#right {
/* grid-column: 2 / 3; */
}
main,
#right {
grid-column: 2 / span 2;
}
}
<div id="grid-wrapper">
<header>
<div id="logo">
<h1>Logo</h1>
</div>
<div id="searchbar">
<p>Header stuff</p>
</div>
<div id="hamburgermenu">
<h1>...</h1>
</div>
</header>
<div class="subheader">
<p class="telephone-content">Dit is telefoon informatie</p>
</div>
<aside id="left">
<h1>Left</h1>
</aside>
<main>
<h1>Content</h1>
<p>Saaie boel</p>
</main>
<aside id="right">
<h1>Right</h1>
</aside>
</div>
</div>
This is what you have in your mobile view:
#media screen and (max-width: 800px) {
#grid-wrapper {
grid-template: "header header header" 66px
"subheader subheader subheader" 55px
"left main right" auto / 6.75% auto 25%;
}
This layout produces three rows and three columns.
row heights: 66px 55px auto
column widths: 6.75% auto 25%
But you want right to appear underneath main (or vice versa?). So try this instead:
#media screen and (max-width: 800px) {
#grid-wrapper {
grid-template: "header header header" 66px
"subheader subheader subheader" 55px
"left main main" auto /* adjustment */
"left right right" auto /* new row */
/ 6.75% auto 25%;
}
https://plnkr.co/edit/X3nlF5Jx3vSdUm52DoyZ?p=preview
Related
I have seen names within square brackets in a site's CSS:
/* simplified example */
body {
grid-template-columns:
[main-menu]
20%
[content]
40%
[asides]
20%
[ads]
20%
;
}
MDN's documentation explains that these are custom identifiers and that one can add many of them within the square brackets.
Yet it does not talk about why one would use them and which effect this has. My first guess was that they are cosmetic and help to structure the code. But deleting these lines, or replacing them with a value like 0 or auto changes the layout.
Why would one use them? Which effect do they have?
A self-explanatory example
body {
display: grid;
grid-template-columns:
[main-menu]
20%
[content]
40%
[asides]
20%
[ads]
20%
;
}
.ads {
grid-area: ads; /* I will get placed at the line called "ads" in the template */
height: 100px;
background: red;
}
<div class="ads"></div>
[linename]
A <custom-ident> specifying a name for the line in that location. ref
<custom-ident>
If there is a named line with the name '<custom-ident>-start/<custom-ident>-end', it contributes the first such line to the grid item's placement. ref
I think I figured it out.
The square-bracket-syntax ...
body {
display: grid;
grid-template-columns:
[menu]
20%
[content]
60%
[aside]
20%
;
}
... is an alternative for using grid-template-areas:
body {
display: grid;
grid-template-columns:
20%
60%
20%
;
grid-template-areas:
"menu content aside"
;
}
Here a more complex 2-dimensional layout example, using the square-bracket syntax ...
body {
margin:0;
width: 100vw;
height:100vh;
display: grid;
grid-template-columns:
[left] 20%
[center] 60%
[right] 20%
;
grid-template-rows:
[top] 20%
[middle] 60%
[bottom] 20%
;
}
.header {
grid-area: top / left / top-end / right-end;
background: yellow;
}
.menu {
grid-area: middle / left / middle-end / left-end;
background: lime;
}
.content {
grid-area: middle / center / middle-end / center-end;
background: skyblue;
}
.aside {
grid-area: middle / right / middle-end / right-end;
background: orange;
}
.footer {
grid-area: bottom / left / bottom-end / right-end;
background: forestgreen;
}
<div class="header"></div>
<div class="menu"></div>
<div class="content"></div>
<div class="aside"></div>
<div class="footer"></div>
... and the same example, but using grid-template-areas:
body {
margin:0;
width: 100vw;
height:100vh;
display: grid;
grid-template-columns:
20%
60%
20%
;
grid-template-rows:
20%
60%
20%
;
grid-template-areas:
"header header header"
"menu content aside"
"footer footer footer"
;
}
.header {
grid-area: header;
background: yellow;
}
.menu {
grid-area: menu;
background: lime;
}
.content {
grid-area: content;
background: skyblue;
}
.aside {
grid-area: aside;
background: orange;
}
.footer {
grid-area: footer;
background: forestgreen;
}
<div class="header"></div>
<div class="menu"></div>
<div class="content"></div>
<div class="aside"></div>
<div class="footer"></div>
In my opinion, the grid-template-areas variant is simpler to use. The square bracket syntax probably has its use case, though I currently can not think of one.
The red sidebar in this page needs to be 100% of the container height:
body {
display: grid;
min-height: 85vh;
grid-template-columns: auto 10fr 4fr;
grid-template-rows: minmax(1rem, max-content) 1fr minmax(1rem, max-content);
grid-template-areas: "header header aside" "main main aside" "footer footer footer";
}
header {
grid-area: header;
background: pink;
}
footer {
grid-area: footer;
background: blue;
}
main {
grid-area: main;
background: green;
}
aside {
grid-area: aside;
background: red;
height: 100px;
overflow-y: scroll;
}
<header> header </header>
<main>main</main>
<aside>
aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>
</aside>
<footer> footer </footer>
Can this be achieved without adding another inner element with 100% height absolute position ?
note that I added 100px height to it just to point out that it needs to be scrollable. But I want the height to be 100% of container...
Use min-height: 100%;height:0; to avoid the height of the aside affecting the layout then force it to be 100% height at the same time (height of its track defined by the other content)
body {
display: grid;
min-height: 85vh;
grid-template-columns: auto 10fr 4fr;
grid-template-rows:
minmax(1rem, max-content) 1fr minmax(1rem, max-content);
grid-template-areas:
"header header aside"
"main main aside"
"footer footer footer";
}
header {
grid-area: header;
background: pink;
}
footer {
grid-area: footer;
background: blue;
}
main {
grid-area: main;
background: green;
}
aside {
grid-area: aside;
background: red;
min-height: 100%;
height:0;
overflow-y: scroll;
}
<header> header </header>
<main>main</main>
<aside>
aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>
</aside>
<footer> footer </footer>
You can add the exact height that uses on the grid container and then add overflow-y: scroll
body {
display: grid;
min-height: 75vh;
grid-template-columns: auto 10fr 4fr;
grid-template-rows: minmax(1rem, max-content) 1fr minmax(1rem, max-content);
grid-template-areas: "header header aside" "main main aside" "footer footer footer";
}
header {
grid-area: header;
background: pink;
}
footer {
grid-area: footer;
background: blue;
}
main {
grid-area: main;
background: green;
}
aside {
height: 100%;
grid-area: aside;
background: red;
max-height: 75vh;
overflow-y: scroll;
z-index: 1;
}
<header> header </header>
<main>main</main>
<aside>
aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>aside<br>
</aside>
<footer> footer </footer>
I am new to css grid I try to achieve the layout from the image attached where ONE element DIV 4 is wider than the grid layout. I try to avoid to close the grid-div before DIV 4 and then reopen the grid after DIV 4 again so I can controll the appearance of each grid element and how it is displayed through ONE css-class only and it won't need a different div-structure.
https://codepen.io/anon/pen/RBdjbd
.grid-2er {
grid: auto-flow dense / 1fr 1fr;
display: grid;
grid-gap: 20px;
grid-auto-rows: auto;
}
.grid-2er .halfwidth {
grid-column: 1 / -1;
}
.grid-2er .fullwidth {
grid-column: 1 / -1;
}
Might I suggest a four column grid
grid-template-columns: 1fr minmax(0, 400px) minmax(0, 400px) 1fr;
Codepen Demo
* {
margin: 0;
padding: 0;
text-decoration: none;
outline: none;
font-weight: 300;
border: none;
font-family: "Source Sans Pro", sans-serif;
text-align: center;
}
*,
*::after,
*::before {
box-sizing: border-box;
}
.grid-2er {
grid-template-columns: 1fr minmax(0, 400px) minmax(0, 400px) 1fr;
display: grid;
grid-gap: 20px;
grid-auto-rows: auto;
}
.grid-2er * {
background: blue;
color: white
}
.grid-2er .mainwidth {
grid-column: 2 / 4;
}
.grid-2er .halfwidth {
grid-column: 2;
}
.halfwidth+.halfwidth {
grid-column: 3;
}
.grid-2er .fullwidth {
grid-column: 1 / -1;
}
<div class="grid-2er">
<div class="mainwidth">DIV 1</div>
<div class="halfwidth">DIV 2</div>
<div class="halfwidth">DIV 3</div>
<div class="fullwidth">DIV 4</div>
<div class="halfwidth">DIV 5</div>
<div class="halfwidth">DIV 6</div>
</div>
You can use negative margin. If the width of the whole grid is maximized to 800px then you can have a negative margin of (800px - 100vw)/2 on each side. Then when the size of the window is less than 800px you reset margin to 0:
Here is an example (I used 600px in this case)
* {
margin: 0;
padding: 0;
font-weight: 300;
border: none;
font-family: "Source Sans Pro", sans-serif;
text-align: center;
padding: 10px;
}
*,
*::after,
*::before {
box-sizing: border-box;
}
.grid-2er {
grid: auto-flow dense / 1fr 1fr;
display: grid;
grid-gap: 20px;
grid-auto-rows: auto;
max-width: 600px;
margin: auto;
}
.grid-2er .halfwidth {
grid-column: 1 / -1;
background: blue;
color: white
}
.grid-2er .fullwidth {
grid-column: 1 / -1;
background: blue;
color: white
}
.outside {
margin: 0 calc((600px - 100vw)/2);
}
#media only screen and (max-width: 600px) {
.outside {
margin: 0;
}
}
#media only screen and (min-width: 480px) {
.grid-2er .halfwidth {
grid-column: auto;
}
.grid-2er .fullwidth .tile {
width: 50%;
}
}
<div class="grid-2er">
<div class="fullwidth ">
DIV 1
</div>
<div class="halfwidth">
DIV 2
</div>
<div class="halfwidth">
DIV 3
</div>
<div class="fullwidth outside">
DIV 4
</div>
<div class="halfwidth">
DIV 5
</div>
<div class="halfwidth">
DIV 6
</div>
</div>
Use calc to get the value of your gutter. The width of the gutter is half the width of it's container minus half the width of the content container. In your case the math is calc(50% - 400px). I like to add a minmax to keep the gutter from collapsing completely but you can ignore that if you don't need it. This frees you up to use 1fr for your interior columns so they are responsive and you can change the number of columns without having to recalculate their widths.
.content {
display: grid;
grid-template-columns: calc(50% - 400px) repeat(2, 1fr) calc(50% - 400px);
gap: 1rem;
}
.column {
text-align: center;
background-color: #ddd;
}
.--column1 {
grid-column: 2 / 3;
}
.--column2 {
grid-column: 3 / 4;
}
.--columnfull {
grid-column: 1 / 5;
}
<div class="container">
<div class="content">
<div class="column --column1">column</div>
<div class="column --column2">column</div>
<div class="column --columnfull">column</div>
</div>
</div>
I am trying to build a layout with a full-width header, then two 150px wide ad blocks stacked vertically on the left, the main part in the center, then two more ad blocks stacked vertically on the right, with a full-width footer at the bottom.
The code I expected to work is
.container {
display: grid;
grid-gap: 2px;
background-color: black;
padding: 2px;
min-height: 300px;
width: 100%;
margin: 0 auto;
--nav-width: 250px;
}
.container {
grid-template-columns: 150px 1fr 150px; /*Three columns - 150px for the ads; rest of screen for main */
grid-template-rows: 200px 1fr 1fr 40px;
grid-template-areas:
"header header header"
"left_ad1 main right_ad1"
"left_ad2 main right_ad2"
"footer footer footer";
}
.header {
background:PaleTurquoise;
}
.nav {
background:LightPink;
}
.content {
background:red;
}
.footer {
background:blue;
}
div {
font-size: 28px;
}
body {
text-align: center;
}
.ad {
height: 250px;
}
header {
background: LightSalmon;
}
#left_ad1 {
background:PaleTurquoise;
grid-area: left_ad1;
}
#left_ad2 {
background:PaleTurquoise;
grid-area: left_ad2;
}
#right_ad1 {
background:LightPink;
grid-area: right_ad1;
}
#right_ad2 {
background:LightPink;
grid-area: right_ad2;
}
main {
background-color: red;
grid-area: main;
}
footer {
background: LightSkyBlue;
grid-area: footer;
}
<div class="container">
<header>Header</header>
<div id="left_ad1">Left ad 1</div>
<main>Main</main>
<div id="right_ad1" class="ad">Right ad 1</div>
<div id="left_ad2" class="ad">Left ad 2</div>
<div id="right_ad2" class="ad">Right ad 2</div>
<footer>Footer</footer>
</div>
but this makes the header fill just the left-most cell of the top row.
I can get it to work by adding
header {
grid-column: 1 / 4;
}
to force the header to span the whole width of the grid, but surely that shouldn't be needed? The use of grid-template-areas: "header header header" should achieve that without the use of grid-column shouldn't it?
Confused! Any help appreciated!
You need to specify grid-area: header; on your header element.
.container {
display: grid;
grid-gap: 2px;
background-color: black;
padding: 2px;
min-height: 300px;
width: 100%;
margin: 0 auto;
--nav-width: 250px;
}
.container {
grid-template-columns: 150px 1fr 150px; /*Three columns - 150px for the ads; rest of screen for main */
grid-template-rows: 200px 1fr 1fr 40px;
grid-template-areas:
"header header header"
"left_ad1 main right_ad1"
"left_ad2 main right_ad2"
"footer footer footer";
}
div {
font-size: 28px;
}
body {
text-align: center;
}
.ad {
height: 250px;
}
header {
background: LightSalmon;
grid-area: header;
}
#left_ad1 {
background:PaleTurquoise;
grid-area: left_ad1;
}
#left_ad2 {
background:PaleTurquoise;
grid-area: left_ad2;
}
#right_ad1 {
background:LightPink;
grid-area: right_ad1;
}
#right_ad2 {
background:LightPink;
grid-area: right_ad2;
}
main {
background-color: red;
grid-area: main;
}
footer {
background: LightSkyBlue;
grid-area: footer;
}
<div class="container">
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
<div id="left_ad1">Left ad 1</div>
<div id="left_ad2" class="ad">Left ad 2</div>
<div id="right_ad1" class="ad">Right ad 1</div>
<div id="right_ad2" class="ad">Right ad 2</div>
</div>
I have an article and an aside (sidebar) element - easy, except the title and sub-heading of the article need to span the entire row. If I take the title/sub-heading out of the article, the article element is no longer semantically complete.
Is there a way, using CSS Grid, to have the format below, where Title, Sub and Content are all a part of an "Article" element, and "Aside" is the second in a 2 column grid?
From my research so far, it seems this is not possible.
You can hack your way through using nested CSS grid if you know:
The width of the aside section
The height of the title and sub heading sections
(in many layouts, these dimensions are fixed)
You can use a pseudo element that create a space for the aside element and then sneak it inside the outer grid container - check out the demo below:
body {
margin: 0;
}
* {
box-sizing: border-box;
}
article,
aside {
border: 1px solid;
display: flex;
align-items: center;
justify-content: center;
}
div {
display: grid;
grid-template-areas: "section aside";
}
section {
grid-area: section;
display: grid;
grid-template-areas: "header header" "subhead subhead" "content empty";
grid-template-rows: 50px 50px auto;
grid-template-columns: 80vw auto;
height: 100vh;
width: 100vw;
}
section article:first-child {
grid-area: header;
}
section article:nth-child(2) {
grid-area: subhead;
}
section article:last-child {
grid-area: content;
}
section:after {
content: '';
display: block;
grid-area: empty;
}
aside {
grid-area: aside;
height: calc(100vh - 100px);
width: 20vw;
align-self: flex-end;
position:relative;
transform: translateX(-100%);
}
<div>
<section>
<article>Article title</article>
<article>Article sub-heading</article>
<article>Article content</article>
</section>
<aside>Aside</aside>
</div>
You can use something like this.
* {box-sizing: border-box;}
.wrapper {
max-width: 940px;
margin: 0 auto;
}
.wrapper > div {
border: 2px solid rgb(233,171,88);
border-radius: 5px;
background-color: rgba(233,171,88,.5);
padding: 10px;
color: #d9480f;
}.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column: 1 / 4;
grid-row: 1;
}
.two {
grid-column: 1 / 4;
grid-row: 2;
}
.three {
grid-column: 1 / 3;
grid-row: 3;
min-height:200px;
}
.four {
grid-column: 3;
grid-row: 3;
min-height:200px;
}
<div class="wrapper">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Also check Fiddle.
And for more details please visit https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
You can achieve that by simply floating all the cells, as long as the article doesn't float - https://jsfiddle.net/yxbckzcq/1/
<div class="wrapper">
<article>
<div style="float:left;width:100%" class="one">One</div>
<div style="float:left;width:100%" class="two">Two</div>
<div style="float:left;width:70%" class="three">Three</div>
</article>
<div style="float:left;width:30%" class="four">Four</div>
</div>