I want to make a grid with different column sizes ('ITEM = V' covers all width 'ITEM A' or 'P' or 'T' cover each 50 percent of the grid width), as shown in the image. Any help?
i ve been tryin to solve this for a week now. Really what's wrong with this. (video should take two columns)
<div class="grid-container">
<div *ngFor="let media of allMedia">
<div *ngIf="media.type==='V'" class="item1">
{{media.title}}
</div>
<div *ngIf="media.type==='A'" >
{{media.title}}
</div>
<div *ngIf="media.type==='P'" >**Bold Text Here**
{{media.title}}
</div>
<div *ngIf="media.type==='T'">
{{media.title}}
</div>
</div>
</div>
CSS
.grid-container {
display: grid;
background-color: #2196F3;
grid-template-columns: 50% 50%;
}
.item1 {
grid-area: 2 / 1 / span 2 / span 2 !important;
border-style:solid;
text-align:center
}
It'd be best to use display: grid; for something like this.
You'd have to add unique classes/id's for the children elements and then set the grid-area property on each of them.
The layout of grid-area is:
grid-area: row-start / column-start / row-end / column end;
You can also use shorthand if two properties have the same value:
grid-area: 2 / 1
/* Equates to: */
grid-area: 2 / 1 / 2 / 1
Example:
.outer-grid {
display: grid;
height: 100vh;
}
.newspaper1 {
grid-area: 1 / 3 / 2 / 1;
border-style: solid;
}
.newspaper2 {
grid-area: 2 / 1;
border-style: solid;
}
.newspaper3 {
grid-area: 2;
border-style: solid;
}
.newspaper4 {
grid-area: 3 / 1;
border-style: solid;
}
.newspaper5 {
grid-area: 3 / 2;
border-style: solid;
}
.newspaper6 {
grid-area: 4 / 3 / 4 / 1;
border-style: solid;
}
<div class="outer-grid">
<div *ngIf="item==='V'" class="newspaper1">
some content
</div>
<div *ngIf="item==='A'" class="newspaper2">
some content
</div>
<div *ngIf="item==='P'" class="newspaper3">
some content
</div>
<div *ngIf="item==='T'" class="newspaper4">
some content
</div>
<div *ngIf="item==='A'" class="newspaper5">
some content
</div>
<div *ngIf="item==='V'" class="newspaper6">
some content
</div>
</div>
Here's a good interface for learning CSS Grid if you want to learn more: https://alialaa.github.io/css-grid-cheat-sheet/
Related
given this html
<div class="parent">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
<div class="fourth">4</div>
</div>
and this css
.parent {
display: grid;
grid-template-areas:
'first second'
'third third'
'fourth fourth'
}
I expected the grid area "third" and "fourth" to implicitly have 1 column, which would render like so
I understand I can fix this by specifying grid-area, curious if theres another approach?
https://jsfiddle.net/qgdh2b8a/2/
This isn't a completely different approach, but you could use grid-column and not use grid-template-areas entirely. This solution also uses grid-template-columns.
.parent {
display: grid;
grid-gap: 3px;
/* Defines two columns */
grid-template-columns: 1fr 1fr;
}
.parent > div {
/* Visibility and styling */
background-color: black;
color: white;
padding: 1rem;
text-align: center;
font-family: sans-serif;
}
.third, .fourth {
/* Sets the column that the item should span */
grid-column: 1 / -1;
}
<div class="parent">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
<div class="fourth">4</div>
</div>
Here, the third and fourth classes have this style applied: grid-column: 1 / -1. The slash specifies the amount of columns that the element should span. 1 is the first column and -1 is the first from last (the last column).
Examples:
grid-column: 3 Sets the grid column to 3.
grid-column: 1 / 3 Sets the element to span columns 1 through 3.
grid-column: 1 / -2 Sets the element to span columns 1 through the 2nd last one.
You can use grid-column.
.first {
gird-column: 1 / 3; //like this
}
This tells the grid to start from the beginning of the first column, till the beginning of the third column.
The same can work for grid-rows.
You can read more here: grid-column
This question is about whether CSS grid "span counting" -- whether it should start on implicit grid line. In CSS Definitive Guide, 4th Ed, p. 695, it is said that
box4 is where things really get interesting. It ends on the fifth row line, which is to say the second implicit grid line. It spans back three lines—and yet, it still starts on the same grid line as box3. This happens because spans have to start counting within the explicit grid. Once they start, they can continue on into the implicit grid (as happened with box2), but they cannot start counting within the implicit grid.
Is it true? Or has there been a spec change? Can "span counting" start within implicit grid?
It is a bit confusing as the code in the book used:
.box04 {grid-column: 4; grid-row: span 2 / 5;}
while the online code on Github.com used:
.box04 {grid-column: 4; grid-row: span 4 / 5;}
(so I do see it start counting at row grid line 5, and start counting 4 steps back starting at this implicit grid line 5, and the rule is "we shouldn't start counting at implicit grid lines". So has the rule changed or the rule doesn't mean it that way?).
and in order to have the result as on the book, it needs to be 4 / 5 instead of 2 / 5, and the text in the book said "spans back three lines" -- shouldn't it be span back 4 or 2 lines? If we can't count implicit grid, then really it should be 2 / 5, but if we can count implicit grid, then it should be 4 / 5. So was there a spec change? And the "three lines" probably is a typo? So if we need to span 4, then that probably means we count starting on either implicit or explicit grid line?
The code is a bit long but we can just look at box04:
html {
background: #DDD;
}
body {
padding: 2em;
margin: 0;
box-sizing: border-box;
background: white;
}
ul.grid {
padding: 0;
margin: 0;
}
.grid.boxed {
border: 1px solid black;
}
.grid.boxed.lines {
padding: 1px 0 0 1px;
}
.grid.small *[class^="box"] {
font-size: 1em;
font-weight: normal;
padding: 0.25em;
border-width: 0.167em;
}
*[class^="box"] {
border: 0.33em solid;
font: bold 2em Arvo, sans-serif;
display: flex;
align-items: center;
justify-content: center;
}
*[class^="box"][class*="01"] {
color: rgb(255, 0, 0);
background: rgba(255, 0, 0, 0.1);
}
*[class^="box"][class*="02"] {
color: rgb(255, 128, 0);
background: rgba(255, 128, 0, 0.15);
}
*[class^="box"][class*="03"] {
color: rgb(216, 168, 0);
background: rgba(216, 168, 0, 0.2);
}
*[class^="box"][class*="04"] {
color: rgb(0, 128, 0);
background: rgba(0, 128, 0, 0.1);
}
*[class^="box"][class*="05"] {
color: rgb(0, 0, 255);
background: rgba(0, 0, 255, 0.1);
}
*[class^="box"][class*="06"] {
color: rgb(128, 0, 128);
background: rgba(128, 0, 128, 0.1);
}
span[class*="gridline"] {
border: 1px dashed;
margin: -1px 0 0 -1px;
}
/* for print preview/production
body:hover {filter: saturate(0%);}
*/
#grid {
grid-auto-rows: 2em;
grid-auto-columns: 5em;
width: 35em;
}
#grid {
display: grid;
grid-template-rows: 2em 2em;
grid-template-columns: repeat(6, 4em);
}
.box01 {
grid-column: 1;
grid-row: 1 / 4;
}
.box02 {
grid-column: 2;
grid-row: 3 / span 2;
}
.box03 {
grid-column: 3;
grid-row: span 2 / 3;
}
.box04 {
grid-column: 4;
grid-row: span 4 / 5;
}
.box05 {
grid-column: 5;
grid-row: span 6 / 5;
}
.box06 {
grid-column: 6;
grid-row: -1 / span 3;
}
.box07 {
grid-column: 7;
grid-row: span 3 / -1;
}
span[class*="box"] {
z-index: 1;
}
span.explicit {
background: #DDD;
grid-area: 1 / 1 / 3 / 7;
}
<div class="grid gridlines" id="grid">
<span class="box01">1</span>
<span class="box02">2</span>
<span class="box03">3</span>
<span class="box04">4</span>
<span class="box05">5</span>
<span class="box06">6</span>
<span class="box07">7</span>
<span class="explicit"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
<span class="gridlines"></span>
</div>
Can "span counting" start within implicit grid?
No, we start considering the explicit grid and never the implicit grid. Focus on the word start which is the most important because the explicit grid is always the reference and the implicit grid is only the result of extra column/row created in order to contain everything.
As I explained here we cannot consider the implicit grid because we will easily run into undefined behaviors.
Starting considering the explicit grid doesn't necessarily mean that we will be inside the explicit grid. Read until the end to understand this part.
From the specification:
Numeric indexes in the grid-placement properties count from the edges of the explicit grid. Positive indexes count from the start side (starting from 1 for the start-most explicit line), while negative indexes count from the end side (starting from -1 for the end-most explicit line).
And
When grid items are positioned outside of these bounds, the grid container generates implicit grid tracks by adding implicit grid lines to the grid... ref
Let's have some examples to better understand.
Here is a grid with 3 explicit rows (4 lines) and no implicit row created:
.box {
display:grid;
grid-gap:5px;
grid-template-rows:repeat(3,50px);
grid-template-columns:repeat(3,1fr);
grid-auto-rows:200px; /* This wil never be used */
border:1px solid;
}
.a {
grid-row:span 2/3;
background:red;
}
.b {
grid-row:span 2/4;
background:red;
}
.c {
grid-row:1/4;
background:red;
}
<div class="box">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
The .a ends at line 3 and span back 2 rows. Same for .b but ending at line 4. For .c we start from 1 to 4.
Let's create an implicit grid by making the .c until 5
.box {
display:grid;
grid-gap:5px;
grid-template-rows:repeat(3,50px);
grid-template-columns:repeat(3,1fr);
grid-auto-rows:200px; /* This is used for the implicit row */
border:1px solid;
}
.a {
grid-row:span 2/3;
background:red;
}
.b {
grid-row:span 2/4;
background:red;
}
.c {
grid-row:1/5;
background:red;
}
<div class="box">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
Note how the .a and .b didn't move which is trivial in this case because we added a line at the bottom so will not see any trick around the explicit grid.
Now let's add an implicit grid at the beginning:
.box {
display:grid;
grid-gap:5px;
grid-template-rows:repeat(3,50px);
grid-template-columns:repeat(3,1fr);
grid-auto-rows:200px; /* This is used for the implicit row */
border:1px solid;
}
.a {
grid-row:span 2/3;
background:red;
}
.b {
grid-row:span 2/4;
background:red;
}
.c {
grid-row:span 4/4;
background:red;
}
<div class="box">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
Now it's intresting because we can see that .a and .b are no more starting from 3 and 4 considering the implicit grid but they do inside the explicit one!
For .c we start at the line 4 but we need 4 rows and our grid contain only 3 so we generate implicit rows and we continue the count there.
Basically, we have the follwing steps:
We have the explicit grid
We place items inside the explicit grid (we start the count). Until now there is no implicit grid
we start counting and if we reach the edges and there is no more rows we add new ones. The implicit grid is created.
Another example:
.box {
display:grid;
grid-gap:5px;
grid-template-rows:repeat(3,50px);
grid-template-columns:repeat(3,1fr);
grid-auto-rows:10px; /* This is used for the implicit row */
border:1px solid;
}
.a {
grid-row: 2/span 6;
background:red;
}
.b {
grid-row:span 2/4;
background:red;
}
.c {
grid-row:span 4/4;
background:red;
}
<div class="box">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
If you inspect the code you can easily visualize the explicit grid (50px height for rows) and the implicit ones (20px height for rows). We start the count considering the explicit grid and we may end in the implicit one.
In the above, we always considered the starting (or ending) to be a number that we can easily identify inside the explicit grid and only the span is larger. Let's now consider the case where the starting (or ending) is also a bigger number than the lines defined in the explicit grid.
.box {
display:grid;
grid-gap:5px;
grid-template-rows:repeat(3,50px);
grid-template-columns:repeat(3,1fr);
grid-auto-rows:10px; /* This is used for the implicit row */
border:1px solid;
}
.a {
grid-row: 1/span 2;
background:red;
}
.b {
grid-row:span 10/8;
background:red;
}
.c {
grid-row:span 2/4;
background:red;
}
<div class="box">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
In this case, we defined the .b to end at 8 and span back 10 but there is no line number 8 in the explicit grid. We will then create extra implicit lines in order to have the line 8 and we will count from there and go back 10 rows.
So we started the count from the implicit grid!?
Yes and no. We used the explicit grid to count the lines in order to identify the line 8 (so our reference is always the explicit grid) then when we reach the edge we added more lines to reach 8 then from that point we went back and we created more implicit lines at the beginning.
If we consider the final result of the implicit grid, we cannot say that we started the count from the implicit grid (you can clearly see that it's not the line number 8 in the implicit grid but the last one, the line number 11) but if we consider the fact that the line 8 was created inside the implicit grid then we can say that our starting point is an implicit grid line.
Our reference is always the explicit grid in order to identify the starting/ending line but we may end having our line as an implicit grid line and not an explicit grid line.
box4 is where things really get interesting. It ends on the fifth row line, which is to say the second implicit grid line. It spans back three lines—and yet, it still starts on the same grid line as box3. This happens because spans have to start counting within the explicit grid. Once they start, they can continue on into the implicit grid (as happened with box2), but they cannot start counting within the implicit grid.
the book said "spans back three lines" -- shouldn't it be span back 4 or 2 lines?
Here it's a matter of language. From the specification:
grid span
How many grid tracks the grid item occupies in each axis
Then
Grid track is a generic term for a grid column or grid row—in other words, it is the space between two adjacent grid lines.
So span 4 means 4 rows or 4 columns which is clear but if we try to use this with lines it can be ambiguous because we will have 5 lines involved and our element will cross only 3 of them and we have 2 at the edges. Maybe the book is refering to the 3 middle lines and omitting the ones at the edges when saying "spans back three lines". In other words, the element is overlapping (spanning back) only 3 lines.
I'm trying to accomplish the following layout:
My first thought is to use flexbox to achieve this layout. I currently have the following HTML:
<section>
<div class"item">box1</div>
<div class"item">box2</div>
<div class"item">box3</div>
<div class"item">box4</div>
<div class"item">box5</div>
</section>
How can I achieve the desired layout with my HTML? I can add line break div elements in between items like this as well:
<div class"break"> </div>
Unfortunately I am still not able to achieve the required layout. Please help
A simple CSS-grid based approach would be to use a "template of named grid areas".
CSS grid allows for named areas, which dictate the placement of children based on the grid-area of those grid children. In the case of your requirements, a template based on named areas could be defined as:
grid-template-areas:
"a a b b c c"
". . e f . .";
These template areas work by causing:
child elements with grid-area of a, b, and c to occupy the top row of the template layout, where each spans two columns of the 6 column grid
child elements with grid-area of e and f to occupy the bottom row of the template, at the third and fourth column respectively. The . on this row configuration specifies that no child apples to that area of the template
Note that template area strings can be written on the same line for the grid-template-areas property as shown below:
section {
/* Specify that CSS grid is to be used for layout of children */
display: grid;
/* Specify spacing between children */
grid-gap:1rem;
/* Wrap against six evenly spaced columns of this grid */
grid-template-columns: repeat(6, 1fr);
/* Define the area names of the grid template */
grid-template-areas: "a a b b c c" ". . e f . .";
}
section div:nth-child(1) {
grid-area: a;
}
section div:nth-child(2) {
grid-area: b;
}
section div:nth-child(3) {
grid-area: e;
}
section div:nth-child(4) {
grid-area: f;
}
section div:nth-child(5) {
grid-area: c;
}
/* Optional aesthetics to better match your example */
div {
background: darkgrey;
border-radius: 5px;
color: white;
text-align: center;
}
<section>
<div class "item">box1</div>
<div class "item">box2</div>
<div class "item">box3</div>
<div class "item">box4</div>
<div class "item">box5</div>
</section>
Updates
section {
display: grid;
grid-gap:1rem;
grid-template-columns: repeat(5, auto);
grid-template-areas: "a b c c d e" ". . f g . .";
}
section div:nth-child(1) {
grid-area: a;
}
section div:nth-child(2) {
grid-area: b;
}
section div:nth-child(3) {
grid-area: c;
}
section div:nth-child(4) {
grid-area: f;
}
section div:nth-child(5) {
grid-area: g;
}
section div:nth-child(6) {
grid-area: d;
}
section div:nth-child(7) {
grid-area: e;
}
/* Optional aesthetics to better match your example */
div {
background: darkgrey;
border-radius: 5px;
color: white;
text-align: center;
}
<section>
<div class "item">box1</div>
<div class "item">box2</div>
<div class "item">box3</div>
<div class "item">box4 lots of content causes uneven column distribution</div>
<div class "item">box5</div>
<div class "item">box6</div>
<div class "item">box7</div>
</section>
You Can use CSS Grid Instead:
Complete Grid Guide
Working Demo:
.grid {
display: grid;
grid-template-areas: "i1 i1 i2 i2 i3 i3" ". . i4 i5 . .";
grid-template-columns: repeat(6,1fr); /* to make all boxes same with */
grid-gap: 10px;
}
.i1 {
grid-area: i1
}
.i2 {
grid-area: i2
}
.i3 {
grid-area: i3
}
.i4 {
grid-area: i4
}
.i5 {
grid-area: i5
}
.item {
min-height: 40px;
background-color: #7D7D7D;
border-radius: 10px;
display: flex;
justify-content: center;
;
align-items: center;
color: white;
font-size: 1.5rem;
font-weight: bolder;
}
.i4,.i5 {
border-radius: 8px;
}
<section class="grid">
<div class="item i1">box1</div>
<div class="item i2">box2</div>
<div class="item i3">box3</div>
<div class="item i4">box4</div>
<div class="item i5">box5</div>
</section>
With flexbox you can adjust the order of the element and rely on wrapping:
section {
display:flex;
flex-wrap:wrap;
justify-content:center;
}
section > .item {
width:calc(100%/3 - 10px);
margin:5px;
}
section > .item:nth-child(3),
section > .item:nth-child(4){
order:1;
width:calc((100%/3 - 20px) /2);
}
/* Irrelevant styles */
section > .item {
padding:10px;
box-sizing:border-box;
text-align:center;
background:#000;
color:#fff;
border-radius:10px;
}
<section>
<div class="item">box1</div>
<div class="item">box2</div>
<div class="item">box3</div>
<div class="item">box4</div>
<div class="item">box5</div>
</section>
I am trying to create a row with 4 cells and I don't know why its not working.
I have created a parent row and 4 children.
<div className='row'>
<div className='col-1-of-4'>
hi
</div>
<div className='col-1-of-4'>
hi
</div>
<div className='col-1-of-4'>
hi
</div>
<div className='col-1-of-4'>
hi
</div>
</div>
(Ignore the className for class, as I am using react)
and the css properties are:
[class^="col-"] {
float: left;
&:not(:last-child) {
margin-right: $gutter-horizontal;
}
}
.col-1-of-4 {
width: calc((100% - #{$gutter-horizontal}) / 4);
}
What it does is, calculates total width, and then subtracts the margin and then divides by 4.
Technically it should work and I should be able to see 4 cells in a row.
But the result I get is, 3 cells in a row and the fourth one on the next line.
the result should be something like this
hi hi hi hi
but the actual result is
hi hi hi
hi
Here is the working code
https://codepen.io/sarmad1995/pen/REYXBV?editors=1100
You shouldn't divide the margin inside your calculation. It should be outside or will you will remove less than the margin set for each element. You are setting X margin and only removing X/4 so each element will take 25% - X/4 + X (the last one 25% - X/4) as a space thus the total will be 100% + 2X which bigger than 100%.
.col-1-of-4 {
width: calc(100% / 4 - #{$gutter-horizontal});
}
.row {
max-width: 114rem;
margin: 0 auto;
}
.row:not(:last-child) {
margin-bottom: 8rem;
}
.row::after {
content: "";
display: table;
clear: both;
}
.row [class^="col-"] {
float: left;
}
.row [class^="col-"]:not(:last-child) {
margin-right: 6rem;
}
.row .col-1-of-4 {
width: calc(100% / 4 - 6rem);
background-color: red;
}
<div class='row'>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
</div>
And in case you need a space between behavior (which is what you want) you can do like this:
.col-1-of-4 {
width: calc(100% / 4 - 3*#{$gutter-horizontal}/4);
}
That you can also write like this:
.col-1-of-4 {
width: calc((100% - 3*#{$gutter-horizontal})/4);
}
You need to remove the 3 margins (defined for the first 3 elements) from the total width then divide by 4:
.row {
max-width: 114rem;
margin: 0 auto;
}
.row:not(:last-child) {
margin-bottom: 8rem;
}
.row::after {
content: "";
display: table;
clear: both;
}
.row [class^="col-"] {
float: left;
}
.row [class^="col-"]:not(:last-child) {
margin-right: 6rem;
}
.row .col-1-of-4 {
width: calc(100% / 4 - 3*6rem/4);
background-color: red;
}
<div class='row'>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
<div class='col-1-of-4'>
hi
</div>
</div>
You should apply the same logic for all your other classes
Looking at your codepen example, you are setting a margin-right.
[class^="col-"] {
float: left;
&:not(:last-child) {
margin-right: $gutter-horizontal;
}
}
Removing this gives you the four columns as described.
Please in future include all relevant code to your question.
While using the old CSS grid spec that is supported by IE 11 and EDGE. Is it possible for the grid items to be auto placed like the current spec?
i.e. to not have to define the column on a grid item:
.item:nth-child(1) {
-ms-grid-column: 1;
}
.item:nth-child(2) {
-ms-grid-column: 2;
}
.item:nth-child(n) {
-ms-grid-column: n;
}
https://codepen.io/JoeHastings/pen/mMPoqB
The answer is NO (unfortunately).
Old specs section about auto-placement has such preamble
This section describes early thinking around automatic placement of Grid Items. Multiple algorithms are possible for such a feature. One is proposed here.
Run this code in IE/Edge and you'll see a lot of rows with 1 in console because IE/Edge stacks all grid items in first cell and you can't force IE/Edge to place grid items automatically. Setting -ms-grid-column and -ms-grid-row to auto won't change anything, because this value is not supported (as you can see in MSDN links). Demo:
var gridItems = document.querySelectorAll(".grid__item");
for (var i = 0; i < gridItems.length; i++) {
var gridItem = gridItems[i];
console.log(window.getComputedStyle(gridItem)["-ms-grid-row"]);
console.log(window.getComputedStyle(gridItem)["-ms-grid-column"]);
}
.grid {
display: -ms-grid;
-ms-grid-columns: 100px 100px 100px;
-ms-grid-rows: 100px 100px 100px;
}
.grid__item {
-ms-grid-row: auto;
-ms-grid-column: auto;
background-color: tomato;
color: white;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>