So I'm trying to set up a grid-formatted website page with pure HTML and CSS, as you will see in my code below.
I'm trying to alternate between two div tags going down the left hand column of Header & inner-placeholder tags.
You will see the HTML layout alignment with the grid-template-area clearly laid out, along with the number of rows as specified by grid-template-rows
So why do I get just a red box at the corner of the screen when it's fairly obvious what I want to have as per the illustration - except for a curved box followed by a straight box, followed by a curved box etc going down the left hand side?
I have tried to change the fr number to accommodate the number of rows on the left hand side.
Thank you.
Illustration
.grid{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-areas:
"Title Title"
"Header Content"
"inner-placeholder Content"
"Header Content"
"inner-placeholder Content"
"Sidebar Content"
"Footer Footer";
grid-gap: 10px;
}
.Title{
grid-area: Title;
}
.Header{
grid-area: Header;
}
.Sidebar{
grid-area: Sidebar;
}
.Content{
grid-area: Content;
}
.Footer{
grid-area: Footer;
}
.inner-placeholder{
grid-area: inner-placeholder;
}
.grid div:nth-child(even){
background-color: red;
}
.grid div:nth-child(odd){
background-color: green;
}
<div class="grid">
<div class="Title">Title
</div>
<div class="Header">Header
</div>
<div class="inner-placeholder">
</div>
<div class="Header">Header
</div>
<div class="inner-placeholder">
</div>
<div class="Sidebar">Sidebar
</div>
<div class="Content">Content
</div>
<div class="Footer">Footer
</div>
</div>
It seems you misunderstood how grid areas work. If any grid area spans more than 1 row or column, it needs to form a square or a rectangle. Which means they also need to be in one continuous sequence as a 2x2 or 1x3 and so on, in your case you split the Header area and placeholder area between each other, which breaks the grid.
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(7, 1fr);
grid-template-areas:
"Title Title"
"Header Content"
"inner-placeholder Content"
"Header2 Content"
"inner-placeholder2 Content"
"Sidebar Content"
"Footer Footer";
grid-gap: 10px;
}
.Title {
grid-area: Title;
}
.Header {
grid-area: Header;
}
.Header2 {
grid-area: Header2;
}
.Sidebar {
grid-area: Sidebar;
}
.Content {
grid-area: Content;
}
.Footer {
grid-area: Footer;
}
.inner-placeholder {
grid-area: inner-placeholder;
}
.inner-placeholder2 {
grid-area: inner-placeholder2;
}
.grid div:nth-child(even) {
background-color: red;
}
.grid div:nth-child(odd) {
background-color: green;
}
<div class="grid">
<div class="Title">Title</div>
<div class="Header">Header</div>
<div class="inner-placeholder"></div>
<div class="Header2">Header2</div>
<div class="inner-placeholder2"></div>
<div class="Sidebar">Sidebar</div>
<div class="Content">Content</div>
<div class="Footer">Footer</div>
</div>
Related
.grid-container {
display: grid;
grid-gap: 10px;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr 1fr;
}
.grid-item {
background: blue;
height: 100px;
}
.grid-item .item1 {
grid-row-start: 1;
grid-row-end: 3;
}
<div class="grid-container">
<div class="grid-item"> </div>
<div class="grid-item item1"> </div>
<div class="grid-item"> </div>
</div>
I have this, but it's not what I want
What I don't want
I want this, see this following picture :
What I want
Remove the height from the grid-items and set the rows to be 100px.
Then tell the "tall" item to be in column 2
.grid-container {
display: grid;
gap: 10px;
grid-template-columns: 2fr 1fr;
grid-auto-rows: 100px;
}
.grid-item {
background: blue;
}
.grid-item.item1 {
grid-column:2;
grid-row: 1 / span 2;
}
<div class="grid-container">
<div class="grid-item"> </div>
<div class="grid-item item1"> </div>
<div class="grid-item"> </div>
</div>
At first, You have a typo .grid-item .item1 , .item1 is not a child of .grid-item . You need to remove that space in between classnames : .grid-item.item1.
beside you have also to reset height for .item1 so it can grow the entire rows it spans, and if you also set in which columns it should stand, it avoids to see it elsewhere.
To help you debug your css, give different background-color to your items to see exactly where they stand.
possible CSS fix
.grid-container {
display: grid;
grid-gap: 10px;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr 1fr;
}
.grid-item {
background: blue;
height: 100px;
}
.grid-item.item1 {
grid-row-start:1;
grid-row-end:3;
grid-column:2;
height:auto;
background:red;
}
<div class="grid-container">
<div class="grid-item"> </div>
<div class="grid-item item1"> </div>
<div class="grid-item"> </div>
</div>
CSS Grid Layout excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer, between parts of a control built from HTML primitives.
So you setting height of grid-item is wrong, because it defeats the whole purpose of grid, which is to assign area to grid childrens based upon the layout divided by grid-lines.
.grid-container {
display: grid;
grid-gap: 10px;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr 1fr;
height:200px;
}
.grid-item {
background: blue;
}
.item1 {
grid-row: 1/3;
grid-column: 2/3;
}
<div class="grid-container">
<div class="grid-item"> </div>
<div class="grid-item item1"> </div>
<div class="grid-item"> </div>
</div>
See image to see how it is now. I want the yellow part (.content) to push the bottom black part (.footer) down and expand to take up all remaining screen space (horizontal and vertical). But as you can see, it does neither. Code at the bottom, after this image:
.container {
height: 100vh;
width: 100vh;
display: grid;
grid-template-columns: 1fr 5fr 1fr;
grid-template-rows: 2fr 9fr 1fr;
grid-template-areas:
"h h h"
"c c c"
"f f f";
}
.header {
background-color: #000000;
grid-area: h;
justify-items: center;
}
.content {
background-color: #ffff00;
grid-area: c;
}
.footer {
background-color: #000000;
grid-area: f;
justify-self: end;
align-self: end;
}
<div class="container">
<div class="header">
<div><a href="index.asp">
<img src="images/title-img-640.png" class="logo" alt="Play to Evolve" title="Play to Evolve">
</a></div>
</div>
<div class="content">
What is your reaction to receiving criticism?
<div>
<div class="footer">
<div class="textFooterSmall">
Copyright 2019 ClearSay.net<br>
</div>
<div></div>
<div class="textFooterSmall">
design by <a class="footerlinkSmall" href="http://www.OceanMedia.net" target="_blank">OceanMedia.net</a><br>
<a class="footerlinkSmall" href="admin_menu.asp">admin</a>
</div>
</div>
</div>
Thank you for any ideas you can share!
Scott
The principal problem is that your .content element doesn't have a closing div.
<div class="content">What is your reaction to receiving criticism?<div>
Another problem is that width: 100vh doesn't give you the full width you expect.
.container {
height: 100vh;
width: 100vh;
display: grid;
...
...
}
You're using viewport height units for width. I think you wanted vw.
But in the end, you don't need any of it, as block elements take full width by default.
Also, if you want full width, you don't need end values.
.footer {
background-color: #000000;
grid-area: f;
justify-self: end;
align-self: end;
}
.container {
height: 100vh;
display: grid;
grid-template-columns: 1fr 5fr 1fr;
grid-template-rows: 2fr 9fr 1fr;
grid-template-areas: "h h h"
"c c c"
"f f f";
}
.header {
grid-area: h;
background-color: #000000;
}
.content {
grid-area: c;
background-color: #ffff00;
}
.footer {
grid-area: f;
background-color: #000000;
}
body {
margin: 0;
}
<div class="container">
<div class="header">
<div>
<a href="index.asp">
<img src="images/title-img-640.png" class="logo" alt="Play to Evolve" title="Play to Evolve">
</a>
</div>
</div>
<div class="content">
What is your reaction to receiving criticism?
</div>
<div class="footer">
<div class="textFooterSmall">
Copyright 2019 ClearSay.net<br>
</div>
<div></div>
<div class="textFooterSmall">
design by <a class="footerlinkSmall" href="http://www.OceanMedia.net" target="_blank">OceanMedia.net</a><br>
<a class="footerlinkSmall" href="admin_menu.asp">admin</a>
</div>
</div>
</div>
I have made a blog design using CSS grid, having used inline-block to pack DIVs together.
In my blog I have 2 picture-DIVS of height 60 that I want to show next to a text-DIV of height 120. Only the first picture is shown next to the text.
Why is the second picture shown below the text, and please get some pointers on how I can fix this.
.GridCont {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto auto auto;
grid-template-areas: "content content content content" "content content content content" "content content content content";
}
.PostContent {
grid-area: content;
background: #B8E986;
}
.Content {
background: #000000;
width: 35%;
color: white;
display: inline-block;
}
.box1 {
height: 120vh;
}
.PicContent {
background: blue;
color: white;
display: inline-block;
}
.pic1 {
height: 60vh;
width: 50%;
}
.pic2 {
height: 60vh;
width: 45%;
}
.cTextP {
padding: 20px;
}
<div class="GridCont">
<div class="PostContent">
<div class="PicContent pic1">
<div class="cTextP">Picture #1</div>
</div>
<div class="Content box1">
<div class="cTextP">Content #1</div>
</div>
<div class="PicContent pic2">
<div class="cTextP">Picture #2</div>
</div>
</div>
</div>
Code is at this JS-fiddle
Why would the second image show right beneath the first? There is no reason for that.
The second image is on the second row.
The second row goes right beneath the first row.
More specifically, the first row is occupied by two elements: image #1 and the content box. The height of the first row is defined by the tallest element. In this case, that would the content box.
So, because image #1 doesn't extend the full height of row #1, there will be a gap between images.
Here's an even more detailed explanation of the problem:
Is it possible for flex items to align tightly to the items above them?
(It's a flexbox-related post, but the logic applies here, as well.)
Instead of inline-block, use Grid properties to get the content box to span both rows:
.PostContent {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 60vh 60vh;
grid-gap: 1em;
grid-template-areas: " pic1 box1 "
" pic2 box1 ";
}
.box1 {
grid-area: box1;
}
.pic1 {
grid-area: pic1;
}
.pic2 {
grid-area: pic2;
}
.PostContent { background: #B8E986; }
.PicContent { background: blue; color: white; }
.Content { background: #000000; color: white; }
.cTextP { padding: 20px;}
<div class="GridCont">
<div class="PostContent">
<div class="PicContent pic1">
<div class="cTextP">Picture #1</div>
</div>
<div class="Content box1">
<div class="cTextP">Content #1</div>
</div>
<div class="PicContent pic2">
<div class="cTextP">Picture #2</div>
</div>
</div>
</div>
revised jsfiddle
Also note that grid properties work only between parent and child elements.
This will fix your problem:
<div class="grid-container">
<div class="image1"></div>
<div class="image2"></div>
<div class="text"></div>
</div>
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "image1 image1 text text" "image2 image2 text text";
}
.image1 { grid-area: image1; }
.image2 { grid-area: image2; }
.text { grid-area: text; }
You can see the working example over here:
https://codepen.io/dennisperremans/pen/NeqNJp
I have a card built with CSS Grid layout. There might be an image to the left, some text to the right top and maybe a button or a link at the right bottom.
In the code below, how can I make the green area take up as much space as possible and at the same time make the blue area take up as little space as possible?
The green should push the blue area down as far as possible.
https://jsfiddle.net/9nxpvs5m/
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"one two"
"one three"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.two {
background: green;
grid-area: two;
}
.three {
background: blue;
grid-area: three;
}
<div class="grid">
<div class="one">
One
</div>
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
Adding grid-template-rows: 1fr min-content; to your .grid will get you exactly what you're after :).
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr min-content;
grid-template-areas:
"one two"
"one three"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.two {
background: green;
grid-area: two;
}
.three {
background: blue;
grid-area: three;
}
<div class="grid">
<div class="one">
One
</div>
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
Jens edits: For better browser support this can be used instead: grid-template-rows: 1fr auto;, at least in this exact case.
A grid is a series of intersecting rows and columns.
You want the two items in the second column to automatically adjust their row height based on their content height.
That's not how a grid works. Such changes to the row height in the second column would also affect the first column.
If you must use CSS Grid, then what I would do is give the container, let's say, 12 rows, then have items span rows as necessary.
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: repeat(12, 15px);
}
.one {
grid-row: 1 / -1;
background: red;
}
.two {
grid-row: span 10;
background: lightgreen;
}
.three {
grid-row: span 2;
background: aqua;
}
.grid > div {
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
</div>
Otherwise, you can try a flexbox solution.
.grid {
display: flex;
flex-flow: column wrap;
height: 200px;
}
.one {
flex: 0 0 100%;
width: 30%;
background: red;
}
.two {
flex: 1 0 1px;
width: 70%;
background: lightgreen;
}
.three {
background: aqua;
}
.grid>div {
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
</div>
When using grid, and you have grid template area used, and by chance you gave a particular area a width, you are left with a space grid does automatically.
In this situation, let grid-template-columns be either min-content or max-content, so that it adjusts its position automatically.
A possible approach might be grouping two and three together, and using flexbox:
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas: "one two"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.wrap {
grid-area: two;
display: flex;
flex-direction: column;
}
.two {
background: green;
flex: 1;
}
.three {
background: blue;
}
<div class="grid">
<div class="one">
One
</div>
<div class="wrap">
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
</div>
Definitely not the most elegant solution and probably not best practice, but you could always add more lines of
"one two"
before the part where you have
"one three"
so it ends up looking like
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"one two"
"one two"
"one two"
"one three"
}
Again, pretty sure this is just a work around and there's better solutions out there... But this does work, to be fair.
Just use width: 100% and height: 100% in the CSS class of the item you want to fill the grid. Join a max-width property and a max-height property if you don't want a grid item inside a grid container to grow more than some size.
I want to make my website using CSS grid system but it seems not to be working. Here is my code:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" "about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
When using the grid-template-areas property, string values must have the same number of columns.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" "about-us about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
You can use a period, or an unbroken line of periods, to represent an empty cell (spec reference).
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" " ... about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
From the Grid spec:
7.3. Named Areas: the grid-template-areas
property
All strings must have the same number of columns, or else the declaration is invalid.
If a named grid area spans multiple grid cells, but those cells do not form a single filled-in rectangle, the declaration is invalid.
Non-rectangular or disconnected regions may be permitted in a future version of this module.
Note: As stated in the spec, in addition to an equal number of columns, grid areas must also be rectangular (see this post for more details).
If this:
Is the desired result, then you've only made a minor error.
You've set the grid to be a 2 x 2 square here:
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
But you aren't filling all the space.
grid-template-areas: "logo faq", "about-us";
That line of code is saying "In the top two squares put logo and faq respectively. In the bottom two rows put about-us" and that causes an error. If you want one grid-area to fill the entire space then you need to declare it twice. Thus the above line becomes:
grid-template-areas: "logo faq", "about-us about-us";
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq", "about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>