https://codepen.io/nhn34/pen/zVQyWG
I'm trying to overlap 3 photos using CSS Grid. This is the outcome that I want:
desired outcome
I tried following these tutorials that both uses the same method but they didn't work for me: https://www.superhi.com/video/overlapping-layouts-with-css-grid,
https://www.youtube.com/watch?v=sZJrcOfBaNY
The results that I get looks like in CodePen and I don't know where I did wrong!
These are my code:
section {
display: grid;
grid-template-columns: repeat(4, 1fr);
div:first-child {
grid-column: 2 / span 3;
}
div:nth-child(2) {
grid-column: 1 / span 2;
}
div:last-child {
grid-column: 2 / span 2;
}
}
<section>
<div>
<img src="img/cancer/face1.svg" alt="face1">
</div>
<div>
<img src="img/cancer/cancer.jpg" alt="cancer">
</div>
<div>
<img src="img/cancer/point1.svg" alt="point1">
</div>
</section>
you only missed specifing grid-row property
grid-row: 1;
good luck
Related
I have 4 icons which should align like the image below.
I've tried to first put them into a <div> with a class which controlls the position.
Now with my knowledge I would give every each image a absolute position, but that will not work, because on every res. my images are not together and just all over the place.
How can I align my images like a "flower" in a responsive way.
For a responsive layout you can use CSS grid:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
width: 50vw;
aspect-ratio: 3 / 2;
}
.container>div {
aspect-ratio: 1 / 1;
border: 1px solid black;
box-sizing: border-box;
}
.container>div:nth-child(1) {
grid-column: 1;
grid-row: 2 / span 2;
}
.container>div:nth-child(2) {
grid-column: 2;
grid-row: 1 / span 2;
}
.container>div:nth-child(3) {
grid-column: 3;
grid-row: 2 / span 2;
}
.container>div:nth-child(4) {
grid-column: 2;
grid-row: 3 / span 2;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Obviously set the container width to what you require.
This snippet sets the divs in a clockwise fashion starting at the left most div.
I have just recreated what you posted above. I can help you when you specify what you really need
.main {
display: flex;
height:100%;
align-items:center
}
.sec{
height: 50px;
width: 50px;
border:1px solid black
}
<div class="main">
<div class="sec"></div>
<div class="sec2">
<div class="sec"></div>
<div class="sec"></div>
</div>
<div class="sec"></div>
</div>
Need to create 3 columns wrapped in a flex container and aligned vertically
.wrapper {
display: flex;
}
.column {
align-items: center;
}
(I am trying to convert this data entry page from a very primitive CSS/HTML "table" layout to something a bit better, using CSS Grid layout).
In line with common practice, it seems, I've made it 12 columns wide. Each entry field has a label, of the same width. In other words my CSS is currently very repetitive:
.container {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: 10px;
}
#SigNameLabel {
grid-column: 1 / 13;
grid-row: 2;
}
#SignatureName {
grid-column: 5 / 13;
grid-row: 2;
}
#PaymentNoLabel {
grid-column: 1 / 13;
grid-row: 3;
}
#PaymentNo {
grid-column: 5 / 13;
grid-row: 3;
}
#CurrencyLabel {
grid-column: 1 / 13;
grid-row: 4;
}
#Currency {
grid-column: 5 / 13;
grid-row: 4;
}
* {
border: 1px solid #999;
}
<div class="container">
<div id='SigNameLabel' class='unselectable'>Signature name:</div>
<div id='SignatureName' class='unselectable dataField single-line'></div>
<div id='PaymentNoLabel' class='unselectable'>Payment No:</div>
<div id='PaymentNo' class='unselectable dataField single-line'></div>
<div id='CurrencyLabel' class='unselectable'>Currency:</div>
<div id='Currency' class='dataField single-line'></div>
</div>
Short of using JS to "create" the layout in automated fashion, i.e. by analysing the DIVs in the container, is there any way to make the CSS less cumbersome and explicit, more just "taking its lead from" what the HTML does?
For example, I have had to give a specific ID to each of the labels here: when they each sat in their own TD they didn't need that. Is there any way each such label DIV could be given a class, say left-hand-column, and somehow they could all have grid-column: 1 / 13 applied to them, and somehow the same grid-row as the data field DIV to their right?
You can simplify your code like below. And you don't necessarily need 12 columns
.container {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-gap: 10px;
}
.container>*:nth-child(even) {
grid-column: span 2;
border:1px solid;
}
.container>*:nth-child(odd) {
/* Not sure if you need this but it will allow
the full width of the grid like your code grid-column: 1 / 13;
width:calc(300% + 2*10px); */
border:1px solid red;
}
<div class="container">
<div id='SigNameLabel' class='unselectable'>Signature name:</div>
<div id='SignatureName' class='unselectable dataField single-line'></div>
<div id='PaymentNoLabel' class='unselectable'>Payment No:</div>
<div id='PaymentNo' class='unselectable dataField single-line'></div>
<div id='CurrencyLabel' class='unselectable'>Currency:</div>
<div id='Currency' class='dataField single-line'></div>
</div>
I am struggling to get what I want and I am not sure if its even possible.
Tried everything I got, showing some code below
section {
display: grid;
grid-template-columns: auto auto auto auto;
}
section > *{
border: 1px solid red;
}
section > h1{
grid-row: 1;
grid-column: 2 / 3;
}
section > h2{
grid-row: 2;
grid-column: 2 / 3;
}
section > img{
grid-row: 1/2;
grid-column: 1 / 3;
width: 20%;
}
section > span{
grid-row: 1;
grid-column: 3 / 3;
}
<div>
<section>
<h1>HEADING</h1>
<img src=img.png alt="">
<h2>HEADING 2</h2>
<span>11:44</span>
</section>
<section>
<h1>HEADING</h1>
<img src=img.png alt="">
<h2>HEADING 2</h2>
<span>11:44</span>
</section>
...
</div>
I want the image to appear left, using the upper and lower cell, so full height.
I want the h1 to use the upper center space.
I want the h2 to use the lower center space.
i want the span to use the upper right space.
The lower right space should be combined with the lowercenter in case the content of lowercenter overflows.
You were almost there but there were some issues.
You defined a four column grid but your description only requires three.
grid-template-columns: auto 1fr 1fr; /* (seems more appropriate) /*
* {
margin: 0 !important;
}
section {
display: grid;
grid-template-columns: auto 1fr 1fr;
}
section>* {
border: 1px solid red;
}
section>h1 {
grid-row: 1;
grid-column: 2 / 3;
}
section>h2 {
grid-row: 2;
grid-column: 2 / 4;
/* span 2 columns*/
}
section>img {
grid-row: 1 / 3;
/* span 2 rows */
}
section>span {
grid-row: 1;
}
<section>
<h1>HEADING</h1>
<img src="https://placekitten.com/200/200" alt="">
<h2>HEADING 2</h2>
<span>11:44</span>
</section>
I want the h2 to use the lower center space.
I want the span to use the upper right space.
The lower right space should be combined with the lowercenter in case the content of lowercenter overflows.
The h2 area is supposed to span 2 columns so we extend it out into column 3.
I want to be able to reverse the order of columns (the 2 small to the left, the big one right). I've tried several solutions but didn't find one that works.
Here's the code:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: 708fr 340fr;
& > div:first-child{
grid-row: span 2;
}
&.reverse{
grid-template-columns: 340fr 708fr;
& > div:first-child{
order: 2; // doesn't work (I want to place the first item at the end of the 3)
}
}// reverse
}// images-block-box
Note that I really want to reverse the order of the columns themselves, not just their dimensions.
Simply adjust grid-column and conisder grid-auto-flow:dense; to allow the next elements to be placed before:
.grid {
display: grid;
grid-gap: 16px;
grid-template-columns: 2fr 1fr;
grid-auto-flow:dense;
margin:5px;
}
.grid div {
min-height: 50px;
border: 1px solid;
}
.grid div:first-child {
grid-row: span 2;
}
.grid.reverse {
grid-template-columns: 1fr 2fr;
}
.grid.reverse div:first-child {
grid-column:2;
}
<div class="grid">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid reverse">
<div></div>
<div></div>
<div></div>
</div>
dense
If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.ref
Another option is to place the big box to the last column by using grid-column-end: -1 - see demo below:
.images-block-box {
display: grid;
grid-gap: 16px;
grid-template-columns: 708fr 340fr;
grid-template-rows: 100px 100px;
grid-auto-flow: column;
}
.images-block-box>div {
border: 1px solid;
}
.images-block-box>div:first-child {
grid-row: span 2;
}
.images-block-box.reverse {
grid-template-columns: 340fr 708fr;
}
.images-block-box.reverse>div:first-child {
grid-column-end: -1;
}
<div class="images-block-box">
<div></div>
<div></div>
<div></div>
</div>
<br/>
<div class="images-block-box reverse">
<div></div>
<div></div>
<div></div>
</div>
grid-column-end
<integer> && <custom-ident>?
Contributes the nth grid line to the grid
item’s placement. If a negative integer is given, it instead counts in
reverse, starting from the end edge of the explicit grid.
Since there are 2 answers that could be marked as accepted (thanks to #kukkuz and #Temani Afif) I'm posting here a sum up. The working techniques pointed out till now are:
grid-auto-flow: dense (container) + grid-column: 2 (first-child)
grid-auto-flow: column (container) + grid-column-end: -1 (first-child)
The rest of the code remains the same. Please take a look at the related answers.
Both are currently working well (at least in major/modern browsers).
Then Maybe You can use a different approach
.grid {
display: grid;
grid-template-columns: 5fr 2fr;
grid-template-rows: 1fr 1fr;
height: 500px;
grid-gap: 2rem;
}
.one {
background-color: red;
grid-row: 1 / 3;
}
.two {
background-color: green;
}
.three {
background-color: blue;
}
.reverse > .one {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.reverse > .three {
grid-column: 1 / 2;
grid-row: 1 / 3;
}
<h1>Without Reverse</h1>
<div class="grid">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
<h1>With Reverse</h1>
<div class="grid reverse">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
I am trying to get the content of item to be in the middle column, but it does not seem to be moving.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
div {
text-align: center;
margin: 2vh;
}
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="/src/imgs/sitelogo.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
https://css-tricks.com/snippets/css/complete-guide-grid/
The elements you want to center are descendants, but not children, of the grid container.
Because grid layout only extends between parent and child elements, the .item element is out of scope and will not accept grid properties.
But these elements are inline-level children of a block container, which means that text-align: center will work.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
text-align: center; /* NEW */
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
jsFiddle demo
If you want to use the grid for a child of your container, you can always just inherit the same properties.
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
grid-column: 1 / span 3;
grid-row: 2 / span 3;
background: #81d4fa;
/* inherit the container-grid setup */
display: grid;
grid-template-columns: inherit;
grid-template-rows: inherit;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
div {
text-align: center;
margin: 2vh;
}
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="https://dummyimage.com/200x50/cccccc/ffffff.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>
As others have pointed out, since the item element isn't a direct child of the grid container - you can't apply grid properties to it.
Obviously, to fix this you could pull the item out of the home-main div and make it a direct child of the grid - but I'm guessing that that's not a viable solution here :)
Grid Layout Module Level 2 - Subgrids are supposed to solve this problem.
Subgrid is currently only a draft spec, but fwiw, in your case you would do something like:
.home-main {
display: subgrid;
grid-column: span 3;
}
Nevertheless, there actually is a way to pull this off:
display: contents (caniuse)
From Caniuse:
display: contents causes an element's children to appear as if they
were direct children of the element's parent, ignoring the element
itself. This can be useful when a wrapper element should be ignored
when using CSS grid or similar layout techniques.
So in order for the grid placement properties to work on the item, you could simply add display: contents; to home-main (currently working in Firefox)
(NB: This will obviously render the grid properties on home-main useless - but then again - they aren't necessary to place the item)
.home-main {
display: contents;
...
}
.home-grid-container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 0.10fr 0.98fr auto;
height: 100vh;
}
.home-header {
grid-column: 1 / span 3;
grid-row: 1 / span 1;
background: #3f51b5;
}
.home-main {
/*grid-column: 1 / span 3;
grid-row: 2 / span 3; */
display: contents;
background: #81d4fa;
}
.item {
grid-column: 2 / span 1;
grid-row: 2 / span 3;
background: salmon;
}
.home-footer {
grid-column: 1 / span 3;
grid-row: 5 / span 1;
background: #3f51b5;
}
.home-footer div {
text-align: center;
margin: 2vh;
}
<div class="home-grid-container">
<div class="home-header">
<h1>
<img src="/src/imgs/sitelogo.png" />
</h1>
</div>
<div class="home-main">
<div class="item">
Simple, Fast, Powerful
<input type="button" value="100% Free" />
</div>
</div>
<div class="home-footer">
<div>All Rights Reserved</div>
</div>
</div>