4 image panel grid with empty space in the middle (for email template) - html

I'm trying to recreate this 4 image structure in the way of the image below, however, I am doing this for an email template so the margin minus doesn't work.
generally, I tried to float left the images and replaced the margin minus with:
position: relative; top: -px;
, but that also doesn't work. am I even approaching this in the right way? or is there an easier way of doing this whole thing.
(the email template is done in SendGrid)

You can try with css grid and grid areas:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 10px;
justify-content: center;
}
.item {
padding: 1em;
}
.div1 {
grid-area: 1 / 1 / 2 / 3;
border: 1px solid red;
}
.div2 {
grid-area: 2 / 1 / 4 / 2;
border: 1px solid purple;
}
.div3 {
grid-area: 1 / 3 / 3 / 4;
border: 1px solid green;
}
.div4 {
grid-area: 3 / 2 / 4 / 4;
border: 1px solid blue;
}
<div class="item">text</div>
<div class="container">
<div class="div1 item"> 1</div>
<div class="div2 item"> 2</div>
<div class="div3 item"> 3</div>
<div class="div4 item"> 4</div>
</div>

Related

Is it possible to grid bootstrap vertically?

It seems that bootstrap can only produce horizontal grid systems which is making it hard for me to try develop a project. Here's what I am trying to do:
My page is divided into 4 sections, the leftside height of each blocks are different to the height of the rightside blocks.
I want to make the leftside have the same equal height while the right side has a different height each width which I can do when the grid is a horizontal system.
I want box1 and box2 to be the same height (vh-50) and then box3 to have the equal height.
my desired grid layout:
I've tried doing it like this but it doesn't work and look horrible.
#infoBox {
height: 50vh;
width: 60vh;
}
#tracklistBox {
height: 60vh;
width: 40vh;
}
#playBox {
height: 50vh;
}
#episodesBox {
height: 40vh;
}
<body class="d-flex flex-column min-vh-100">
<div class="container-fluid">
<div class="row ">
<div id="infoBox" class="col border">
1 of 2
</div>
<div id="tracklistBox" class="col border">
2 of 2
</div>
</div>
<div class="row">
<div id="playBox" class="col border">
1 of 3
</div>
<div id="episodesBox" class="col border">
2 of 3
</div>
</div>
</div>
</body>
It's not bootstrap but you can use the grid system
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 {
grid-area: 1 / 1 / 3 / 3;
background-color: aqua;
}
.div2 {
grid-area: 3 / 1 / 5 / 3;
background-color: yellow;
}
.div3 {
grid-area: 1 / 3 / 4 / 4;
background-color: violet;
}
.div4 {
grid-area: 4 / 3 / 5 / 4;
background-color: greenyellow;
}
<div class="parent">
<div class="div1">Box 1</div>
<div class="div2">Box 2</div>
<div class="div3">Box 3</div>
<div class="div4">Box 4</div>
</div>

How to make second column be the largest but also able to shrink?

I am new to CSS grid and trying to implement the second row only in the below picture.
I've tried to create six sections but have the second section spread out longer. For example I've tried:
grid-column: 2 / span 5;
But it seems to push the last four section to the next line cause it to wrap which I do not want.
my unsuccessful code:
.container {
border: solid black 3px;
height: 100px;
display: grid;
grid-template-columns: repeat(6, 1fr);
}
.item {
border: solid skyblue 1px;
}
.item:nth-of-type(2) {
/* grid-column: 2 / span 5; */
}
<div class="container">
<div class="item"></div>
<div class="item">Totals</div>
<div class="item">6000</div>
<div class="item">-</div>
<div class="item">194</div>
<div class="item">12.5%</div>
</div>
Try auto on the columns, with 1fr on the flexible one.
.container {
border: solid black 3px;
height: 100px;
display: grid;
grid-template-columns: minmax(100px, auto) 1fr repeat(4, minmax(100px, auto));
}
.item {
border: solid skyblue 1px;
}
<div class="container">
<div class="item"></div>
<div class="item">Totals</div>
<div class="item">6000</div>
<div class="item">-</div>
<div class="item">194</div>
<div class="item">12.5%</div>
</div>
jsFiddle demo
Try adding grid-auto-flow: column; to your .container and change grid-column: 2 / span 5; to grid-column: 2 / span 3;

div positioning right under the other inline

can someone please tell me why the 3rd div is looking that way instead of being right under the 1st div? And what would I need to write in my CSS file to make the 3rd div positioned right under the 1st one?
This is the HTML:
<div class="div-main">
<div class="div-1">
1
</div>
<div class="div-2">
2
</div>
<div class="div-3">
3
</div>
</div>
This is the CSS:
.div-main {
border: 5px solid yellow;
padding: 15px;
}
.div-1 {
border: 1px solid black;
padding: 15px;
width: 30%;
height: 30vh;
display: inline-block;
}
.div-2 {
border: 1px solid black;
padding: 15px;
width: 69%;
height: 50vh;
display: inline-block;
}
.div-3 {
border: 1px solid black;
padding: 15px;
width: 30%;
height: 30vh;
display: inline-block;
}
Why this is happening?
By default, the block elements, whether they are block or inline-block, will fill all the available space in the row, so if the blocks should have an overlapping situation, you can't achieve it with block approaches.
How to solve it?
With the CSS grid approach, you can make sure how each element should be positioned in your box. You can specify how your columns should be distributed by using the grid-template-columns, and how your rows should do it, with the grid-auto-rows property. You can also ensure how much of your current available space should be filled with the children by using grid-column and grid-row on each child.
The grid approach:
.div-main {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.div-1, .div-2, .div-3 {
border: 1px solid black;
}
.div-1 {
grid-column: 1 / 2;
grid-row: 1;
}
.div-2 {
grid-column: 2 / 4;
grid-row: 1 / 3;
}
.div-3 {
grid-column: 1;
grid-row: 2 / 3;
}
<div class="div-main">
<div class="div-1">1</div>
<div class="div-2">2</div>
<div class="div-3">3</div>
</div>
How the above code works?
In this example by default,
I distributed the available space for the column into 3 even blocks (grid-template-columns: repeat(3, 1fr)).
I set the minimum of each row to be 100px and allow them to grow if other blocks in the container want them to (grid-auto-rows: minmax(100px, auto)).
At last, I set the children to fill the available space the way I wanted (grid-column: *; grid-row: *;).
NOTE1: If in any case you want to make the third child gets bigger in height in comparison to the second child you can change the second part of grid-row: 2 / 3; to a bigger number like grid-row: 2 / 4;.
.div-main {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.div-1, .div-2, .div-3 {
border: 1px solid black;
}
.div-1 {
grid-column: 1 / 2;
grid-row: 1;
}
.div-2 {
grid-column: 2 / 4;
grid-row: 1 / 3;
}
.div-3 {
grid-column: 1;
grid-row: 2 / 4;
}
<div class="div-main">
<div class="div-1">1</div>
<div class="div-2">2</div>
<div class="div-3">3</div>
</div>
NOTE2: You can learn more about how CSS grid works in the CSS-tricks website with more examples.
Here I don't directly say why; I think others have done a great job there. Here I show how you can place items in columns in a container, and then forced some sizing to show the effect of doing that within individual blocks - and why sizing to the containing element might be more desirable at times.
I added a left/right block to illustrate the effect of creating logical groups of elements to work with by simply wrapping them in a group-left and group-right thus if you change grid-template-columns: minmax(150px, 30%) 30%; to grid-template-columns: minmax(150px, 30%) 1fr; the right group takes up whatever is remaining - a typical left/right layout where you have say links in the left group for example.
The only difference between the to major containers here is the content of each and those styles added to those contained elements.
.parent {
display: grid;
grid-template-columns: minmax(150px, 30%) 30%;
}
.group-left {
border: solid purple 3px;
background-color: #77008822;
}
.group-left>* {
margin: 1rem;
}
.group-right {
border: solid orange 3px;
}
.content-block {
/* just here to center the text in both directions */
display: grid;
place-items: center;
border: 1px solid;
}
/* below here is now just color and border styling and some forced sizing */
.div-main {
border: 5px solid yellow;
/* padding: 15px;*/
}
.div-1 {
border: 1px solid black;
/* force a height */
height: 30vh;
}
.div-2 {
border: 1px solid black;
/* force a height */
height: 50vh;
background-color: #eeffdd;
/* this can make the second block wider and potentially overlap the next column */
width: 20em;
}
.div-3 {
border: 1px solid black;
/* force a height */
height: 30vh;
}
.forced-height {
height: 30vh;
background-color: #44ddff33;
}
.img-force {
border: dashed 2px cyan;
width: 50%;
height: 30vh;
}
<div class="parent div-main">
<div class="group-left">
<div class="content-block div-1">1 is a happy one
</div>
<div class="content-block div-2">
2 here
</div>
</div>
<div class="group-right">
<div class="content-block div-3">
3 is not sad
</div>
</div>
</div>
<div class="parent">
<div class="group-left">
<div class="content-block">1 is a happy one
</div>
<div class="content-block forced-height">
2 here
</div>
</div>
<div class="group-right">
<div class="content-block">
<img class="img-force" src="" alt="no soup for you"> 3 is not sad
</div>
</div>
</div>
Inline elements can't position themselves like what you want as they're block level elements. You can use CSS grid and set div-2 to span two rows. There's a lot to grid but it's really flexible. Have a look. I've annotated the CSS so you can see how I've done it.
Some good resources on CSS tricks and here's a video by Kevin Powell that's a handy introduction.
.div-main {
border: 5px solid yellow;
padding: 15px;
/* this makes a grid layout with 2 columns and as many rows as needed. */
/* There's only 3 divs so that'll automatically give us 2 rows */
/* The grid-template-columns property is the width of each column - though there are some qualifications with this */
display: grid;
grid-template-columns: 30% 69%;
}
.div-main>div {
/* I've moved this to its own rule so you don't need to repeat yourself */
border: 1px solid black;
padding: 15px;
}
.div-1 {
/* I've kept the height of your original divs */
height: 30vh;
}
.div-2 {
height: 50vh;
/* setting grid-row: span 2 makes this div use two rows when it's being displayed */
/* this allows the third div to appear to the left */
/* in effect there's 4 cells in this grid but the last, bottom right cell is taken up by div-2 as we've told it to span 2 rows */
grid-row: span 2;
}
.div-3 {
height: 30vh;
}
<div class="div-main">
<div class="div-1">
1
</div>
<div class="div-2">
2
</div>
<div class="div-3">
3
</div>
</div>

Make a grid as big as the screen

I need the grid ad big as the page (it should touch the top the bottom and both sides) and I'd like it to be non-scrollable.
HTML:
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
CSS:
.wrapper {
padding-top: 10%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
I've read multiple questions but I couldn't find any solution that works fine for me.
As you can see in the picture above the grid doesn't touch neither the top or the bottom!
Set gird-auto-rows to use a percentage of the viewport height. Equal amounts per expected row. So in your case 25vh. Then remove any padding or margin around the grid.
html, body {
margin: 0
}
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 25vh;
width: 100%;
}
.prova{
border: 1px solid;
}
.wrapper div:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper div:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
<div class="wrapper">
<div class="prova">One</div>
<div class="prova"> </div>
<div class="prova">Three</div>
<div class="prova">Four</div>
<div class="prova"> five </div>
<div class="prova">Six</div>
<div class="prova">Seven</div>
<div class="prova">Eight</div>
<div class="prova">Nine</div>
<div class="prova">Ten</div>
<div class="prova">Eleven</div>
<div class="prova">Twelve</div>
</div>
If you want it to touches the top just remove the padding
And for other sides just set the width and height of the wrapper to 100vh and 100vw

Irregular grid lines on one part of css grid

I've got a really simple grid set up in CSS, but when I look at the grid lines in the inspector there's a strange irregularity at the bottom. I can't understand why this exists when the rest of the grid lines are all regular.
There's no special styling on div-4, it's just the same as the rest. Is it something to do with the margins produced by the h3 tag?
HTML
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>
CSS
.left-sidebar-grid {
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(8, 1fr);
grid-gap: 16px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 2 / 1 / 4 / 2; }
.div3 { grid-area: 4 / 1 / 10 / 2; }
.div4 { grid-area: 10 / 1 / 11 / 2; }
You defined only 8 explicit rows and you have placed the div4 starting at line 10 which will create 2 extra rows so you will end up with 10 rows in total where only 8 are sized using the 1fr and 2 will have an auto size: the empty one you see and the one where you placed div4.
To avoid this use grid-auto-rows:1fr instead of your template in order to make sure all the rows are sized the same way:
.left-sidebar-grid {
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap: 16px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 2 / 1 / 4 / 2; }
.div3 { grid-area: 4 / 1 / 10 / 2; }
.div4 { grid-area: 10 / 1 / 11 / 2; }
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>
You can also simplify your code like below:
.left-sidebar-grid {
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap: 16px;
}
.div1 {
grid-row:span 1;
}
.div2 {
grid-row:span 2;
}
.div3 {
grid-row:span 6;
}
.div4 {
grid-row:span 1;
}
<div class="left-sidebar-grid">
<div class="div1">
<h3>Div1</h3>
</div>
<div class="div2">
<h3>Div2</h3>
</div>
<div class="div3">
<h3>Div3</h3>
</div>
<div class="div4">
<h3>Div4</h3>
</div>
</div>