Align columns in CSS Grid - css

Previously I used Flexbox to create a 12 column grid system. When implementing a similar system using CSS Grid, there was a problem with column alignment.
For example: there is a system of 12 columns and two elements that occupy 3 columns, which go one after another, when using Flexbox you can specify the justify-content: space-between to separate these columns on both sides of the container.
How to achieve the same behavior when using CSS Grid provided that the width of the columns is specified in fr and the number of columns occupied by the element is specified using the grid-column: span $number property?
It is not desirable to specify manually which column the element starts with in order to achieve an offset in this way (for example: starts with column 9 and ends with column 12).
I have attached a basic reproducible example.
Codesanbox

With how grid works, you will have to specify where each box starts, at least for your problem.
If you really don't want to specify the starting column, you can just create a grid with:
grid-template-columns: 3fr 6fr 3fr which is 3 + 6 + 3 = 12 columns
In your HTML, just add a third filler div in between your two boxes, so it can occupy the 6fr section in the grid.
UPDATE:
.container {
width: 1000px;
margin: 0 auto;
}
.grid {
display: grid;
grid-template-columns: 3fr 6fr 3fr;
border: 1px solid teal;
}
.box {
color: #ffffff;
background: teal;
border-radius: 4px;
padding: 10px;
}
.col-3-start {
grid-column: span 3;
}
.col-3-end {
grid-column: -4 / span 3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
</head>
<body>
<div class="container">
<div class="grid">
<div class="box">Box 1</div>
<div class="filler"></div>
<div class="box">Box 2</div>
</div>
</div>
</body>
</html>

Related

Whats the reason for flex-wrap not to work?

I've looked at other questions on this website and none of them were similar to my problem, applying flex-direction:row; didnt help, applying all kinds of width's (min-width, max-width) didn't help as well.
Am I using wrong units for styling the items in container?
My goal is for the content to wrap in a new row.
HTML and CSS:
body {
margin: 0;
padding: 0;
background-color: #eeeeee;
}
h1, h5 {
padding: 10px;
margin: 0;
}
.pre-header {
text-align: center;
}
#header-content1-1 {
font-size: 1.15em;
margin: 0;
padding: 0;
}
hr {
margin-top: 20px;
margin-bottom: 3px;
}
.container {
display: flex;
background-color: cornflowerblue;
justify-content:space-between;
max-width: 80%;
margin: auto;
align-items: center;
height: 40vh;
flex-wrap: wrap;
}
.flex-item {
background-color: red;
line-height: 9vh;
width: 13%;
text-align:center;
flex-shrink: 3;
}
<!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">
<meta name="description" content="Find out who was Avicii!">
<link rel="stylesheet" href="style.css">
<title>David</title>
</head>
<body>
<header>
<div class="pre-header">
<h1 id="header-content1">Avicii - Tim Bergling</h1>
<h5 id="header-content1-1">Swedish DJ, remixer, record producer, musician, and songwriter</h5>
</div>
</header>
<main>
<hr>
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
</div>
</main>
<footer>
</footer>
</body>
</html>
One suggested way as mentioned in comments is having an appropriate width (in your case 22%) so it sums up to 100% some items show up in the next row. One can add margin (like margin: 0% 5%) too to add to the width.
There is one way to do that manually, but you will have to add something similar to breaks in your HTML code. Here is a solution inspired by this.
<div class="container">
<div class="flex-item">E</div>
<div class="flex-item">R</div>
<div class="flex-item">I</div>
<div class="flex-item">N</div>
<div class="flex-item">N</div>
<div class="flex-item break"></div>
<div class="flex-item f2">N</div>
<div class="flex-item f2">N</div>
</div>
.break {
flex-basis: 100%;
height: 0;
}
This uses flex-basis.
Have a look at this codepen for demo.
There is also the option to have add one more level of divs inside your container divs as parents to your flex-item. But overall I would suggest to use the dynamic width and not use these methods as they will only add complexity when your number of boxes are dynamic and will probably require some Js too.

How do I remove this white space while using CSS grid layout?

I am just learning how to use CSS grid layout from a crash course. While tinkering around with the grid-template-columns property, a white space has appeared under one of my cat images that I cannot get rid of.
This is my HTML:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.gallery {
display: grid;
grid-template-columns: 200px 200px 1fr;
}
.gallery img {
width: 100%;
}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<main>
<div class="gallery">
<img src="https://placeimg.com/640/480/animals" alt='' />
<img src="https://placeimg.com/640/480/arch" alt='' />
<img src="https://placeimg.com/640/480/nature" alt='' />
<img src="https://placeimg.com/640/480/people" alt='' />
<img src="https://placeimg.com/640/480/tech" alt='' />
</div>
</main>
Can someone help me resolve this?
Make the third image into 3 rows:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.gallery {
display: grid;
grid-template-columns: 200px 200px 1fr;
}
.gallery img {
width: 100%;
}
.gallery img:nth-child(3) {
grid-row: span 3;
}
<div class="gallery">
<img src="https://placeimg.com/640/480/animals" >
<img src="https://placeimg.com/640/480/arch" >
<img src="https://placeimg.com/640/480/nature" >
<img src="https://placeimg.com/640/480/people" >
<img src="https://placeimg.com/640/480/tech" >
</div>
This depends on what you want to have happen instead.
grid-template-columns specifies your grid columns. By setting it to: 200px 200px 1fr you're basically instructing the browser:
There should be 3 columns for my content.
Set the first and second columns to 200px wide
Use flex for the third column.
So instead, one option would be to make use of a repeat function. The following will make 3 equal columns:
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
img {
width: 100%;
}
Also, FWIW keep an eye on both your HTML and CSS. In the HTML, you should have closing tag for <main></main>. And if you're working with vanilla CSS (not Sass or Less), your declarations for img should be outside those for .gallery.

change order of display via css

I have a piece of bootstrap based code:
<div class="alert alert-primary" style="padding:0.6rem;margin-bottom:0.5rem">
<div style="display:inline-block;font-weight:bold;width:100px;vertical-align:top">Name</div>
<div style="display:inline-block;vertical-align:top">Summary, which is long and will wrap on small screen</div>
<div style="display:inline-block;float:right;vertical-align:top">Date</div>
</div>
which looks like this on laptop screen:
Name Summary... Date
While on phone screen it looks like:
Name
Summary...
Date
i.e. Date is on the 3rd row, and pops out of the background of the "alert" box.
I want it to be this on phone screen:
Name Date
Summary, ....
... ...
i.e. on large screen: name, summary, date, on small screen, name, date, summary.
Is that possible
please try this code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#media(max-width: 767px){
.alert.alert-primary{
display: flex;
flex-direction: column;
}
.alert div:nth-child(1){
order: 1;
display: block !important;
}
.alert div:nth-child(2){
order: 3;
display: block !important;
}
.alert div:nth-child(3){
order: 2;
display: block !important;
}
}
</style>
</head>
<body>
<div class="alert alert-primary" style="padding:0.6rem;margin-bottom:0.5rem">
<div style="display:inline-block;font-weight:bold;width:100px;vertical-align:top">Name</div>
<div style="display:inline-block;vertical-align:top">Summary, which is long and will wrap on small screen</div>
<div style="display:inline-block;float:right;vertical-align:top">Date</div>
</div>
</body>
</html>

An arbibrary hight on header + rest of the height on container [duplicate]

This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Fill remaining vertical space with CSS using display:flex
(6 answers)
Closed 4 years ago.
I want to achieve the following behavior like in the image
So, I have a header with an arbitrary height and I want the container to fill the rest of the space. I have the following code:
<body>
<div class="header">
My header<br> Arbitrary height (ex: 123px)
</div>
<div class="container">
Container <br> Height = rest of the viewport
</div>
</body>
Note: I don't want to use .container{ height: calc(100% - 123px) } because the in the future 123px may change, so I don't want to modify in two places.
You can use flexbox for this:
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.header {
height: 123px; /* whatever height you want */
background:green;
}
.container {
flex-grow: 1;
background:beige;
}
<div class="header"></div>
<div class="container"></div>
See following example:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
html,
body {
height: 100%;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
padding:0;
margin:0;
}
.container {
flex: 1;
overflow:auto;
padding:10px;
}
.header {
background-color:green;
}
</style>
</head>
<body>
<div class="header">
<p>My header<br> Arbitrary height (ex: 123px)</p>
<p>My header<br> Arbitrary height (ex: 123px)</p>
</div>
<div class="container">
Container <br> Height = rest of the viewport
</div>
</body>
</html>

Make a grid column span the entire row

Imagine we have 2 CSS Grid containers with dynamic columns count based on width.
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
The grid works perfectly, but what if we need to have another grid to have the 1st column to be same as in another grid with the code shown above, but it's another column to span through more cells - depending on how many cells are in the current row.
To better understand issue, there are images:
On more narrow wrapper:
We would need to apply something like grid-column: span ALL (if something like that exists), with meaning that ALL = till the end of current row.
What is really important is that "First" column should always align with "1" column.
Code to run example is here:
.grid div {
/* Not important fancy styles */
height: 40px;
text-align: center;
padding-top: 20px;
}
.grid {
width: 350px;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
background-color: silver;
}
.grid-second {
background-color: red;
}
.grid-another {
background-color: purple;
border: 1px solid gray;
}
<div class="grid">
<div class="grid-first">
First
</div>
<div class="grid-second">
Second (Want till end)
</div>
</div>
<!-- Another same grid -->
<div class="grid">
<div class="grid-another">
1
</div>
<div class="grid-another">
2
</div>
<div class="grid-another">
3
</div>
<div class="grid-another">
4
</div>
</div>
PS. please do not post solutions using media query. I am interested in any (even little hacky solution), which will work without usage of media queries.
Here are two interesting sections in the CSS Grid specification:
7.1. The Explicit Grid
Numeric indexes in the grid-placement properties count from the edges
of the explicit grid. Positive indexes count from the start side,
while negative indexes count from the end side.
also here...
8.3. Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties
If a negative integer is given, it instead counts in reverse, starting
from the end edge of the explicit grid.
In other words, when dealing with an explicit grid, which means a grid defined by these properties:
grid-template-rows
grid-template-columns
grid-template-areas
grid (which is the shorthand for the three properties above, among others)
... you can make a grid area span all columns by setting this rule:
grid-column: 1 / -1;
That tells the grid area to span from the first column line to the last column line, which I believe meets your stated objective:
"We would need to apply something like grid-column: span ALL (if something like that exists), with meaning that ALL = till the end of current row."
jsFiddle demo
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
background-color: silver;
}
.grid-second {
grid-column: 2 / -1;
background-color: red;
}
/* Not important fancy styles */
.grid div {
height: 40px;
text-align: center;
padding-top: 20px;
}
.grid-another {
background-color: purple;
border: 1px solid gray;
}
<div class="grid">
<div class="grid-first">First</div>
<div class="grid-second">Second (Want till end)</div>
</div>
<!-- Another same grid -->
<div class="grid">
<div class="grid-another">1</div>
<div class="grid-another">2</div>
<div class="grid-another">3</div>
<div class="grid-another">4</div>
<div class="grid-another">1</div>
<div class="grid-another">2</div>
<div class="grid-another">3</div>
<div class="grid-another">4</div>
<div class="grid-another">1</div>
<div class="grid-another">2</div>
<div class="grid-another">3</div>
<div class="grid-another">4</div>
</div>

Resources