Align rows of the css grid (diplay:grid) to the top? [duplicate] - html

This question already has answers here:
What is the difference between align-items vs. align-content in Grid Layout?
(1 answer)
CSS Grid - Auto height rows, sizing to content
(3 answers)
Closed 1 year ago.
I have a css grid (display:grid) and rows with fixed height as well.
Can I align the rows to the top of the grid instead of distributing them vertically?
.grid {
height: 180px;
display: grid;
grid-template-columns: 1fr;
border: solid 1px red;
align-content: top;
align-items: top;
}
.row {
grid-column: 1 / -1;
height: 20px;
background: silver;
border: dashed 1px blue;
}
<div class="grid">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
</div>
I want to achieve this:

Just add align-content: flex-start
.grid {
height: 180px;
display: grid;
grid-template-columns: 1fr;
align-content: flex-start;
border: solid 1px red;
}
.row {
grid-column: 1 / -1;
height: 20px;
background: silver;
border: dashed 1px blue;
}
<div class="grid">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
</div>

You can achieve this with grid-template-rows which defines dimensions for the rows and prevents them of getting a third of the container height (180px).
Working example:
.grid {
height: 180px;
display: grid;
grid-template-rows: 20px 20px 20px;
border: solid 1px red;
}
.row {
height: 20px;
background: silver;
border: dashed 1px blue;
}
<div class="grid">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
</div>

You can set the grid-auto-rows to the same height as your rows to align them at the top:
grid-auto-rows
The grid-auto-rows CSS property specifies the size of an implicitly-created grid row track or pattern of tracks.
.grid {
height: 180px;
display: grid;
grid-template-columns: 1fr;
border: solid 1px red;
grid-auto-rows: 20px;
}
.row {
grid-column: 1 / -1;
height: 20px;
background: silver;
border: dashed 1px blue;
}
<div class="grid">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
</div>

Change the grid height to auto .grid{height:auto;}
.grid {
height:auto;
display: grid;
grid-template-columns: 1fr;
border: solid 1px red;
align-content: top;
align-items: top;
}
.row {
grid-column: 1 / -1;
height: 20px;
background: silver;
border: dashed 1px blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="grid">
<div class="row">row 1</div>
<div class="row">row 2</div>
<div class="row">row 3</div>
</div>
</body>
</html>

Related

Div under grid in flexbox

I have a layout that is a sidebar and a grid both wrapped in a flexbox. I'd like to put a div underneath the grid so it can have prev/next buttons, like in this image, but I can't figure out how to do that. The grid resizes itself with the window so the grid can take as many rows as necessary and then the div should go below that, and be as wide as the grid.
This is what I have, but the div is on the right of the grid:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Boardgame Database</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
aside {
background-color: red;
flex: 1;
min-width: 250px;
}
.grid-container {
flex: 4;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.grid-item {
border: 1px solid black;
padding: 20px;
font-size: 24px;
text-align: center;
overflow: hidden;
}
#flex-container {
display: flex;
flex-direction: row;
min-height: 100vh;
}
</style>
</head>
<body>
<div id="flex-container">
<aside class="sidebar">
</aside>
<section class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
<div class="grid-item">10</div>
<div class="grid-item">11</div>
<div class="grid-item">12</div>
<div class="grid-item">13</div>
<div class="grid-item">14</div>
<div class="grid-item">15</div>
<div class="grid-item">16</div>
<div class="grid-item">17</div>
<div class="grid-item">18</div>
</section>
<div id="page-buttons">
prev
next
</div>
</div>
Checkout the following Code.
#main{
display :flex;
}
#sidebar{
width:70px;
height: 300px;
border: solid black 1px;
}
#grid-area{
width:200px;
height: 300px;
border: solid black 1px;
display: block;
}
#grid{
width:200px;
height: 250px;
border: solid black 1px;
display: block;
}
<div id="main">
<div id="sidebar"></div>
<div id="grid-area">
<div id="grid"></div>
<div id="button">next / prev</div>
</div>
</div>
You should use nested flex containers. Section and bottom div should be wrapped inside another flex container with flex direction to column.
So outer flex will make sidebar & inner flex container to be side by side.
Or just use a normal div container instead of flex.
here is another example only with grid keeping the pre/next button at the bottom of the viewport:
body {
margin: 0;
}
#grid-container {
display: grid;
height: 100vh;
grid-template-columns: minmax(250px, 1fr) 4fr;
grid-template-rows: 1fr auto;
}
aside {
background-color: red;
border: 1px solid;
margin: 0.25em;
grid-row: span 2;
grid-column: 1;
}
section,
#page-buttons {
grid-column: 2;
border: solid 1px;
margin: 0.25em;
}
section {
overflow: auto;
}
#page-buttons {
display: flex;
gap: 1em;
padding: 0.5em;
background: lightgray;
justify-content: center;
}
.grid-item {
border: 1px solid black;
padding: 20px;
font-size: 24px;
text-align: center;
overflow: hidden;
}
<div id="grid-container">
<aside class="sidebar">
</aside>
<section class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
<div class="grid-item">10</div>
<div class="grid-item">11</div>
<div class="grid-item">12</div>
<div class="grid-item">13</div>
<div class="grid-item">14</div>
<div class="grid-item">15</div>
<div class="grid-item">16</div>
<div class="grid-item">17</div>
<div class="grid-item">18</div>
</section>
<div id="page-buttons">
prev
next
</div>
</div>

CSS Grid layout with equal width sections columns and sections with borders/margins

I am looking to have a grid layout (3 columns) of repeating sections. I want the sections to have border and margins as well as have equal width columns throughout all sections. I have gotten most of the way there but am battling between no border/margin using display: contents; or unequal widths. Is what I am asking for css subgrid? (poorly supported), is there another way or am I left to apply border/margin to children?
.grid {
display: grid;
grid-template-columns: auto auto 1fr;
padding: 10px;
border: 2px solid red;
}
.sectionWrap {
display: contents;
border: 3px solid purple;
margin: 6px;
}
.c1,
.c2,
.c3 {
border: 1px solid blue;
}
<div class="grid">
<div class="sectionWrap">
<div class="c1">
shorter text
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
<div class="sectionWrap">
<div class="c1">
longer text...............
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
</div>
<span> unfortunately missing my border and margin using display: contents.
Margin can be replaced with gap and border with individual border on your elements:
.grid {
display: grid;
grid-template-columns: auto auto 1fr;
row-gap:12px;
padding: 12px;
border: 2px solid red;
}
.sectionWrap {
display: contents;
}
.c1 {
border:3px solid purple;
border-right:1px solid blue;
}
.c2 {
border:3px solid purple;
border-right:1px solid blue;
border-left:1px solid blue;
}
.c3 {
border:3px solid purple;
border-left:1px solid blue;
}
<div class="grid">
<div class="sectionWrap">
<div class="c1">
shorter text
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
<div class="sectionWrap">
<div class="c1">
longer text...............
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
</div>
<span>
You can keep all of your columns the same width by changing grid-template-columns: auto auto 1fr; to grid-template-columns: 1fr 1fr 1fr; This is how your code looks with this change and I also removed the display: contents;
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
padding: 10px;
border: 2px solid red;
}
.sectionWrap {
border: 3px solid purple;
margin: 6px;
}
.c1,
.c2,
.c3 {
border: 1px solid blue;
}
<div class="grid">
<div class="sectionWrap">
<div class="c1">
shorter text
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
<div class="sectionWrap">
<div class="c1">
longer text...............
</div>
<div class="c2">
2
</div>
<div class="c3">
3
</div>
</div>
</div>
<span> unfortunately missing my border and margin using display: contents.

How the flex box item use the full width of its parent

.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
}
<div class="container">
<div class=item>Box 1</div>
<div class=item>Box 2</div>
<div class=item>Box 3</div>
<div class=item>Box 4</div>
<div class=item>Box 5</div>
</div>
My question, how can "Box 1", "Box 2", "Box 3" use the full width of the "container" class? and "Box 4" and "Box 5" will line up from below to the above box "Box 1" and "Box 2".
You have several ways to go about it; here are two ways:
Use flex-grow. If you add flex-grow: 1 to the item selector then the boxes on each row will take up the full width of the container. Note: With this solution you may want to make sure you have the same number of boxes per row, if you want these boxes to appear as a uniform grid. Otherwise the line with only one or two boxes will be stretched to fill the width of the container. So keep that in mind.
.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
flex-grow: 1;
}
Second option: Add margin: 0 auto; to the item selector, and they will fill the width by centering.
.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
margin: 0 auto;
}
This was actually kind of a brainteaser until I realized you need CSS grid instead of Flexbox :). There doesn't seem to exist a solution with Flexbox without adding "ghost divs", which isn't really a good option.
.container {
width: 400px;
border: 2px solid red;
display: grid;
grid-template-columns: 110px 110px 110px;
justify-content: space-between;
}
.item {
padding: 20px;
border: 1px solid blue;
}
<div class="container">
<div class=item>Box 1</div>
<div class=item>Box 2</div>
<div class=item>Box 3</div>
<div class=item>Box 4</div>
<div class=item>Box 5</div>
</div>

flexbox wrapping with items of varying size

Can I achieve this layout with flexbox with the below document structure?
I want the big <img> on the left with two smaller images on the right and wrapping.
This is what I did, with display: flex on gallery-container and flex-wrap.
.container {
height: 100%;
}
.container .gallery-container {
background-color: #f6f6f6;
display: flex;
flex-wrap: wrap;
width: 300px;
align-items: flex-start;
}
.container .gallery-container .gallery-big-image {
display: block;
width: 200px;
height: 200px;
background: lavender;
}
.container .gallery-container .gallery-small-img {
display: block;
width: 100px;
height: 100px;
background-color: purple;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
</div>
</div>
(codepen)
The layout is clunky and inefficient with flexbox, for reasons explained here: CSS-only masonry layout
However, the layout is relatively simple and easy with CSS Grid.
No changes to HTML.
.gallery-container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-auto-rows: 100px;
width: 300px;
background-color: #f6f6f6;
}
.gallery-big-image {
grid-column: span 2;
grid-row: span 2;
background: lavender;
}
.gallery-small-img {
background-color: purple;
color: white;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small 1</div>
<div class="gallery-small-img">small 2</div>
<div class="gallery-small-img">small 3</div>
<div class="gallery-small-img">small 4</div>
<div class="gallery-small-img">small 5</div>
<div class="gallery-small-img">small 6 (continues wrapping)</div>
<div class="gallery-small-img">small 7 (continues wrapping)</div>
</div>
</div>
How about using grid layout instead?
.container {
height: 100%;
}
.gallery-container {
background-color: #f6f6f6;
width: 300px;
height: 100px;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.gallery-img {
background: purple;
width: 100px;
height: 100px;
}
.gallery-img-large {
background: lavender;
width: 200px;
height: 200px;
grid-column-start: 0;
grid-column-end: span 2;
grid-row-start: 0;
grid-row-end: span 2;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-img-large">big</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
</div>
</div>

Grid items overflow container with max width

I've a css grid and multiple items inside it. Right know it's covering the whole width possible. What I want is to limit the width of the container (such as making it only 700px) instead of covering the whole width.
I've tried to use width or max-width properties for the container but none of them is successful. The content inside the container overflows. I should be missing something but do not know what.
Here is the codepen:
https://codepen.io/sercanyilmaz/full/YaRmPN/
#import url('https://fonts.googleapis.com/css?family=Muli');
#import url('https://fonts.googleapis.com/icon?family=Material+Icons');
.wrapper {
display: grid;
grid-template-columns: repeat(350, 1fr);
grid-template-rows: repeat(33, 1fr);
grid-gap: 4px;
grid-row-gap: 5px;
background-color: #a5adb0;
border-radius: 5px;
color: #ddd;
padding: 15px;
font-family: 'Muli';
}
.func {
grid-column: span 25;
grid-row: span 3;
border-radius: 5px;
background: #20252A;
display: grid;
align-items: center;
justify-items: center;
border-bottom: 5px solid #000;
cursor: pointer;
}
.num {
grid-column: span 24;
grid-row: span 6;
border-radius: 5px;
background: #20252A;
display: grid;
align-items: center;
justify-items: center;
border-bottom: 5px solid #000;
cursor: pointer;
}
.back {
grid-column: span 38;
}
.letters {
grid-column: span 24;
grid-row: span 6;
border-radius: 5px;
background: #20252A;
display: grid;
align-items: center;
justify-items: center;
border-bottom: 5px solid #000;
cursor: pointer;
}
.tab {
grid-column: span 38;
}
.caps {
grid-column: span 42;
}
.enter {
grid-column: span 44;
}
.left-shift {
grid-column: span 50;
}
.right-shift {
grid-column: span 60;
}
.fn {
grid-column: span 22;
}
.left-command,
.right-command {
grid-column: span 28;
}
.space {
grid-column: span 120;
}
.up {
grid-row: span 3;
}
.down {
grid-row: span 3;
border-bottom: 0px;
border-top: 5px solid #000;
;
}
.left,
.right {
grid-column: span 28;
}
.func:active,
.num:active,
.letters:active {
border-bottom: 5px inset #20252A;
background: #111;
}
.down:active {
border-bottom: 0px !important;
border-top: 5px inset #20252A;
background: #111;
}
<div class="wrapper">
<!-- first row -->
<div class="func">esc</div>
<div class="func">F1</div>
<div class="func">F2</div>
<div class="func">F3</div>
<div class="func">F4</div>
<div class="func">F5</div>
<div class="func">F6</div>
<div class="func">F7</div>
<div class="func">F8</div>
<div class="func">F9</div>
<div class="func">F10</div>
<div class="func">F11</div>
<div class="func">F12</div>
<div class="func">F13</div>
<!-- second row -->
<div class="num">~<br/>`</div>
<div class="num">!<br/>1</div>
<div class="num">#<br/>2</div>
<div class="num">#<br/>3</div>
<div class="num">$<br/>4</div>
<div class="num">%<br/>5</div>
<div class="num">^<br/>6</div>
<div class="num">&<br/>7</div>
<div class="num">*<br/>8</div>
<div class="num">(<br/>9</div>
<div class="num">)<br/>0</div>
<div class="num">-<br/>_</div>
<div class="num">+<br/>=</div>
<div class="num back">delete</div>
<!-- third row -->
<div class="letters tab"><i class="material-icons"></i></div>
<div class="letters">Q</div>
<div class="letters">W</div>
<div class="letters">E</div>
<div class="letters">R</div>
<div class="letters">T</div>
<div class="letters">Y</div>
<div class="letters">U</div>
<div class="letters">I</div>
<div class="letters">O</div>
<div class="letters">P</div>
<div class="letters">{<br/>[</div>
<div class="letters">}<br/>]</div>
<div class="letters">|<br/>/</div>
<!-- fourth row -->
<div class="letters caps">caps lock</div>
<div class="letters">A</div>
<div class="letters">S</div>
<div class="letters">D</div>
<div class="letters">F</div>
<div class="letters">G</div>
<div class="letters">H</div>
<div class="letters">J</div>
<div class="letters">K</div>
<div class="letters">L</div>
<div class="letters">:<br/>;</div>
<div class="letters">"<br/>'</div>
<div class="letters enter">enter<br/>return</div>
<!-- fifth row -->
<div class="letters left-shift">shift</div>
<div class="letters">Z</div>
<div class="letters">X</div>
<div class="letters">C</div>
<div class="letters">V</div>
<div class="letters">B</div>
<div class="letters">N</div>
<div class="letters">M</div>
<div class="letters">
<<br/>,</div>
<div class="letters">><br/>.</div>
<div class="letters">?<br/>\</div>
<div class="letters right-shift">shift</div>
<!-- sixth row -->
<div class="letters fn">fn</div>
<div class="letters">control</div>
<div class="letters">option</div>
<div class="letters left-command">⌘<br/>command</div>
<div class="letters space"></div>
<div class="letters right-command">⌘<br/>command</div>
<div class="letters">option</div>
<div class="letters left">←</div>
<div class="letters up">↑</div>
<div class="letters right">→</div>
<div class="letters down">↓</div>
</div>
The problem is the grid-column-gap you have set on the grid container.
.wrapper {
display: grid;
grid-template-columns: repeat(350, 1fr);
grid-template-rows: repeat(33, 1fr);
grid-gap: 4px; <----- PROBLEM HERE
grid-row-gap: 5px;
background-color: #a5adb0;
border-radius: 5px;
color: #ddd;
padding: 15px;
font-family: 'Muli';
}
When you set grid-gap: 4px, that is shorthand for:
grid-row-gap: 4px
grid-column-gap: 4px
(Incidentally, the grid-row-gap set in the shorthand is overridden with your next line of code.)
Now look at how many columns you have set:
grid-template-columns: repeat(350, 1fr)
Now multiply 350 * 4px. The minimum possible width of a grid row is 1400px.
For an illustration, set the container's width to 1400px and remove the padding: 15px. The grid items begin to overflow at 1399px.
If you disable grid-gap: 4px you'll see that your layout scales nicely without any overflow.
Depending on how you want to space the keys, you'll have to test different units on the column gaps, such as straight percentages (%) or viewport percentages (vh, vw, vmin, vmax, etc).
Or consider using less (wider) columns.