Css Grid Dynamic layouts - html

I am trying to make a dynamic grid layout containing 1-4 elements. They achieved something close to what I am looking for at https://css-tricks.com/exploring-css-grids-implicit-grid-and-auto-placement-powers/ under the "dynamic layouts" section. But slightly different.
The CSS for this layout:
.grid {
display: grid;
}
.grid :nth-child(2) {
grid-column-start: 2;
}
.grid :nth-child(3):last-child {
grid-column-start: span 2;
}
I am trying to do something similar but different, but I cannot get it. This is a picture of what I want to achieve:

You can use the CSS nth-last-child selector to spot when the first child is the first of three children.
.grid {
display: grid;
}
.grid :nth-child(2) {
grid-column-start: 2;
}
.grid :nth-child(1):nth-last-child(3) {
grid-row-start: span 2;
}
/**/
.grid {
width: 300px;
aspect-ratio: 1;
grid-gap: 5px;
outline: 2px solid red;
vertical-align: top;
margin: 10px;
counter-reset: num;
}
.grid * {
border: 2px solid;
font-size: 30px;
box-sizing: border-box;
font-family: sans-serif;
display: grid;
place-content: center;
}
.grid *:before {
content: counter(num);
counter-increment: num;
}
<div class="grid">
<div></div>
</div>
<div class="grid">
<div></div>
<div></div>
</div>
<div class="grid">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
</div>

Related

Three divs in row, last one in another column horizontally centered - Flexbox or Grid

I have a grid container and I want to align three divs like this, also doing them responsive (all stacked). I don't have the heights of the divs.
It would be two columns, in one two rows (two divs one below another), in another column a div centered vertically having in mind the height of the two first divs.
I can use grid or flexbox.
Thanks
Using Flexbox:
.wrapper {
width: 400px;
border: 2px solid black;
height: 300px;
display: flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: center;
align-items: center;
}
.child {
height: 100px;
width: 150px;
border: 1px solid black;
margin-top: 20px;
margin-bottom: 20px;
}
<div class="wrapper">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
and also grid :
Example from2 columns and the third element spanning through 2 rows and margin itself in the middle.
section {
display: grid;
grid-template-columns: repeat(2, minmax(270px, 1fr));/* or any value you need */
grid-gap: 2em;/* or any value you need */
padding: 2em;/* or any value you need */
counter-reset: divs; /*demo*/
width:max-content;/* or any value you need */
margin:auto;/* or any value you need */
}
div {
border: solid red;
min-height: 30vh;/* or any value you need */
width: 270px;/* or any value you need */
display: flex; /* demo*/
}
div {
margin-left: auto;
}
div:nth-child(3) {
grid-column: 2;
grid-row: 1 / span 2;
margin: auto 0;
}
/*demo*/
div:before {
counter-increment: divs;
content: counter(divs);
margin: auto;
font-size: 3em;
}
<section>
<div></div>
<div></div>
<div></div>
</section>
To play with the grid system, you can use : https://css-tricks.com/snippets/css/complete-guide-grid/ / http://gridbyexample.com/ and https://codepen.io/pen/ for the playground.
Here's a jsfiddle: https://jsfiddle.net/5csL2dqy/
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.right {
display: inherit;
align-items: center;
}
.a, .b, .c {
box-sizing: border-box;
width: 150px;
margin: 20px;
border: 1px solid black;
}
<div class="container">
<div class="left">
<div class="a">
<p>
First div
</p>
</div>
<div class="b">
<p>
second div
</p>
</div>
</div>
<div class="right">
<div class="c">
<p>
Third div
</p>
</div>
</div>
</div>
You use the following inline-flex styles
#media only screen and (min-width: 600px) {
.container {
display: inline-flex;
}
.container div {
border: 1px solid red;
padding: 1em;
margin: 1em;
}
.container>div+div {
margin: auto;
}
}
#media only screen and (max-width: 600px) {
.container div:not(first-child) {
border: 1px solid red;
}
}
<div class="container">
<div>
<div>
1
</div>
<div>
2
</div>
</div>
<div>
3
</div>
</div>
This is one of only two answers with equal width/height gaps. G-Cyr's is the other:
.grid{
display: grid;
grid-template-columns: repeat(9,1fr);
grid-template-rows: repeat(7, 1fr);
height: 90vh;
width: 120vh;
}
.grid > div{
border: solid 3px orangered;
font: 26px sans-serif;
display: flex;
align-items:center;
justify-content:center;
}
.grid > div:nth-child(1){
grid-row: 1/span 3;
grid-column: 1/span 4;
}
.grid > div:nth-child(2){
grid-row: 3/span 3;
grid-column: 6/span 4;
}
.grid > div:nth-child(3){
grid-row: 5/span 3;
grid-column: 1/span 4;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

Displaying divs on multiple rows with custom limitations

I am trying to place 6 boxes, as a small exercise to understand how to do it. I want these 6 boxes to be divided in 4 boxes on a row and then 2 on the second one, and I want to do it with the display feature in CSS so that is not applicable only for this case. This is what I have been trying.
https://gyazo.com/f64788cdf85d263e56452c1412fdcfb0?token=f6c45c6813c3fc47addb63483cee3f6a
.parent{
display: flex;
flex-wrap: wrap;
}
.parent-wrapper {
height:100%;
width:100%;
border: 1px solid black;}
.child {
width: 300px;
height: 200px;
background-color: green;
border: 1px solid red;
margin: 5px;
flex: 1 0 21%;
}
You could use display: flex.
HTML:
<div class="flex">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
CSS (EDITED):
.flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flex div {
height: 200px;
background-color: green;
border: 1px solid red;
box-sizing: border-box;
/*flex: 1 0 23%;*/
width: 24.1%;
margin: 5px;
/*margin-bottom: 5px;*/
}
The output is the following:
Not sure if you mean this but what I understood from your question:
HTML:
<div class="divTable">
<div class="divTableBody">
<div class="divTableRow">
<div class="divTableCell"></div>
<div class="divTableCell"></div>
</div>
<div class="divTableRow">
<div class="divTableCell"></div>
<div class="divTableCell"></div>
</div>
<div class="divTableRow">
<div class="divTableCell"></div>
</div>
<div class="divTableRow">
<div class="divTableCell"></div>
</div>
</div>
</div>
CSS:
.divTable{
display: table;
width: 100%;
}
.divTableRow {
display: table-row;
}
.divTableHeading {
background-color: #EEE;
display: table-header-group;
}
.divTableCell, .divTableHead {
border: 1px solid #999999;
display: table-cell;
padding: 3px 10px;
}
.divTableHeading {
background-color: #EEE;
display: table-header-group;
font-weight: bold;
}
.divTableFoot {
background-color: #EEE;
display: table-footer-group;
font-weight: bold;
}
.divTableBody {
display: table-row-group;
}
If you want to use the display: grid the solution could look like this:
https://jsfiddle.net/uvrjs7op/
<div class='Wrapper'>
<div class='Item-A'></div>
<div class='Item-B'></div>
<div class='Item-C'></div>
<div class='Item-D'></div>
<div class='Item-E'></div>
<div class='Item-F'></div>
</div>
.Wrapper {
Display: grid;
grid-template-columns: 25% 25% 25% 25%;
grid-template-rows: 50px 50px;
Background: orange;
}
.Item-A{
grid-column-start: 1;
grid-column-end: 2;
Background: Green;
}
.Item-B{
grid-column-start: 2;
grid-column-end: 3;
Background: blue;
}
.Item-C{
grid-column-start: 3;
grid-column-end: 4;
Background: red;
}
.Item-D{
grid-column-start: 4;
grid-column-end: 5;
Background: brown;
}
.Item-E{
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
Background: yellow;
}
.Item-F{
grid-column-start: 3;
grid-column-end: 5;
grid-row-start: 2;
Background: purple;
}
An easy solution will be
Solution
#wrapper {
display:grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 1fr;
grid-column-gap: 5px;
width:100%;
}
#wrapper > div {
margin:10px;
background-color:#bada55;
}
<div id="wrapper">
<div id="first">first</div>
<div id="second">second</div>
<div id="third">third</div>
<div id="fourth">fourth</div>
<div id="fifth">fifth</div>
<div id="sixth">sixth</div>
</div>

Equal height different aspect ratio boxes with CSS grid

I'm trying to create layout like this:
Orange blocks on the right side all have the same aspect ratio and thus height.
Blue block has different aspect ratio.
Height of blue block and summ of orange blocks should be equal, as shown on the image.
Is there a way to create such layout via CSS grid? I know that I can wrap orange items in a separate column element, but I'd like to avoid this. I also managed to create this layout when aspect ratio of each item is square, but no luck with this one...
Example on jsfiddle http://jsfiddle.net/fq974gov/
.grid {
display: grid;
grid-gap: 10px;
width: 200px;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
You can define template areas and control the ratio using grid-template-columns
.grid {
display: grid;
grid-template-areas:
"l1 r1"
"l1 r2"
"l1 r3";
grid-template-columns:3fr 2fr; /*adjust this as you like*/
grid-gap: 10px;
width: 200px;
animation:change 2s infinite alternate linear;
}
.item-left {
grid-area:l1;
background: lightblue;
/*padding-bottom: 120%; no more needed*/
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
.item-right:nth-child(2) {
grid-area:r1;
}
.item-right:nth-child(3) {
grid-area:r2;
}
.item-right:nth-child(4) {
grid-area:r3;
}
#keyframes change{
to{width:300px;}
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
The code can be simplified like this:
.grid {
display: grid;
grid-template-areas:
"l r"
"l r"
"l r";
grid-template-columns:3fr 2fr; /*adjust this as you like*/
grid-gap: 10px;
width: 200px;
animation:change 2s infinite alternate linear;
}
.item-left {
grid-area:l;
background: lightblue;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
#keyframes change{
to{width:300px;}
}
<div class="grid">
<div class="item-left"></div>
<div class="item-right"></div>
<div class="item-right"></div>
<div class="item-right"></div>
</div>
This is working code for it.
Check it out on JSFiddle
<html>
<head>
<title>Grid View</title>
</head>
<style>
.grid {
display: grid;
grid-gap: 10px;
width: 500px;
grid-template-areas:
"a a b b"
"a a c c"
"a a d d"
;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
grid-area: a;
}
.item-right {
background: tomato;
padding-bottom: 40%;
}
#grid_b {
grid-area: b;
}
#grid_c {
grid-area: c;
}
#grid_d {
grid-area: d;
}
</style>
<body>
<div class="grid">
<div id="grid_a" class="item-left"></div>
<div id="grid_b" class="item-right"></div>
<div id="grid_c" class="item-right"></div>
<div id="grid_d" class="item-right"></div>
</div>
</body>
</html>
At first, I suggest you to read more about grid layout. This link may help you.
And let's solve your problem. Every div item in your case is a grid item. So you should give them different styles. At first You should set grid-template-columns and grid-template-rows for container. After that for items, you should set grid-column-start, grid-column-end, grid-row-start, grid-row-end. Look at the above link about grid layout and try to solve it, This is my solution that may help you.
https://jsfiddle.net/sghgh1996/0cf39bm1/
HTML:
<div class="grid">
<div class="item-left">
</div>
<div class="item-right row1">
</div>
<div class="item-right row2">
</div>
<div class="item-right row3">
</div>
</div>
CSS:
.grid {
display: grid;
grid-gap: 10px;
width: 200px;
grid-template-columns: 50% 50%;
grid-template-rows: 33.333% 33.333% 33.333%;
}
.item-left {
background: lightblue;
padding-bottom: 120%;
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 6;
}
.item-right {
background: tomato;
padding-bottom: 60%;
}
.row1{
grid-row-start: 1;
grid-row-end: 2;
}
.row2{
grid-row-start: 3;
grid-row-end: 4;
}
.row3{
grid-row-start: 5;
grid-row-end: 6;
}

Make flexbox children wrap around a child that is multiple rows tall

I am iterating over a list of items(red boxes). I have another element not part of this list that I want to insert into the items' grid in the top right(tall blue box). I am using flexbox and order to position it accordingly. But I want the 2nd row of red items to be 3 items wide and wrap inline with the blue aside. Screenshot of my ideal outcome below. Code at the bottom of my failed attempt.
.flex {
display: flex;
flex-wrap: wrap;
margin: auto;
max-width: 120px;
}
.flex>div {
background: red;
height: 25px;
width: 25px;
margin: 2px;
order: 3;
}
.flex>div:nth-child(-n+3) {
order: 1;
}
aside {
height: 55px;
width: 25px;
margin: 2px;
background: blue;
order: 2;
}
<div class="flex">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<aside></aside>
</div>
Worth noting that I know I can do this with floats but for other reasons unrelated to this problem I'm kind of stuck with flexbox. Open to any & all suggestions though.
Here is the problem you're facing with flexbox, and several potential solutions:
Is it possible for flex items to align tightly to the items above them?
Make a div span two rows in a grid
Here's a calculator keypad layout using flexbox:
Calculator keypad layout with flexbox
Here's the cleanest and most efficient CSS solution, which uses Grid:
.flex {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25px;
grid-gap: 5px;
margin: auto;
max-width: 120px;
}
aside {
grid-column: 4;
grid-row: 1 / span 2;
background: blue;
}
.flex > div {
background: red;
}
<div class="flex">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<aside></aside>
</div>
jsfiddle demo
css grid browser support
.flex {
display: flex;
flex-wrap: wrap;
margin: auto;
max-width: 120px;
}
.flex>div {
background: red;
height: 25px;
width: 25px;
margin: 2px;
order: 3;
}
.flex>div:nth-child(-n+3) {
order: 1;
}
aside {
height: 55px;
width: 25px;
margin: 2px;
background: blue;
order: 2;
margin-bottom: -57px; /* added */
}
.flex>div:nth-child(6) { /* added */
margin-right: 27px;
}
<div class="flex">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<aside></aside>
</div>
Here is a version of another answer of mine, which might also qualify as a duplicate, though since it has a simpler CSS, I decided to post it as an answer.
It uses the order property and absolute position, to enable the required layout.
Read more here: Flexbox or Column CSS for positioning elements like this
Stack snippet
.container {
display: flex;
flex-wrap: wrap;
}
.container .right_corner > div {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: calc(200% + 10px);
background: blue;
}
.container::before,
.container > div {
height: 50px;
margin: 5px;
}
.container > div:not(:first-child) {
background: red;
}
.container .right_corner {
position: relative;
order: 1;
}
.container::before {
content: '';
order: 3;
}
#media (max-width: 600px){
.container > div:nth-child(n+5) {
order: 2;
}
.container > div:nth-child(n+8) {
order: 4;
}
.container::before,
.container > div {
width: calc((100% / 4) - 10px);
}
}
#media (min-width: 601px) and (max-width: 800px){
.container > div:nth-child(n+6) {
order: 2;
}
.container > div:nth-child(n+10) {
order: 4;
}
.container::before,
.container > div {
width: calc((100% / 5) - 10px);
}
}
#media (min-width: 800px) {
.container > div:nth-child(n+7) {
order: 2;
}
.container > div:nth-child(n+12) {
order: 4;
}
.container::before,
.container > div {
width: calc((100% / 6) - 10px);
}
}
<div class='container'>
<div class='right_corner'>
<div></div>
</div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

css3 display: grid; or grid-column-start: isn't working

I want to use the new grid module in CSS but it isn't working.
This is the code I have:
div {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
p {
grid-column-start: 2;
grid-row-start: 2;
}
<div>
<p>
Hello World! :D
</p>
</div>
It is working properly, you just need to visualise it better. Try adding some other child elements to your main container, you'd see Hello world is positioned where it should be. It is just because you have empty space all around, you are having difficulty
div.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
background: green;
}
div {
background: yellow;
padding: 10px;
background-clip: content-box;
}
p {
grid-column-start: 2;
grid-row-start: 2;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<p>
Hello World! :D
</p>
</div>