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
Related
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;
Can we swap items from different div using CSS?
I need to move item duaA to satuA and otherwise. Is it possible?
I have something like this:
<div id="satu">
<div class="satuA"></div>
<div class="satuB"></div>
</div>
<div id="dua">
<div class="duaA"></div>
<div class="duaB"></div>
</div>
.parent {
display: flex;
direction: rtl;
align-items: right;
justify-content: flex-end;
}
<div class="parent">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaA</div>
</div>
</div>
Do you need like that way. I have used Direction css.
I don't think it is possible to use CSS to swap physical content (if you mean that), but it is in JavaScript.
function swap() {
const satu = document.getElementById("satu").innerHTML
const dua = document.getElementById("dua").innerHTML
document.getElementById("satu").innerHTML = dua
document.getElementById("dua").innerHTML = satu
}
swap()
console.log(document.getElementById("content").innerHTML)
<div id="content">
<div id="satu">
<div class="satuA"></div>
<div class="satuB"></div>
</div>
<div id="dua">
<div class="duaA"></div>
<div class="duaB"></div>
</div>
</div>
Following my first comment, Here is a grid possibility from a common container for both parents:
Follow my second comment : Is it 2 or 4 of them to swap and then, to which position exactly? Is it a simple row, a simple column or a columns and rows layout? , if snippet below do not answer your question.
grid demos:
#satudua {
display: grid;
}
div div {
margin: 4px;
border: solid 2px;
}
#satu,
#dua {
grid-row: 1;
grid-column: 1;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr)
}
.satuA {
grid-row: 2;
grid-column: 1;
color: green
}
.duaA {
grid-row: 1;
grid-column: 1;
color: tomato
}
.satuB {
grid-row: 1;
grid-column: 2;
}
.duaB {
grid-row: 2;
grid-column: 2;
}
div div div:first-of-type:before {
content: ' Swapped ';
color: black;
}
<div id="satudua">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaB</div>
</div>
</div>
or was it side by side ?
#satudua {
display: grid;
}
div div {
margin: 4px;
border: solid 2px;
}
#satu,
#dua {
grid-row: 1;
grid-column: 1;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr)
}
#satu>div {
grid-column: 1;
grid-row: 2;
}
#dua>div {
grid-column: 2;
grid-row: 2;
}
#satu>.satuA {
grid-row: 1;
grid-column: 2;
color: green
}
#dua>.duaA {
grid-row: 1;
grid-column: 1;
color: tomato
}
div div div:first-of-type:before {
content: ' Swapped ';
color: black;
}
<div id="satudua">
<div id="satu">
<div class="satuA">satuA</div>
<div class="satuB">satuB</div>
</div>
<div id="dua">
<div class="duaA">duaA</div>
<div class="duaB">duaB</div>
</div>
</div>
I have the following grid layout:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="index-view"></div>
</div>
and I am trying to insert a new div between sidebar and index such that the resulting layout will be like:
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
My attempt so far has been:
.main-page {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: 72px 1fr;
height: 100%;
}
.main-page > .side-bar {
display: grid;
grid-row: 1/4;
width: 80px;
}
.main-page > .profile-pane {
width: 260px;
position: relative;
grid-row: 2/4;
}
.main-page > .index-view {
grid-row: 2/4;
}
This renders a huge space between profile and index and compresses index to the right. I've been trying different values for the grid-row property but to no avail. However, if I remove either one of profile and index, the remaining div will render nicely and right beside the sidebar. How do I achieve the second layout?
You can consider different values based on the existance of the profile element:
.main-page {
display: grid;
grid-template-columns: 80px 1fr 4fr;
grid-template-rows: 72px 1fr;
height: 200px;
margin:20px;
}
.side-bar {
grid-row: span 2;
}
.nav-bar,
.index-view {
grid-column:span 2;
}
/* Take only one clumn if profile exist*/
.profile-pane + .index-view {
grid-column:span 1;
}
/* Irrelevant code */
.main-page > * {
border:1px solid;
}
.main-page > *:before {
content:attr(class);
}
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<!--<div class="profile-pane"></div>-->
<div class="index-view"></div>
</div>
<div class="main-page">
<div class="side-bar"></div>
<div class="nav-bar"></div>
<div class="profile-pane"></div>
<div class="index-view"></div>
</div>
You can achieve the desired result by setting the "grid-row: span 2" property in the sidebar to increase its height by two lines. And for the navigation bar, the "grid-column: span 2" property is to expand it into two columns
Oh yes, and do not forget to set the columns of the required width for the grid container grid-template-columns: 10% 15% 70%;
Result:
.main-page {
display: grid;
grid-template-columns: 10% 15% 70%;
}
.main-page>* {
padding: 20px;
border: 1px solid #000;
}
.side-bar {
grid-row: span 2;
}
.nav-bar {
grid-column: span 2;
}
.index-view {
min-height: 500px;
}
<div class="main-page">
<div class="side-bar">side-bar</div>
<div class="nav-bar">nav-bar</div>
<div class="profile-pane">profile-pane</div>
<div class="index-view">index-view</div>
</div>
I'm using grid for this layout and I'm halfway through. As you can see number 10,20,30,40,50 gets placed on the same spot (I place them there). I would like to have my layout as from 1 to 10 are
Large on the left (1,11,21,31,41...), 4 small on the right
Large on the right (10,20,30,40...), 4 small on the left
NOTE, this list can contain from 40-100 items, so using fixed positions to place it there would not be an option. Also the making nr 6 large and changing the order does not work either due to sorting.
Hope it's clear what I'm trying to do here.
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
grid-row: 3 / span 2;
}
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
<div class="layout-scale__items">12</div>
<div class="layout-scale__items">13</div>
<div class="layout-scale__items">14</div>
<div class="layout-scale__items">15</div>
<div class="layout-scale__items">16</div>
<div class="layout-scale__items">17</div>
<div class="layout-scale__items">18</div>
<div class="layout-scale__items">19</div>
<div class="layout-scale__items">20</div>
<div class="layout-scale__items">21</div>
<div class="layout-scale__items">22</div>
<div class="layout-scale__items">23</div>
<div class="layout-scale__items">24</div>
<div class="layout-scale__items">25</div>
<div class="layout-scale__items">26</div>
<div class="layout-scale__items">27</div>
<div class="layout-scale__items">28</div>
<div class="layout-scale__items">29</div>
<div class="layout-scale__items">30</div>
<div class="layout-scale__items">31</div>
<div class="layout-scale__items">32</div>
<div class="layout-scale__items">33</div>
<div class="layout-scale__items">34</div>
<div class="layout-scale__items">35</div>
<div class="layout-scale__items">36</div>
<div class="layout-scale__items">37</div>
<div class="layout-scale__items">38</div>
<div class="layout-scale__items">39</div>
<div class="layout-scale__items">40</div>
<div class="layout-scale__items">41</div>
<div class="layout-scale__items">42</div>
<div class="layout-scale__items">43</div>
<div class="layout-scale__items">44</div>
<div class="layout-scale__items">45</div>
<div class="layout-scale__items">46</div>
<div class="layout-scale__items">47</div>
<div class="layout-scale__items">48</div>
<div class="layout-scale__items">49</div>
<div class="layout-scale__items">50</div>
</div>
All green boxes start at 3rd row (grid-row: 3 / span 2) so they are in the same place.
Also, if I understood the pattern in your mind, you have to use indexes 1,11,21,.. and indexes 8,18,28,...
Try this:
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 8) {
background-color: lime;
grid-column: span 2;
grid-row: span 2;
}
I have landed in solving it with "fixed" position on grid-row. I have a loop in scss that generates it for the :nth-child(). The 10 extra classes are worth it compared to the extra markup and css to solve it with a "row" "bootstrap if you will" approach, and even more css for eventually that would be for a fallback solution. For my use case it will not be more than 100 items. If your case use more then 100 items just change the loop times.
$increment: 3;
// change the 10 to your wanted amount
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}
My full solution is on jsfiddle (due to internal code editor does not support scss)
<div class="layout-scale">
<div class="layout-scale__items">1</div>
<div class="layout-scale__items">2</div>
<div class="layout-scale__items">3</div>
<div class="layout-scale__items">4</div>
<div class="layout-scale__items">5</div>
<div class="layout-scale__items">6</div>
<div class="layout-scale__items">7</div>
<div class="layout-scale__items">8</div>
<div class="layout-scale__items">9</div>
<div class="layout-scale__items">10</div>
<div class="layout-scale__items">11</div>
...
</div>
.layout-scale {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-gap: 1rem;
}
.layout-scale__items {
background-color: aqua;
min-height: 10rem;
}
.layout-scale__items:nth-child(10n + 1) {
background-color: deeppink;
grid-column: span 2;
grid-row: span 2;
}
.layout-scale__items:nth-child(10n + 10) {
background-color: lime;
grid-column: 3 / span 2;
}
$increment: 3;
#for $i from 1 through 10 {
.layout-scale__items:nth-child(#{$i*10}) {
grid-row: #{$increment} / span 2;
}
$increment: $increment + 4;
}
I have a 3 X 3 CSS Grid.
I have a row in which I have three items A, B & C.
I want item C to have a rowspan of 2.
To do so, I am using grid-row: 1 / span 2;. It is taking two rows, but it's being placed in the first column instead of simply lying in the 3rd column. I don't know why this is happening.
I want item C to stay at the place where it is in the HTML.
One work around to this problem is to explicitly setting grid-column: 3 / span 1 which I don't want to do. I want items to be placed the way they are in HTML.
Is there any way to suppress this behavior?
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
h1 {
border: 2px solid;
padding: 0;
margin: 0;
font-size: 20px;
}
.a {
grid-row: 1 / span 2;
background: orange;
}
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
</div>
Another way of solving it (That points to the reason why is stating a row for the other items):
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
h1 {
border: 2px solid;
padding: 0;
margin: 0;
font-size: 20px;
}
.a {
grid-row: 1 / span 2;
background: orange;
}
.b {
grid-row: 1;
}
<div class="grid-container">
<div class="b">
<h1>A</h1>
</div>
<div class="b">
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
</div>
And the reason of this behaviour is that the more restrictive elements get positioned first. This way, the possibilities of the grid algorithm to achieve a solution are bigger.
That is, an element that has a requirement will be positioned first, elements that don't have a requirement last.
Steps 2 (for a item) and 4 (for the remaining items) in this part of the spec
If only one gets stock to a row number it will come first and stick there ahead in the flow. To avoid this, other grid items needs to be set to a defaut row as well.
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
div {
grid-row: 1;/* here is the basic fix but will set each item on first row */
}
h1 {
border: 2px solid;
padding: 0;
margin: 0;
font-size: 20px;
}
.a {
grid-row: 1 / span 2;
background: orange;
}
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
</div>
Else you need also to tell in which grid-column it should stand
.a {
grid-row: 1 / span 2;
grid-column:3;
background: orange;
}
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
h1 {
border: 2px solid;
padding: 0;
margin: 0;
font-size: 20px;
}
.a {
grid-row: 1 / span 2;
grid-column:3;
background: orange;
}
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
</div>
or let auto placement do its job while only setting how many rows to span, wich is here, in my own opinion, the most flexible way with a minimum of css rules/selector to set, too much grid kills grid :) , make it simple :
.a {
grid-row: span 2;
background: orange;
}
snippet with a few example letting the .aclass do its job without setting the column nor the row number where to stand, it will just be spanning where it stans in the flow
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
h1 {
border: 2px solid;
padding: 0;
margin: 0;
font-size: 20px;
}
.a {
grid-row: span 2;
background: orange;
}
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
</div>
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div class="a">
<h1>B</h1>
</div>
<div>
<h1>C</h1>
</div>
</div>
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div>
<h1>C</h1>
</div>
<div>
<h1>D</h1>
</div>
<div>
<h1>E</h1>
</div>
<div class="a">
<h1>F</h1>
</div>
<div>
<h1>G</h1>
</div>
<div>
<h1>H</h1>
</div>
</div>
<hr/>
<div class="grid-container">
<div>
<h1>A</h1>
</div>
<div>
<h1>B</h1>
</div>
<div class="a">
<h1>C</h1>
</div>
<div>
<h1>D</h1>
</div>
<div>
<h1>E</h1>
</div>
<div>
<h1>F</h1>
</div>
<div>
<h1>G</h1>
</div>
<div>
<h1>H</h1>
</div>
</div>
Clearly, there's something in the spec that causes this behavior. I'm not yet sure what it is. (Update: see #Vals' answer for an explanation.)
However, here's a valid and simple solution:
Instead of:
.a {
grid-row: 1 / span 2;
}
Use:
.a {
grid-row-end: span 2;
}
From the spec:
9.3. Line-based Placement: the grid-row-start,
grid-column-start, grid-row-end, and grid-column-end
properties
The grid-row-start, grid-column-start, grid-row-end, and
grid-column-end properties determine a grid item’s size and location
within the grid by contributing a line, a span, or nothing (automatic)
to its grid placement, thereby specifying the inline-start,
block-start, inline-end, and block-end edges of its grid area.
...
For example, grid-column-end: span 2 indicates the second grid line
in the endward direction from the grid-column-start line.
Also, consider this single rule that gives you full control and makes it all work:
.a {
grid-area: 1 / 3 / 3 / 4;
}
jsFiddle
The grid-area shorthand property parses values in this order:
grid-row-start
grid-column-start
grid-row-end
grid-column-end
Note the counter-clockwise direction, which is the opposite of margin and padding.