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
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.
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 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>
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>
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>