Container with grid layout and grid area - css

Hello I'm trying to make a container grid with grid areas to achieve this goal:
But I am having difficulties in defining the areas of the father and the children.
.grid_layout {
display: grid;
grid-template-areas:
"a b c"
"a d e";
grid-gap: 6px;
grid-template-columns: 1fr fr 1fr;
height: 100%;
}
<div className="grid_layout">
<div className="a" />
<div className="b" />
<div className="c" />
</div>

You don't need template areas to accomplish this...but you do need six columns.
.grid_layout {
display: grid;
grid-gap: 6px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: auto;
width: 80%;
margin: 1em auto;
}
.item {
display: flex;
justify-content: center;
align-items: center;
background: lightgreen;
border: 1px solid green;
padding: 1em;
}
.item:nth-child(1),
.item:nth-child(2),
.item:nth-child(3) {
grid-column: span 2;
}
<div class="grid_layout">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>

if you want to use areas , you still need to relay on 6 columns as stated in the comments.
.grid_layout {
display: grid;
grid-template-areas:
"a a b b c c "
"d e f g h i";
/*grid-template-columns:repeat(6,1fr); if you need this */
grid-gap: 6px;
height: 100%;/* 100% of what here ? parent has no height set*/
grid-auto-flow:row dense
}
img {width:100%;/* of the grid cell defined */}
img:nth-child(1) {
grid-area:a ;
}
img:nth-child(2) {
grid-area:b;
}
img:nth-child(3) {
grid-area:c;
}
img:nth-child(4) {
grid-area:d;
}
img:nth-child(5) {
grid-area:e;
}
img:nth-child(6) {
grid-area:f;
}
img:nth-child(7) {
grid-area:g;
}
img:nth-child(8) {
grid-area:h;
}
img:nth-child(9) {
grid-area:i;
}
<div class="grid_layout">
<img src="http://dummyimage.com/300x150/456">
<img src="http://dummyimage.com/300x150/789">
<img src="http://dummyimage.com/300x150/029">
<img src="http://dummyimage.com/300x150/fa0">
<img src="http://dummyimage.com/300x150/bad">
<img src="http://dummyimage.com/300x150/g0d">
<img src="http://dummyimage.com/300x150/f00">
<img src="http://dummyimage.com/300x150/555">
<img src="http://dummyimage.com/300x150/0af">
</div>
For a repeating pattern, grid-template-areas is not at best, but grid-template-columns would be better helped with grid-auto-flow:row dense; while telling text to span 2columns.
possible example :
.grid_layout {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: 6px;
height: 100%;
/* 100% of what here ? parent has no height set*/
grid-auto-flow: row dense;
}
p {
border: solid;
margin: 0;
}
img {
width: 100%;
}
.a {
grid-column: 1 / span 2;
text-align: center;
}
.b {
grid-column: 3 / span 2;
text-align: center;
}
.c {
grid-column: 5 / span 2;
text-align: center;
}
div {
counter-reset: ps
}
p:before {
counter-increment: ps;
content: 'N°'counter(ps)' - ';
}
<div class="grid_layout">
<img class="a" src="http://dummyimage.com/300x150/456">
<p class="a">some text</p>
<img class="b" src="http://dummyimage.com/300x150/789">
<p class="b">some text</p>
<img class="c" src="http://dummyimage.com/300x150/029">
<p class="c">some text</p>
<img src="http://dummyimage.com/300x150/fa0">
<img src="http://dummyimage.com/300x150/bad">
<p class="a">some text</p>
<img src="http://dummyimage.com/300x150/g0d">
<img src="http://dummyimage.com/300x150/f00">
<p class="b">some text</p>
<img src="http://dummyimage.com/300x150/555">
<img src="http://dummyimage.com/300x150/0af">
<p class="c">some text</p>
</div>

Related

Image pushing divs below

I have a 2 column layout with an image to the left and wanted to have 3 divs on the right but can only manage to get 1 div to align next to the image and the other 3 divs are below the image. How can I have all 3 divs next to the image?
I know this is easy with grid-areas but wanted to do it with out.
.wrapper {
background-color: pink;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: auto auto 1fr;
}
.hero {
background-color: red;
}
.foo {
background-color: orange;
}
.bar {
background-color: lime;
}
.baz {
background-color: aqua;
}
img {
width: 100%;
display: block;
}
<div class="wrapper">
<div class="hero">
<img src="https://via.placeholder.com/1080x1080" alt="">
</div>
<div class="foo">
foo
</div>
<div class="bar">
bar
</div>
<div class="baz">
baz
</div>
</div>
https://codepen.io/emmabbb/pen/oNqPwad
Set a specific grid row value on your hero: grid-row: 1 / 4;
Like this:
.wrapper {
background-color: pink;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: auto auto 1fr;
}
.hero {
background-color: red;
grid-row: 1 / 4;
}
.foo {
background-color: orange;
}
.bar {
background-color: lime;
}
.baz {
background-color: aqua;
}
img {
width: 100%;
display: block;
}
<div class="wrapper">
<div class="hero">
<img src="https://via.placeholder.com/1080x1080" alt="">
</div>
<div class="foo">
foo
</div>
<div class="bar">
bar
</div>
<div class="baz">
baz
</div>
</div>
If you want your divs with text in them to be of equal height change the grid template rows to grid-template-rows: 1fr 1fr 1fr; Like this:
.wrapper {
background-color: pink;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 1fr 1fr 1fr;
}
.hero {
background-color: red;
grid-row: 1 / 4;
}
.foo {
background-color: orange;
}
.bar {
background-color: lime;
}
.baz {
background-color: aqua;
}
img {
width: 100%;
display: block;
}
<div class="wrapper">
<div class="hero">
<img src="https://via.placeholder.com/1080x1080" alt="">
</div>
<div class="foo">
foo
</div>
<div class="bar">
bar
</div>
<div class="baz">
baz
</div>
</div>
I believe the easiest way to get the 3 divs on the right of the image without using grid area would be to wrap foo, bar, and baz in a parent div and use 1 row on your grid; you may have to mess with the hight of the divs on the right though.
<div class="wrapper">
<div class="hero">
<img src="https://via.placeholder.com/1080x1080" alt="">
</div>
<div>
<div class="foo">
foo
</div>
<div class="bar">
bar
</div>
<div class="baz">
baz
</div>
</div>
</div>
I hope that does what your looking for!

How to create layout with grid

I want to create layout where the last element is centered. I should do with grids, but cant center the last element
Desired view
.box {
min-width: 50px;
min-height:50px;
background: red;
margin: 5px;
}
.container {
width: 200px;
display: grid;
grid-template-columns: auto auto auto;
}
.box7 {
grid-column-start: 2;
grid-row-start: 3;
grid-column-end: 4;
}
<div class='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
<div class='box'>5</div>
<div class='box'>6</div>
<div class='box box7'>7</div>
<div>
Desired view
.box {
min-height: 50px;
background: red;
margin: 5px;
grid-column: span 2;
}
.container {
width: 200px;
display: grid;
grid-template-columns: repeat(6, 1fr);
}
.box7 {
grid-column-start: 2;
grid-column-end: 6;
}
<div class='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
<div class='box'>5</div>
<div class='box'>6</div>
<div class='box box7'>7</div>
<div>
You can also find multiple ways on this discussion
I hope this approach of mine will help you:
.box {
min-width: 50px;
min-height:50px;
background: red;
margin: 5px;
}
.container {
width: 200px;
display: grid;
grid-template-rows: repeat(3, [row] auto );
grid-template-columns: repeat(3, [col] auto) ;
}
.subgrid {
grid-column: col / span 3;
grid-row: row 3;
}
.box7
{
width:66%;
margin-left:auto;
margin-right:auto;
}
<div class='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
<div class='box'>5</div>
<div class='box'>6</div>
<div class="subgrid">
<div class='box box7'>7</div>
</div>
<div>

How do I remove grid gaps when columns are not present?

I have a section of html that needs to be displayed in a certain way but some elements may be optional and I'm not sure if I can do it with display:grid.
I need to have 3 columns, but the first and last one are optional and I need to remove the gap when they are not present.
Note that the markup needs to be this one without extra wrapper :
.grid {
display: grid;
grid-template-columns: auto 1fr auto;
grid-gap: 0 20px;
align-items: center;
background-color: lightgrey;
}
.grid > .image {
grid-column: 1;
grid-row: 1 / span 2;
background-color: red;
}
.grid > .title {
grid-column: 2;
background-color: blue;
}
.grid > .description {
grid-column: 2;
background-color: purple;
}
.grid > .button {
grid-column: 3;
grid-row: 1 / span 2;
background-color: green;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>Unwanted gap when no image :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>Unwanted gap when no image or button :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>
Rely on implicit column creation and keep only one explicit column
.grid {
display: grid;
grid-template-columns: 1fr; /* one column here */
grid-gap: 0 20px;
align-items: center;
background-color: lightgrey;
}
.grid > .image {
grid-column: -3; /* this will create an implicit column at the start */
grid-row: span 2;
background-color: red;
}
.grid > .title {
background-color: blue;
}
.grid > .description {
background-color: purple;
}
.grid > .button {
grid-column: 2; /* this will create an implicit column at the end */
grid-row:1/ span 2;
background-color: green;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
</div>
<p> </p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>
Instead of using grid gaps, use margins on the individual elements.
.grid {
display: grid;
grid-auto-columns: auto 1fr auto;
/* grid-gap: 0 20px; */
align-items: center;
background-color: lightgrey;
}
.grid > .image {
margin-right: 20px; /* new */
grid-column: 1;
grid-row: 1 / span 2;
background-color: red;
}
.grid > .button {
margin-left: 20px; /* new */
grid-column: 3;
grid-row: 1 / span 2;
background-color: green;
}
.grid > .title {
grid-column: 2;
background-color: blue;
}
.grid > .description {
grid-column: 2;
background-color: purple;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>NO unwanted gap when no image :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>NO unwanted gap when no image or button :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>

how to make a grid mobile responsive in react

I have to make videos in the grid to appear horizontally one after the other when seen in a mobile(mobile responsive) but they should stay vertically aligned in desktop view.
i have tried giving values to rows and columns as auto
return (
<div>
<h1 className="text">trending in youtube</h1>
<div className="grid-container">
<div className="one">
<YouTube
videoId="y6fThXQPT6I"
opts={opts}
onReady={this._onReady}
/>
</div>
<div className="two">
<YouTube
videoId="bo_efYhYU2A"
opts={opts}
onReady={this._onReady}
/>
</div>
<div className="three">
<YouTube
videoId="3AtDnEC4zak"
opts={opts}
onReady={this._onReady}
/>
</div>
</div>
</div>
);
}
css file
display: grid;
grid-template-columns: repeat(auto, 1fr);
grid-gap: 5px;
grid-auto-rows: minmax(100px, auto);
}
.text {
margin-top: 50px;
margin-left: 40%;
}
.one {
grid-column: auto;
grid-row: 1;
}
.two {
grid-column:auto;
grid-row: 1;
}
.three {
grid-column: auto;
grid-row: 1;
}
As you tagged your post with bootstrap-4 I'll assume you use it.
Bootstrap has all you need, look at the grid system: https://getbootstrap.com/docs/4.3/layout/grid/
In your case you can use it like this:
return (
<div className="container">
<h1 className="text">trending in youtube</h1>
<div className="row justify-content-center">
<div className="col-xs-12 col-md-4">
<YouTube
videoId="y6fThXQPT6I"
opts={opts}
onReady={this._onReady}
/>
</div>
<div className="col-xs-12 col-md-4">
<YouTube
videoId="bo_efYhYU2A"
opts={opts}
onReady={this._onReady}
/>
</div>
<div className="col-xs-12 col-md-4">
<YouTube
videoId="3AtDnEC4zak"
opts={opts}
onReady={this._onReady}
/>
</div>
</div>
</div>
);
No more CSS needed 😉
You can Use grid-auto-flow:
.grid-container {
display: grid;
grid-gap: 5px;
grid-auto-flow: row; /* appear Vertically*/
justify-items: center;
}
#media (max-width: 767px) {
.grid-container {
grid-auto-flow: column; /* appear Horizontally on mobile phones*/
}
}
Example About css grid-auto-flow property: When you run the snippet it will appear horizontally, but if you opened it as full screen it will appear vertically.
.grid-container {
display: grid;
grid-gap: 5px;
grid-auto-flow: row;
justify-items: center;
}
#media (max-width: 767px) {
.grid-container {
grid-auto-flow: column;
}
}
.item {
width: 250px;
height: 100px;
}
.one {
background-color: lightblue;
}
.two {
background-color: lightpink;
}
.three {
background-color: lightcoral;
}
<div class="grid-container">
<div class="item one"></div>
<div class="item two"></div>
<div class="item three"></div>
</div>

How to span columns differently for each row within a nested grid using CSS Grid?

I am trying to build like the below in the main content in the website layout.
Row 1: "Title text (2 columns) + Image (1 column)"
Row 2: "Box + Box + Box"
Row 3: "Box + Box + Box"
Issues:
Tried to make "Row 1" as "title-block" and make it span 3 rows. then splitting it into 2 (title-text for 2 rows and image in the last row).
Also from 2nd row.. wanted three blocks and can fill in text or image. But they are all filling up in 1 box.
Screenshot also attached below.
Where am i going wrong? I saw several examples, some are either using %'s (do not want to use) or using some complex math (n-th..) which i was not able to understand.
.main {
display: grid;
background-color: indianred;
padding: 20px;
grid-template-areas:
"title-block title-block title-block"
"box box box"
"box box box";
grid-template-columns: 1fr, 1fr, 1fr;
//grid-template-rows: repeat(3, [row] auto );
grid-gap: 10px;
}
.main > * {
//background-color: yellowgreen;
padding: 20px;
}
img {
width: 50%;
}
.title-block {
background-color: lightsalmon;
grid-column: span 3;
grid-row: span 1;
}
.title-text {
grid-column: 1 / span 2;
grid-row: 1;
}
.title-image {
grid-column: 3 / span 1;
grid-row: 1;
}
.tech {
grid-area: box;
background-color: lightcyan;
grid-column: span 3;
grid-row: span 1;
}
.books {
grid-area: box;
background-color: violet;
grid-column: span 3;
grid-row: span 1;
}
<div class="main">
<div class="title-block">
<div class=title-text><h1>Software Developer, Architect, Open-Source Evangelist, Inventor, Mentor, Blogger, Author, Speaker</h1></div>
<div class=title-image><img src="https://upload.wikimedia.org/wikipedia/en/7/70/Bob_at_Easel.jpg"></div>
</div>
<div class="tech">
<div>Tech 1</div>
<div>Tech 2</div>
<div>Tech 3</div>
</div>
<div class="books">
<div>Book 1</div>
<div>Book 2</div>
<div>Book 3</div>
</div>
</div>
Does this work for you? This is how I understood your requirement, using CSS Grid of course, if this needs some changes let me know to update it
.main {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(70px, auto);
background-color: indianred;
grid-gap: 10px;
padding: 20px;
}
.title-block, .tech, .books {
grid-column: span 3;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.title-text {
grid-column: span 2;
border: 1px solid #000;
}
.title-image{
border: 1px solid #000;
}
.title-image img{
width: 70%;
display: block;
}
.tech {
background-color: lightcyan;
}
.tech div, .books div{
border: 1px solid #000;
}
.books {
background-color: violet;
}
<div class="main">
<div class="title-block">
<div class=title-text>
<h1>Software Developer, Architect, Open-Source Evangelist, Inventor, Mentor, Blogger, Author, Speaker</h1>
</div>
<div class=title-image><img src="https://upload.wikimedia.org/wikipedia/en/7/70/Bob_at_Easel.jpg"></div>
</div>
<div class="tech">
<div>Tech 1</div>
<div>Tech 2</div>
<div>Tech 3</div>
</div>
<div class="books">
<div>Book 1</div>
<div>Book 2</div>
<div>Book 3</div>
</div>
</div>
Is this what you looking for ?
.main {
background-color: indianred;
}
.main > * {
//background-color: yellowgreen;
padding: 20px;
}
img {
width: 50%;
}
.title-block {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.title-text {
width: calc(2 * (100% / 3))
}
.title-image {
width: calc(1 * (100% / 3))
}
.tech {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.books {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
<div class="main">
<div class="title-block">
<div class=title-text><h1>Software Developer, Architect, Open-Source Evangelist, Inventor, Mentor, Blogger, Author, Speaker</h1></div>
<div class=title-image><img src="https://upload.wikimedia.org/wikipedia/en/7/70/Bob_at_Easel.jpg"></div>
</div>
<div class="tech">
<div>Tech 1</div>
<div>Tech 2</div>
<div>Tech 3</div>
</div>
<div class="books">
<div>Book 1</div>
<div>Book 2</div>
<div>Book 3</div>
</div>
</div>

Resources