CSS Grid How to get grid cells into a new row responsive? - css

I'm trying to make my page responsive. At a certain point my text is overflowing into another grid cell cause there is not enough space. How can I put these cells into a "new" row so the text has space and my other cells are fully visible?
Layout
Do I need to add another row into my parent-grid? What is the easiest way to fix this? Best case would be almost no media queries.
Thanks.

Here's an example by 'adding' another row below the image and text. I suspect you probably don't need the fifth box and it can easily be removed from the code. This is not the responsive part (as we presume you already have that built-in elsewhere in your CSS. Your actual setup may be a 'page grid' versus this example (grid-container), so posting some of your code would help us to visualize a better solution.
.grid-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, auto);
background-color: #2196F3;
column-gap: 5px;
row-gap: 5px;
padding: 5px;
font-family: arial, san-serif;
color: #000;
}
.grid-item {
/*--background-color: rgba(255, 255, 255, 0.5); alternative color for all sections--*/
border: 2px solid rgba(0, 0, 0, 0.5);
padding: 20px;
font-size: 1.5em;
text-align: left;
}
.item1 {
grid-column: 1 / span 1;
background-color: lime;
}
.item2 {
grid-column: 2 / span 2;
background-color: yellow;
}
.item3 {
grid-column: 1 / 2;
background-color: blue;
}
.item4 {
grid-column: 2 / 2;
background-color: orange;
}
.item5 {
grid-column: 3 / 3;
background-color: red;
}
<div class="grid-container">
<div class="grid-item item1">1 image here</div>
<div class="grid-item item2">2 lots of text here <br>more text <br>more text <br>more text </div>
<div class="grid-item item3">3 link</div>
<div class="grid-item item4">4 link</div>
<div class="grid-item item5">5 link</div>
</div>

Related

CSS Grid: column-placed item going to next row

I'm trying to achieve a grid showing position, name, evolution and score of users.
This list is dynamic, meaning I don't know how many rows I'm gonna have at the end.
Another constraint is that I can't change the order of elements in HTML.
As you can see in the snippet below, when I place items by column number, .name goes to the next row instead of staying on the current one, and I don't know why...
body {
background-color: darkslategrey;
color: white;
}
.container {
display: grid;
grid-template-columns: repeat(3, auto);
gap: 10px;
text-align: center;
}
.name,
.evolution,
.score {
border-top: 1px solid white;
border-bottom: 1px solid white;
}
.position {
grid-column: 1 / span 3;
}
.name {
grid-column: 1;
}
.evolution {
grid-column: 2;
}
.score {
grid-column: 3;
}
<div class="container">
<div class="position">1st</div>
<div class="evolution">+2</div>
<div class="score">85pts</div>
<div class="name">Jack</div>
<div class="position">2nd</div>
<div class="evolution">+3</div>
<div class="score">82pts</div>
<div class="name">Kate</div>
<div class="position">3rd</div>
<div class="evolution">-2</div>
<div class="score">80pts</div>
<div class="name">Sawyer</div>
<!-- and many more, this list is dynamic -->
</div>
What am I missing here ?
The grid is filling in the order in which you have given it the HTML elements
But you'd like it to fill up any spare space if it can. CSS has the grid-auto-flow property which will make this happen. It'll spot the empty cell on row two and put Jack into it for example.
body {
background-color: darkslategrey;
color: white;
}
.container {
display: grid;
grid-template-columns: repeat(3, auto);
grid-auto-flow: dense;
gap: 10px;
text-align: center;
}
.name,
.evolution,
.score {
border-top: 1px solid white;
border-bottom: 1px solid white;
}
.position {
grid-column: 1 / span 3;
}
.name {
grid-column: 1;
}
.evolution {
grid-column: 2;
}
.score {
grid-column: 3;
}
<div class="container">
<div class="position">1st</div>
<div class="evolution">+2</div>
<div class="score">85pts</div>
<div class="name">Jack</div>
<div class="position">2nd</div>
<div class="evolution">+3</div>
<div class="score">82pts</div>
<div class="name">Kate</div>
<div class="position">3rd</div>
<div class="evolution">-2</div>
<div class="score">80pts</div>
<div class="name">Sawyer</div>
<!-- and many more, this list is dynamic -->
</div>

neither FLEX nor GRID can't do what's needed

I'm trying to solve a simple task but the solutions seem not be that simple.
Basically, I want many blocks with the same size to be aligned in center but I nee 1 block that is twice bigger than the others.
If I use FLEX - there are blank spaces around the big block.
If I use GRID - I can't align the blocks in the center.
Please help!
#all {
width: 100%;
border: 1px solid #ff0000;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 150px);
grid-template-rows: repeat(auto-fill, 150px);
}
#all div {
width: 150px; height: 150px;
border: 1px solid #ff0000;
}
#all .big {
width: 310px; height: 312px;
grid-column: 2/ 4;
grid-row: 2 / 4;
}
<html>
<head>
<style>
</style>
</head>
<body>
<div id=all>
<div></div>
<div></div>
<div class=big></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</body>
</html>
I need them to be aligned in the center
Here is an edited answer from W3Schools.
NOTE: there must be enough items to circle the one in the middle.
First, you need to add odd items in the grid.
Then, add odd columns to align them properly as you want.
Last, use grid-area to start any of the items from the 2nd row and column. then end it at the other corner according to the number of items in the grid.
and the good thing about this is that it's responsive and you can select any item to put it in the middle.
here is the code.
.grid-container {
display: grid;
grid-template-columns: auto auto auto ; /* odd column */
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.item5 {
grid-area: 2 / 2 / 4 / 3; /* start and end the selected item */
display: flex;
justify-content: center;
align-items: center;
}
<h1>The grid-column Property</h1>
<p>Use the <em>grid-column</em> property to specify where to place an item.</p>
<div class="grid-container">
<!-- add odd items in the grid -->
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
<div class="item9">9</div>
<div class="item10">10</div>
<div class="item11">11</div>
</div>

Make a border span across higher-level containers

I'd like to have a bottom border on my title that breaks the grid. There are 3 columns, left, middle, and right, and my title and content go in the middle. I'd like to have a bottom border extend all the way to the left side of the left column. Is there a better way to do this than what I came up with below? Does CSS grid provide a built-in mechanism for doing this sort of thing? I'd appreciate any suggestions.
.grid-container {
padding: 10px;
display: grid;
grid-template-columns: [start] 1fr [middle] 4fr [end] 1fr ;
grid-gap: 1rem;
background-color: #fff;
color: #444;
}
.start {
grid-column: start;
background-color: #ccc;
}
.middle {
grid-column: middle;
}
.title {
}
.title:after {
content: '';
display: block;
border-bottom: 1px solid red;
margin-left: calc(-25% - 1rem);
}
.end {
grid-column: end;
background-color: #ccc;
}
<div class="grid-container">
<div class="start">Start</div>
<div class="middle">
<h2 class="title">My Title</h2>
<div class="content">Some text lorem ipsum, whatever.</div>
</div>
<div class="end">End</div>
</div>
This is a modification of Michael_B's answer above. Seems to work the same but without the addition of markup to the original html.
.grid-container {
padding: 10px;
display: grid;
grid-template-columns: [start] 1fr [middle] 4fr [end] 1fr ;
grid-template-rows: repeat(100, 1px); /* new */
grid-column-gap: 1rem; /* adjusted; removed grid-row-gap */
background-color: #fff;
color: #444;
}
.start {
grid-column: start;
background-color: #ccc;
grid-row: 1 / -1; /* new */
}
.middle {
grid-column: middle;
grid-row: 1 / -1; /* new */
}
.end {
grid-column: end;
background-color: #ccc;
grid-row: 1 / -1; /* new */
}
.grid-container:after { /* new */
content: '';
background-color: red;
grid-row-start: 47;
grid-column: 1 / 3;
}
<div class="grid-container">
<div class="start">Start</div>
<div class="middle">
<h2 class="title">My Title</h2>
<div class="content">Some text lorem ipsum, whatever.</div>
</div>
<div class="end">End</div>
</div>
Your negative margin method seems to work. It's a bit clunky, but seems effective nonetheless.
You could also use absolute positioning to align that border under the title. The container would be the bounding box (i.e., position: relative). But that's also a bit clunky.
If you want a pure grid solution, that's also possible. The method I came up with is clean and effective. Some may consider it overkill for a simple border, but your need is somewhat unique, so this may be useful.
Here's the basic concept:
Divide your container into 100 tiny rows (1px).
Make your existing grid items span these rows from top to bottom.
Now you're back to your original layout, but with an upgrade under the hood.
You now have 100 places for a border line.
Create a new grid item (either DOM or pseudo-element).
Span the item across the row under your title.
VoilĂ ! :-)
.grid-container {
padding: 10px;
display: grid;
grid-template-columns: [start] 1fr [middle] 4fr [end] 1fr ;
grid-template-rows: repeat(100, 1px); /* new */
grid-column-gap: 1rem; /* adjusted; removed grid-row-gap */
background-color: #fff;
color: #444;
}
.start {
grid-column: start;
background-color: #ccc;
grid-row: 1 / -1; /* new */
}
.middle {
grid-column: middle;
grid-row: 1 / -1; /* new */
}
.end {
grid-column: end;
background-color: #ccc;
grid-row: 1 / -1; /* new */
}
.grid-container::after { /* new */
content: "";
background-color: red;
grid-row-start: 47;
grid-column: 1 / 3;
}
<div class="grid-container">
<div class="start">Start</div>
<div class="middle">
<h2 class="title">My Title</h2>
<div class="content">Some text lorem ipsum, whatever.</div>
</div>
<div class="end">End</div>
<div class="border"></div>
</div>
jsFiddle demo
Another method, based on the same idea as Micheael_B had, "you need more rows".
What you can do is split the middle part in 3 parts. Title, border, content.
You can give each their own grid-row in order.
See fiddle that only works in Firefox because instead of unwrapping the 3 tags I used the display property contents
https://jsfiddle.net/npddveag/2/
The display property contents is a magic way of making the wrapper div disappear without the actual markup disappearing.(and inherited styles will stil apply, so there is a bit more to it).
If you need it to work in other browsers you can just unwrap the 3 tags.

Setting different lengths for grid gaps in CSS Grid

I'm creating a layout using CSS Grids, and I want to have different space between each row.
I can create the layout fine by just using margin on each element, but this kind of obscures the simplicity of the code. Is there any grid tricks I can do achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
What I'm trying to achieve is a layout like this:
https://jsfiddle.net/8swzgk0b/1/
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
width 100%;
margin: 20px;
grid-column-gap: 40px;
/* grid-row-gap: 40px 60px; */
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
Is there any grid trick I can do to achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
With the grid-row-gap, grid-column-gap and grid-gap properties, you cannot apply different widths to different gaps. Like you noted, only one value can be used for each axis: One for row gaps and another for column gaps (spec).
You could use margins (or padding) to show extra space, but this doesn't actually change the width of the gap. It only expands the row.
In the example below (based on your code), grid-row-gap is set to 20px. Grid items have the margin-bottom variations you set. Notice how the grip-row-gap size never changes. All changes occur inside the row.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
grid-column-gap: 40px;
grid-row-gap: 20px;
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
If you want to apply different size gaps between rows, then consider using actual rows for the job:
Now the gaps between rows have their own unique heights.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: 80px 5px 80px 10px 80px 30px 80px 20px; /* adjusted */
grid-column-gap: 40px;
}
.wide {
grid-column: 1 / span 3;
background: #838383;
}
.row-2 {
grid-row-start: 3;
background: green;
}
.row-3 {
grid-row-start: 5;
background: blue;
}
.row-4 {
grid-row-start: 7;
background: red;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
you can't set different values for the column or row gaps, however, you can use css custom properties such as margin or display or you can create extra rows and columns and assign different values to them using them as gaps.

CSS Grids. Different gap between each grid

I am trying to apply different gap between each grid element, for example we are having the following code. 4 Grid lines, 3 Elements and a 10px width between each grid-box. How can i apply custom width between each grid-box? for example 20px between element1 and element2, and then 30px between element2 and element3?
Can i achieve that with the css grids?
Edit: Without using padding.
Edit2: Provided Pictre.
Click for picture preview
html, body {height: 100%; margin: 0; padding: 0;}
body {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-row: 1fr 1fr;
grid-column-gap: 10px;
grid-row-gap: 10px;
}
#element1 {
grid-column: 1/2;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
#element2 {
grid-column: 2/3;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
#element3 {
grid-column: 3/4;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
<div id="element1">element1</div>
<div id="element2">element2</div>
<div id="element3">element3</div>
Well the general approach that I like to use with css-grid is to make extra columns. Obviously use grid-column-gap and grid-row-gap if you have the same padding, but if not you can add token columns.
Why not padding/ margin?
You can totally use padding/ margin for this, but I like the extra column a bit better, since in css-grid you define the layout in the wrapper and this is where this belongs to semantically. You also do not have to apply it to every single item in those columns. (Also, do you apply it to the left or the right or both items?).
But this messes up my numbering
Yes, that is why you never use numbers to describe an area in css grid!
You can name your lines and with it your areas. Use this! You can use the grid-template-areas for this ore simply name it like this:
grid-template-columns: [left-start] auto [left-end right-start] auto [right-end];
Oh you want extra padding? Here you go:
grid-template-columns: [left-start] auto [left-end] 10px [right-start] auto [right-end];
Note that I am by no means a seasoned web developer (quite the opposite), but I think this approach might - generally - be the best one.
I don't see anything specific on Grid for your case, but you can easily achieve the desired result by adding padding.
HTML
<div id="grid">
<div id="element1">
<div class="content">element1</div>
</div>
<div id="element2">
<div class="content">element2</div>
</div>
<div id="element3">
<div class="content">element3</div>
</div>
</div>
CSS
#element1 {
padding-right: 5px;
}
#element2 {
padding-left: 5px;
padding-right: 10px;
}
#element3 {
padding-left: 10px;
}
.content {
height: 100%;
border: 1px solid #2e2e2e;
}
JsFiddle example:
https://jsfiddle.net/wkt39kk8/

Resources