How to offset a div in a css grid - html

It's possible to "offset" a div in a css grid as in the image ?

Consider negative margin:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 500px;
height: 200px;
border: 1px solid;
}
.box {
grid-column: 2/3;
margin-left: -20px;
margin-right: -80px;
background: red;
}
.box-alt {
grid-column: 2/3;
grid-row:2;
background: blue;
}
<div class="container">
<div class="box"></div>
<div class="box-alt"></div>
</div>

<div class="container">
<div class="area1"></div>
<div class="area2"></div>
</div>
.container{
display: grid;
grid-template: 1fr / repeat(3, 1fr);
grid-template-areas: "area1 offset area2";
}
.area{
width: 100%;
height: 40px;
}
.area1{
background-color: red;
}
.area2{
background-color: yellow;
}

If you are using Mozilla's guide in this link, you can use empty div like this as offset div:
<div class="container">
<div class="row">
<!-- Empty/Offset Div Here -->
<div class="col-xl-2"> </div>
<div class="col-xl-8">
<!-- Content Here -->
</div>
</div>
</div>

Related

How to create a three-column list in with items arranged vertically

I have a problem to style a ul using display: grid. The list should look like the picture below. Elements in this ul can have different heights.
Expected behavior
So far I've added a styles for
ul: grid-template-columns: 1fr 1fr 1fr and grid-auto-flow: column.
For li elements, depending on in which column element should be:
grid-column: 1 or grid-column: 2 or grid-column: 3.
.wrapper {
margin: 0;
padding: 0;
list-style-type: none;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-flow: columns;
row-gap: 10px;
column-gap: 10px;
}
.first-column {
grid-column: 1;
height: 200px;
background-color: skyblue;
}
.second-column {
grid-column: 2;
height: 500px;
background-color: aquamarine;
}
.third-column {
grid-column: 3;
height: 300px;
background-color: silver;
}
<ul class="wrapper">
<li class="first-column"></li>
<li class="first-column"></li>
<li class="second-column"></li>
<li class="second-column"></li>
<li class="third-column"></li>
<li class="third-column"></li>
</ul>
However, this causes the row height to be determined by the highest element in the row. Just like in the picture below.
current behavior
Here's how I did it:
.grid{
display: grid;
grid-template-columns: 100px 200px 100px;
column-gap: 50px; /* The gap you want */
}
.col{
display: grid;
grid-template-rows: repeat(4, 100px);
row-gap: 100px; /* The gap you want */
}
.col.spec{
grid-template-rows: repeat(3, 200px);
row-gap: 50px; /* The gap you want */
}
.elm{
width: 100%;
border: 1px solid black;
}
<div class="grid">
<div class="col">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
<div class="col spec">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
<div class="col">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
</div>
You can always adjust the stylings and dimensions as you want but make sure to make it responsive.

How to use CSS grid to create 3x3 grid but place items in specific grid columns

I'm trying to create a layout that looks like this:
The blue blocks are divs. It's essentially a 3x3 grid but with gaps in the 3rd and 4th grid column.
How can I create a gap within CSS grid to achieve this layout? I've tried it with flexbox, but couldn't achieve the above, so hoping a grid layout is the answer.
Here's my code:
.container{
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
". . ."
". . .";
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
CSS grid allows you to choose which row and column an element will start in (and indeed, though not needed in your case, how many columns/rows it is to span).
This snippet gives the 3rd and 4th children of the wrapper specific grid positions.
.container {
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 10px;
}
.item {
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column: 2;
grid-row: 2;
}
.item:nth-child(4) {
grid-column: 3;
grid-row: 2;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
Note: just for a demo it has also introduced a non-zero grid-gap. The grid-area settings have been removed as not needed if the above method is followed.
A simplified version of the CSS grid solution with only the necessary code:
.container{
border: 1px solid;
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap:5px;
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column:2;
}
.item:nth-child(4) {
grid-column:3;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
How about padding/margin?
.container {
border: 1px solid #777;
display: inline-grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0 0;
grid-template-areas:
". . ."
". . .";
}
.item {
border: 1px solid lightgrey;
padding: 2px 0;
width: 55px !important;
height: 50px !important;
margin: 1px !important;
background: #1657c9;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
color: white;
}
.item-text {
position: relative;
top: 38%;
margin: 0;
font-size: normal;
}
.item-3, .item-4 {
position: relative;
left: 100%;
}
<div class="container">
<div class="item item-1"><span class="item-text">1</span></div>
<div class="item item-2"><span class="item-text">2</span></div><br>
<div class="item item-3"><span class="item-text">3</span></div>
<div class="item item-4"><span class="item-text">4</span></div>
</div>
You can try this:
This is HTML:
<div class="parent">
<div class="div1"> </div>
<div class="div2"> </div>
<div class="div3"> </div>
<div class="div4"> </div>
</div>
and CSS
.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 / 2 / 2;
background: blue;
height: 3rem;
margin: 1rem;
}
.div2 {
grid-area: 1 / 2 / 2 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div3 {
grid-area: 2 / 2 / 3 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div4 {
grid-area: 2 / 3 / 3 / 4;
background: blue;
height: 3rem;
margin: 1rem;
}

How do I get rid of the space between the menu bar and the side nav?

How do I get rid of the space between the menu bar and the sidebar caused by typing hello.
I have tried
display:inline-block; and overflow:hidden; which got rid of the white space that was there previously and now filled it up with a color. I have also tried taking the content div and moving it so it isn't a parent(?) of .sidebar but then "hello" just ends up on the bottom of the page. I want to keep the "hello" text centered on the yellow area without having a space between the side bar and the menu bar.
Picture of the website
.menucontain{
display:grid;
grid-template-columns:1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap:5px;
color:#F2F0D0;
text-align:center;
background-color:#204959;
font-family:helvetica;
padding:15px;
}
.sidebar{
background:#204959;
width:18%;
height:800px;
text-align:center;
color:#F2F0D0;
font-family:helvetica;
display:grid;
grid-template-rows: repeat(6 ,50px);
grid-gap:2px;
}
.side1{
background:gray;
padding-top:15px;
}
.content{
background-color:#F2F0D0;
text-align:center;
overflow:hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
<!--menu contain div on next line-->
</div>
<div class="content">
<p>hello</p>
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
</div>
Here is the correct solution to your problem.
First, move the tag <p> in sequence for sidebar. Like this:
...
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<p>hello</p>
...
Secondly, assign the grid rules for the .content class by adding this to your css:
.content {
display: grid;
grid-template-columns: 18% 1fr;
}
And remove the width rules - width: 18% out of .sidebar selector. Because we defined the width as 18% in the grid rule above.
.menucontain {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap: 5px;
color: #f2f0d0;
text-align: center;
background-color: #204959;
font-family: helvetica;
padding: 15px;
}
.content {
display: grid;
grid-template-columns: 18% 1fr;
}
.sidebar {
background: #204959;
/*width: 18%;*/
height: 800px;
text-align: center;
color: #f2f0d0;
font-family: helvetica;
display: grid;
grid-template-rows: repeat(6, 50px);
grid-gap: 2px;
}
.side1 {
background: gray;
padding-top: 15px;
}
.content {
background-color: #f2f0d0;
text-align: center;
overflow: hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
<!--menu contain div on next line-->
</div>
<div class="content">
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<p>hello</p>
</div>
The p tag is a block element, to remove the space you have to remove hello <\p> from the 'content' class
Use flex display or grid display on the 'content' class
Re-aling the 3 different parts (menucontain, sidebar, content) into a grid by declaring the body as a grid. Sicne you already use grids to style the menucontain and sidebar, you have to switch them to a subgrid.
body {
margin: 0;
display: grid;
grid-template-columns: 18vw auto;
grid-template-rows: min-content auto;
min-height: 100vh;
}
.menucontain {
grid-column: span 2;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: subgrid;
grid-column-gap: 5px;
color: #F2F0D0;
text-align: center;
background-color: #204959;
font-family: helvetica;
padding: 15px;
}
.sidebar {
background: #204959;
height: 800px;
text-align: center;
color: #F2F0D0;
font-family: helvetica;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: repeat(6, 50px);
grid-gap: 2px;
}
.side1 {
background: gray;
padding-top: 15px;
}
.content {
background-color: #F2F0D0;
text-align: center;
overflow: hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
</div>
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<div class="content">
<p>hello</p>
</div>

Let CSS grid row fill available space

I'm working with CSS-grids and I want the last row of my CSS-grid to use all remaining space in the wrapper but at the same time I want all other rows to follow the min-content-strategy.
CSS for the wrapper:
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-auto-rows: min-content;
row-gap: 7px;
justify-items: start;
align-items: start;
}
My initial idea how to achieve this was to simply add margin-top: auto to the button as one would do with flexbox. I have also tried to set grid-auto-rows: auto for the grid wrapper but it does not work either.
Edit: Example code: https://jsfiddle.net/xt139o2g/ (I want button to appear in lower right corner of the wrapper div)
.wrapper {
border: 1px solid blue;
height: 300px;
width: 250px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-auto-rows: min-content;
row-gap: 7px;
justify-items: start;
align-items: start;
}
.button {
grid-column: 1 / -1;
justify-self: end;
align-self: end;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>
Thanks in advance!
You can use the repeat function to set the first two rows to min-content:
grid-template-rows: repeat(2, min-content);
Then, use display: flex on .button and shift its content to the bottom right using justify-content and align-items:
display: flex;
align-items: flex-end;
justify-content: flex-end;
Demo: (I've added borders to demonstrate the spacing.)
.wrapper {
border: 1px solid blue;
height: 300px;
width: 250px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-template-rows: repeat(2, min-content);
row-gap: 7px;
}
.grid>div {
width: 100%;
height: 100%;
border: 1px solid;
}
.button {
display: flex;
align-items: flex-end;
justify-content: flex-end;
grid-column: 1 / -1;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>
I don't think there is a trivial way to achieve this but you can appromxiate it like below:
.wrapper {
display:inline-block;
border: 1px solid blue;
height: 300px;
width: 200px;
padding: 10px;
}
.grid {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 100px auto;
grid-template-rows:repeat(100,min-content) 1fr; /* big number here*/
}
.grid *:not(:last-child) {
margin-bottom:7px; /* replace the gap */
}
.button {
grid-column: 1 / -1;
grid-row: 101; /* place it at the 1fr template */
margin:auto 0 0 auto;
}
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R2C1
</div>
<div>
R2C2
</div>
<div class="button">
Button
</div>
</div>
</div>
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div class="button">
Button
</div>
</div>
</div>
<div class="wrapper">
<div class="grid">
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div>
R1C1
</div>
<div>
R1C2
</div>
<div class="button">
Button
</div>
</div>
</div>

Forcing a div to be full page height without using 100vh

This is a simplified HTML & CSS code to what I currently have in project. Essentially since I'm using ReactJS & routes, I can't wrap everything inside another container with a css grid so I'm looking for solutions to get full page height on both the 'sidebar' & 'content' classes.
I do understand that I could use 100vh and substract from that the height of the header but in this case the header doesn't have a fixed height so I'm looking for alternatives.
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
background-color: lightpink;
height: 100%;
}
.content {
background-color: orange;
height: 100%;
}
<div class="header">
<div>
One
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>
http://jsfiddle.net/de5ut6np/39/
You can consider the body as the main container:
html {
height:100%;
}
body {
margin:0;
height:100%;
display: grid;
grid-template-rows: max-content 1fr;
}
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
background-color: lightpink;
height: 100%;
}
.content {
background-color: orange;
height: 100%;
}
<div class="header">
<div>
One<br>
more
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>
I tested like this and it worked:
html {
height:100%;
}
body {
margin: 0;
height:100%;
display: grid;
grid-template-rows: max-content 1fr;
}
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
display: grid;
background-color: lightpink;
}
.content {
display: grid;
background-color: orange;
}
<div class="header">
<div>
One
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>