Columns overlapping while using grid layout - html

I'm using the grid layout in CSS and my aim is to have an image, text, an input field and a button next to each other, spanning over two rows as illustrated here:
I've given the image the grid-column property of 1 / 1 so that it is only in the first column, and all the other elements have 2 / 2 so that they are in the second column.
The problem I'm facing is that the second column is overlapping the first column, as seen in this snippet:
.profile {
display: grid;
grid-template-columns: auto 1fr;
grid-column-gap: 20px;
}
img {
border-radius: 50%;
height: 100%;
margin-right: 2%;
grid-column: 1 / 2;
grid-row: 1 / 2;
}
.profile>*:not(img) {
grid-column: 2 / 3;
}
.sameline {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="profile">
<img src="https://image.ibb.co/nr3C7T/pic.png">
<div class="sameline">
<h2>Title</h2>
<button>Click</button>
</div>
<form method="post">
<input type="text">
</form>
</div>

All you had to do was increase grid-column-gap. This makes them non overlapping. Change the styling to suit your needs.
.profile {
display: grid;
grid-template-columns: auto 1fr;
grid-column-gap: 100px;
}
img {
border-radius: 50%;
height: 100%;
margin-right: 2%;
grid-column: 1 / 1;
grid-row: 1 / 2;
}
.profile>*:not(img) {
grid-column: 2 / 2;
}
.sameline {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="profile">
<img src="https://image.ibb.co/nr3C7T/pic.png">
<div class="sameline">
<h2>Title</h2>
<button>Click</button>
</div>
<form method="post">
<input type="text" style="width:100%;">
</form>
</div>
Hope this helps.

I'm not sure if I understand your problem correctly, but I think what you mean is that the second column in the second row is overlapping.
The grid-row property is not correctly used in this case. This property works with grid lines. So the first value is used to specify from which grid line the item starts, and the second one specifies the grid line where it should end. So in your case, you say that it should start from grid line 1 (so essentially the top border of the grid) and that it should end at grid line 2 (which is the grid line between the two columns).
What you actually want is for the image to start at grid line 1 and end at grid line 3, so that it covers both of rows. The same rule applies to the grid-column property.
.profile {
display: grid;
grid-template-columns: auto 1fr;
grid-column-gap: 100px;
}
img {
border-radius: 50%;
height: 100%;
margin-right: 2%;
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.profile>*:not(img) {
grid-column: 2 / 3;
}
.sameline {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="profile">
<img src="https://image.ibb.co/nr3C7T/pic.png">
<div class="sameline">
<h2>Title</h2>
<button>Click</button>
</div>
<form method="post">
<input type="text">
</form>
</div>

Related

Align images responsive in a flower shape

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;
}

Can I fill a grid container from the center?

Is there a way to fill a grid from the center?
I have a CSS grid container which has a dynamic content(it gets updated so the number of children is not fixed) that looks like this:
#container {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
and if I had all 4 columns filled it would look like this :
1 2 3 4 //Numbers that represent containers children
Which is okay for me, but the problem comes when I have, for instance, only two divs inside my main container and then it looks like this:
1 2 0 0
And what I would like to achieve is this:
0 1 2 0
NEW ANSWER:
If you want to stick to just grid and assuming you only have four columns and the possible configurations are 0 1 0 0, 0 1 1 0, 0 1 1 1, 1 1 1 1 then following CSS works:
.container {
display: grid;
grid-template-columns: 25% 25% 25% 25%;
}
.col {
height: 50px;
background: green;
}
.col:first-child {
grid-column-start: 2;
}
.col:first-child:nth-last-child(4) {
grid-column-start: 1;
}
Assuming the HTML you have:
<div class="container">
<div class="col">
Col
</div>
<!-- Other Cols Here -->
</div>
Working Fiddle
ORIGINAL ANSWER:
For grids, it's not possible to center a dynamic number of elements. Grid layout is suitable for layouts with a fixed number of elements.
Refer to the use of grid vs flex layouts. Your problem is more suitable to be solved by flex where you use justify-content: center on flex containers to achieve centered children.
To achieve centered children, modify your styles on #container div:
#container {
display: flex;
justify-content: center;
}
Scenario where you want 0 1 0 0, 0 1 1 0, 0 1 1 1, 1 1 1 1 and assuming there are only four columns:
.container {
display: flex;
justify-content: center;
}
.col {
width: 25%;
height: 50px;
background: green;
}
.col:last-child:not(:nth-child(even)):first-child {
margin-left: -25%;
}
.col:last-child:not(:nth-child(even)):not(:first-child) {
margin-right: -25%;
}
I assume your markup will be something like this:
<div class="container">
<div class="col">
Col
</div>
<!-- Other Columns Go Here -->
</div>
Working Fiddle
As everyone already stated Flexbox is much suited for this, However (if i'm not missing anything)
A combination of the following properties should do the trick
grid-auto-flow: column;
grid-auto-columns: 25%; // assumes 4 columns
justify-content: center;
document.querySelectorAll('input')[0].onclick = () => { document.querySelector('[container]').append(document.createElement('div'))}
document.querySelectorAll('input')[1].onclick = () => {document.querySelector('[container]').innerHTML = '<div></div>';}
body * {
padding: 10px;
border: 1px solid;
}
[container] {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 25%;
justify-content: center;
}
[container]>div {
height: 50px;
background: orange;
}
<input type="button" value="Add Column" />
<input type="button" value="reset" />
<div container>
<div></div>
</div>

Can I get content to appear in the middle column of a CSS Grid layout with only one div?

If I have a 3 column grid and I want the content to appear in the 2 column: am I understanding correctly that the content HAS to go in the 2nd column in the HTML, and I have to create an empty div in the HTML?
In the grid below I want the title to appear in the middle column so I've created an empty div before this.
There's no way of getting the title to appear in the middle one of the 3 columns whilst only using one div is there?
** Note I haven't included a div for the 3rd column because I don't need to.
Codepen: https://codepen.io/emilychews/pen/rEoKPg
Code snippet also included below.
body {
margin: 0;
padding: 0;
display: flex;
height: 100vh;
width: 100%;
justify-content: center;
align-items: center;
}
.row {
width: 50%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
}
.grid {
background: #f1f1f1;
padding: 1rem;
}
<div class="row">
<div class="grid grid-item-1"></div>
<div class="grid grid-item-2">The Title</div>
</div>
You don't have to create an empty div if you use grid-column-start, but you will need to specify the column number.
<div class="row">
<div class="grid grid-item-2">The Title</div>
</div>
body {
margin: 0;
padding: 0;
display: flex;
height: 100vh;
width: 100%;
justify-content: center;
align-items: center;
}
.row {
width: 50%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
}
.grid {
background: #f1f1f1;
padding: 1rem;
}
.grid-item-2 {
grid-column-start: 2;
}
Yes, you can. Remove the first div then add this to your css code:
.grid-item-2 {
grid-column-start: 2;
}
Check this article on CSS Tricks with a quick cheatsheet on CSS Grids: A Complete Guide to Grid | CSS Tricks
The MDN reference is very good also: CSS Grid Layout | MDN

Centering an image in CSS grid

I am trying to fix my grid layout.
Firstly, the image should be at the center of .container. I tried using align-self: center;, but that did not work.
The headers and paragraph are really messed up. Before this, the paragraph was pushing down the image so I thought if I gave both of them (and the headers) custom grid-row value, they'd be fixed, but instead, I have all of these elements overlap each other. I need them to be ordered correctly. The paragraph under H3 and H3 below H1.
.container {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 100%;
}
.container img {
grid-column: 1 / 2;
grid-row: 1;
}
.container h1,
h3 {
grid-column: 3;
grid-row: 1;
line-height: 0.35;
}
.container p {
grid-column: 3;
grid-row: 1;
width: 350px;
}
<div class="container">
<h1>-[IFwsI]- Jail</h1>
<h3>More than 40 000 registered players</h3>
<p>The most active, and one of the most successful servers. Jail has a set of rules players need to follow and enjoy the roleplay of inmates vs. CTs scenario</p>
<img src="https://i.imgur.com/epqMIJv.jpg" height="418" width="740" />
</div>
Create columns for the text and image to make it easier to manage the columns.
Take a look at grid-template-columns you can control the widths of each column in myriad ways. I have just set them to 33% width;
https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
justify-content: center puts the columns in the horizontal center.
align-items: center aligns the items vertically.
To change the order I've created a new class .column--left with grid-row: 1 to put move it to the first column.
.container {
display: grid;
grid-template-columns: 33% 33%;
justify-content: center;
align-items: center;
grid-gap: 10px;
height: 100vh;
}
.column.column--left {
grid-row: 1;
}
img {
max-width: 100%;
height: auto;
}
<div class="container">
<div class="column">
<h1>-[IFwsI]- Jail</h1>
<h3>More than 40 000 registered players</h3>
<p>The most active, and one of the most successful servers. Jail has a set of rules players need to follow and enjoy the roleplay of inmates vs. CTs scenario</p>
</div>
<div class="column column--left">
<img src="https://i.imgur.com/epqMIJv.jpg" height="418" width="740" />
</div>
</div>
...but instead, I have all of these elements overlap each other.
In your code, you are specifically telling them to overlap each other.
.container h1, h3 {
grid-column: 3;
grid-row: 1;
line-height: 0.35;
}
.container p {
grid-column: 3;
grid-row: 1;
width: 350px;
}
The h1, h3 and p are all placed in column 3, row 1. Why wouldn't they overlap?
Here's another approach that may be useful to you:
.container {
display: grid;
height: 100vh;
align-items: center;
grid-column-gap: 20px;
grid-template-columns: 1fr 2fr 2fr 1fr;
grid-template-areas: " . pic header1 . "
" . pic header3 . "
" . pic ptext . "
" . pic ptext . "
}
.container > h1 { grid-area: header1; }
.container > h3 { grid-area: header3; }
.container > p { grid-area: ptext; }
.container > div { grid-area: pic; }
.container img { width: 100%; object-fit: contain; }
* { margin: 0; }
<div class="container">
<h1>-[IFwsI]- Jail</h1>
<h3>More than 40 000 registered players</h3>
<p>The most active, and one of the most successful servers. Jail has a set of rules players need to follow and enjoy the roleplay of inmates vs. CTs scenario</p>
<div>
<img src="https://i.imgur.com/epqMIJv.jpg" height="418" width="740" />
</div>
</div>
jsFiddle demo
Here's a visualization of the code using Firefox's grid overlay tool.

How to make CSS Grid items take up remaining space?

I have a card built with CSS Grid layout. There might be an image to the left, some text to the right top and maybe a button or a link at the right bottom.
In the code below, how can I make the green area take up as much space as possible and at the same time make the blue area take up as little space as possible?
The green should push the blue area down as far as possible.
https://jsfiddle.net/9nxpvs5m/
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"one two"
"one three"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.two {
background: green;
grid-area: two;
}
.three {
background: blue;
grid-area: three;
}
<div class="grid">
<div class="one">
One
</div>
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
Adding grid-template-rows: 1fr min-content; to your .grid will get you exactly what you're after :).
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr min-content;
grid-template-areas:
"one two"
"one three"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.two {
background: green;
grid-area: two;
}
.three {
background: blue;
grid-area: three;
}
<div class="grid">
<div class="one">
One
</div>
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
Jens edits: For better browser support this can be used instead: grid-template-rows: 1fr auto;, at least in this exact case.
A grid is a series of intersecting rows and columns.
You want the two items in the second column to automatically adjust their row height based on their content height.
That's not how a grid works. Such changes to the row height in the second column would also affect the first column.
If you must use CSS Grid, then what I would do is give the container, let's say, 12 rows, then have items span rows as necessary.
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: repeat(12, 15px);
}
.one {
grid-row: 1 / -1;
background: red;
}
.two {
grid-row: span 10;
background: lightgreen;
}
.three {
grid-row: span 2;
background: aqua;
}
.grid > div {
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
</div>
Otherwise, you can try a flexbox solution.
.grid {
display: flex;
flex-flow: column wrap;
height: 200px;
}
.one {
flex: 0 0 100%;
width: 30%;
background: red;
}
.two {
flex: 1 0 1px;
width: 70%;
background: lightgreen;
}
.three {
background: aqua;
}
.grid>div {
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
</div>
When using grid, and you have grid template area used, and by chance you gave a particular area a width, you are left with a space grid does automatically.
In this situation, let grid-template-columns be either min-content or max-content, so that it adjusts its position automatically.
A possible approach might be grouping two and three together, and using flexbox:
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas: "one two"
}
.one {
background: red;
grid-area: one;
padding: 50px 0;
}
.wrap {
grid-area: two;
display: flex;
flex-direction: column;
}
.two {
background: green;
flex: 1;
}
.three {
background: blue;
}
<div class="grid">
<div class="one">
One
</div>
<div class="wrap">
<div class="two">
Two
</div>
<div class="three">
Three
</div>
</div>
</div>
Definitely not the most elegant solution and probably not best practice, but you could always add more lines of
"one two"
before the part where you have
"one three"
so it ends up looking like
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"one two"
"one two"
"one two"
"one three"
}
Again, pretty sure this is just a work around and there's better solutions out there... But this does work, to be fair.
Just use width: 100% and height: 100% in the CSS class of the item you want to fill the grid. Join a max-width property and a max-height property if you don't want a grid item inside a grid container to grow more than some size.