Centering squares in CSS Grid - html

I am trying to create four evenly spaced squares displayed in a square pattern (two on top, two on bottom), and centered on the page, much like this:
I have tried to do this in a css grid but when the grid fr get too big the divs stay on the right side of the fr and space the two columns farther apart, regardless of the browser width, like this:
I'd like to shift the Idaho and Nevada divs to the right side of the fr so all four divs are the same distance apart.
Here is my code so far:
Thank you!
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 20px;
}
.idaho {
grid-column: 2/3;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.utah {
grid-column: 3/4;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.nevada {
grid-column: 2/3;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
.arizona {
grid-column: 3/4;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
<div class="grid">
<div class="idaho">
<h2>Idaho</h2>
</div>
<div class="utah">
<h2>Utah</h2>
</div>
<div class="nevada">
<h2>Nevada</h2>
</div>
<div class="arizona">
<h2>Arizona</h2>
</div>
</div>

grid-template-columns
Instead of this:
grid-template-columns: 1fr 1fr 1fr 1fr
Use this:
grid-template-columns: 1fr auto auto 1fr
.grid {
display: grid;
grid-template-columns: 1fr auto auto 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 20px;
}
.idaho {
grid-column: 2/3;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.utah {
grid-column: 3/4;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.nevada {
grid-column: 2/3;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
.arizona {
grid-column: 3/4;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
<div class="grid">
<div class="idaho">
<h2>Idaho</h2>
</div>
<div class="utah">
<h2>Utah</h2>
</div>
<div class="nevada">
<h2>Nevada</h2>
</div>
<div class="arizona">
<h2>Arizona</h2>
</div>
</div>
When you set the four columns to 1fr, you are distributing container space equally among all columns. As you widen the screen, the columns will expand in equal proportion, creating wider columns than the size of the squares.
When you set the inner columns to auto, they are sized to the content width. Then you can use 1fr on the outer columns to consume all free space from opposite directions, pinning the inner columns to the center at all times.
justify-self: end
You can also keep the original grid-template-columns and add justify-self: end to the left-side squares to get them to shift right inside the column.
.grid {
display: grid;
grid-template-columns: 1fr auto auto 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 20px;
}
.idaho {
grid-column: 2/3;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
justify-self: end; /* new */
}
.utah {
grid-column: 3/4;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.nevada {
grid-column: 2/3;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
justify-self: end; /* new */
}
.arizona {
grid-column: 3/4;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
<div class="grid">
<div class="idaho">
<h2>Idaho</h2>
</div>
<div class="utah">
<h2>Utah</h2>
</div>
<div class="nevada">
<h2>Nevada</h2>
</div>
<div class="arizona">
<h2>Arizona</h2>
</div>
</div>
For more about justify-self see:
The difference between justify-self, justify-items and justify-content in CSS Grid

use flexbox for this kind of thing. Makes it a lot easier.
.container{
display:flex;
justify-content:space-evenly;
height:100vh;
}
.left,.right{
display:flex;
flex-direction:column;
justify-content:space-evenly;
}
.box{
height:200px;
width:300px;
border:solid 1px black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example 2</title>
<link rel="stylesheet" type="text/css" href="styles/example2.css" />
</head>
<body>
<div class="container">
<div class='left'>
<div class="box">
<h2>Idaho</h2>
</div>
<div class="box">
<h2>Nevada</h2>
</div>
</div>
<div class='right'>
<div class="box">
<h2>Utah</h2>
</div>
<div class="box">
<h2>Arizona</h2>
</div>
</div>
</div>
</body>
</html>
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 20px;
}
.idaho {
grid-column: 2/3;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.utah {
grid-column: 3/4;
grid-row: 1/2;
height: 300px;
width: 300px;
background-color: gray;
}
.nevada {
grid-column: 2/3;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
.arizona {
grid-column: 3/4;
grid-row: 2/3;
height: 300px;
width: 300px;
background-color: gray;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example 2</title>
<link rel="stylesheet" type="text/css" href="styles/example2.css" />
</head>
<body>
<div class="grid">
<div class="idaho">
<h2>Idaho</h2>
</div>
<div class="utah">
<h2>Utah</h2>
</div>
<div class="nevada">
<h2>Nevada</h2>
</div>
<div class="arizona">
<h2>Arizona</h2>
</div>
</div>
</body>
</html>

Related

Unintended scrolling of a grid container

Even though my grid container is set to (100vh, 100vw) the contents of the grid still overflows.
The weird thing is that when I open the page, it has the scroll bars and scroll, but when I resize the window and put it back into fullscreen again(meaning the size of the screen is the same), the scroll bars go away!
I don't really know whats causing this, so any help would be appreciated.
* {
padding: 0;
margin: 0;
}
.wrapper {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-rows: 1fr 7.5fr 7.5fr 2fr 1fr;
/* overflow: hidden; */
}
.navbar {
background: pink;
grid-row: 1/2;
grid-column: 1/3;
}
.webcam {
background: green;
grid-column: 1/2;
grid-row: 2/3;
}
.chat {
background: blue;
grid-column: 1/2;
grid-row: 3/4;
}
.two-buttons {
background: brown;
grid-column: 1/2;
grid-row: 4/6;
}
.screen {
background: black;
grid-column: 2/3;
grid-row: 2/4;
}
.bunch-of-buttons {
background: red;
grid-column: 2/3;
grid-row: 4/5;
}
.chat-send-button {
background: yellow;
grid-column: 2/3;
grid-row: 5/6;
}
<!DOCTYPE html>
<html>
<head>
<title>Focus</title>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<div class="navbar">
asdf
</div>
<div class="webcam">
asdf
</div>
<div class="chat">
asdf
</div>
<div class="two-buttons">
asdf
</div>
<div class="screen">
asdf
</div>
<div class="bunch-of-buttons">
asdf
</div>
<div class="chat-send-button">
asdf
</div>
</div>
</body>
</html>
Edit: My monitor is 1280*1024.

Grid layout stretching height to fit content, but remaining other grid-cells height

I'm trying to make grid layout. This is code:
<div class="wrapper">
<div class="header">HEADER</div>
<div class="nav">NAV
</div>
<div class="aside-left">LEFT</div>
<div class="main">MAIN
<img src="a1.jpeg">
<img src="a1.jpeg">
<img src="a1.jpeg">
</div>
<div class="aside-right">RIGHT</div>
<div class="footer">FOOTER</div>
</div>
</body>
.wrapper{
height: 100%;
width: 100%;
background-color: ghostwhite;
display: grid;
grid-template-columns: repeat(12,1fr);
grid-template-rows: minmax(100px,auto);
grid-gap:5px;
}
.header{
grid-column: 1/13;
grid-row: 1/2;
}
.nav{
grid-column: 1/13;
grid-row: 2/3;
}
.aside-left{
grid-column: 1/3;
grid-row: 3/10;
}
.main{
grid-column: 3/11;
grid-row: 3/10;
}
.aside-right{
grid-column: 11/13;
grid-row: 3/10;
}
.footer{
grid-column: 1/13;
grid-row:10/12;
}
I want class main to stretch to fit it's content and it is working, but .nav and .footer doesn't take up their min height 100px, but they seem to take up auto height too, however header class works correctly, so any ideas? I want other elements to have at least 100px height
I figured out answer:
body, html{
background-color: ghostwhite;
height: auto;
}
.wrapper{
max-height: auto;
width: 100%;
background-color: ghostwhite;
display: grid;
grid-template-columns: repeat(4,1fr);
grid-auto-rows: minmax(100px,auto);
grid-gap:5px;
}
it seems 100% height was factoring out other elements' height, while increasing others'

How to change grid in css

I want to design a grid like the one in link https://imgur.com/a/yGdgMWZ. This is my code but it doesn't look alike. And can you show me a way to optimize this code cause it look too bad.
HTML link: https://codesandbox.io/s/thirsty-sea-eo3q3
.third-part{
height:80vh;
}
.third-part p{
text-align: center;
}
.London{
grid-area: box-1;
}
.Paris{
grid-area: box-2;
}
.Dubai{
grid-area: box-3;
}
.Amsterdam{
grid-area: box-4
}
.Athens{
grid-area: box-5;
}
.Newyork{
grid-area: box-6;
}
.Barcelona{
grid-area: box-7;
}
.grid{
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap:2em;
grid-template-areas:
"box-1 box-2 box-3 box-3"
"box-4 box-5 box-3 box-3"
"box-4 box-6 box-6 box-7";
}
.grid div{
background-color: #ddd;
}
Changed your css a bit. Run the code snippet i made the grids same as the image. It's hard to explain here how grid works, so i suggest you should check
[CSS Grid MDN] ](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids)
and give a look, you will understand how grids function.
.third-part{
height:80vh;
}
.third-part p{
text-align: center;
}
.London{
}
.Paris{
}
.Dubai{
grid-column: 3/5;
grid-row: 1/3;
}
.Amsterdam{
grid-row: 2/4;
}
.Athens{
}
.Newyork{
grid-column: 2/4;
}
.Barcelona{
}
.grid{
display: grid;
grid-template-columns: repeat(4,1fr);
grid-gap: 20px;
grid-auto-rows: 150px;
}
.grid div{
background-color: #ddd;
}
<div class="third-part">
<p>Popular Places</p>
<div class="grid">
<div class="London">London, United Kingdom</div>
<div class="Paris">Paris, France</div>
<div class="Dubai">Dubai, United Arab Emirates</div>
<div class="Amsterdam">Amsterdam, Netherlands</div>
<div class="Athens">Athens, Greece</div>
<div class="Newyork">New York, Ny</div>
<div class="Barcelona">Barcelona, Spain</div>
</div>

Nested CSS grid layout different behavior in Chrome and Firefox

I'm trying to use CSS grid layout to simulate some responsive behavior, specifically with:
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
My example https://codepen.io/elgs/pen/goNxeL works well in Chrome, however, it doesn't seem to work in Firefox. You will find it when you resize the browser horizontally.
Another example https://codepen.io/elgs/pen/YYoxOq works well in both Chrome and Firefox.
html,body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
I'm wondering whether I have done anything wrong or it's the browser's bug.
Firefox version: 58.0 (64-bit)
Chrome version: Version 64.0.3282.119 (Official Build) (64-bit)
This appears to be a bug in Firefox. But I'm not sure.
Here's what is clear:
The fact that you have nested grid containers matters.
Your second demo, which works in both Chrome and Firefox, has only one grid container.
The first demo, which only works in Chrome, has nested grid containers. If you eliminate that nesting, and use only one grid container, the layout works in both browsers.
So, as a possible cross-browser solution, minimize the nesting of grid containers.
In this revised demo, I've commented out display: grid on the body and .content elements. The only grid container left is on .main, the parent of the red boxes:
revised demo
html,
body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
In Firefox, a fixed value on max-width prevents the box from shrinking to accommodate smaller screen sizes.
Firefox has a problem shrinking the .main container with a pixel value on the max-width. Chrome does not.
A typical solution that comes to mind is to override the min-width: auto default setting on grid items. This prevents items from shrinking past the size of their content or their defined width.
However, that solution, described here: Prevent content from expanding grid items ... doesn't work in this case.
(Probably because there is no content in and no defined widths on the grid items. The only widths defined are on the grid columns, set on the grid container. So the solution, which applies only to grid items, probably doesn't even apply.)
As a possible workaround, if you must keep the nested containers, then instead of using a fixed value with max-width, use a percentage value. That may work for you.
revised codepen
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
height: 100vh;
margin: 0;
}
.header {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.content {
display: grid;
grid-template-columns: 1fr;
/* grid-template-rows: 0; */
align-content: start; /* new */
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 100px; /* new */
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
/* max-width: 1000px; */
max-width: 75%; /* new */
}
.placeholder {
border: 1px solid red;
}
.footer {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title,
.footer .copyright {
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer .copyright {
font-size: 12px;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>

Does the order of elements define their place in a CSS grid?

The following code works as expected: the cells are filled with colors between defined lines
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 2/4;
}
#item3 {
background-color: blue;
grid-column: 4/7;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
I then tried to swap the last two elements (yellow and blue), by swapping the grid-column entries:
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 4/7;
}
#item3 {
background-color: blue;
grid-column: 2/4;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
item3 is not correctly displayed. I suppose that this is because item2 has been rendered further in the grid and the earlier element cannot be rendered anymore (wild guessing).
I am lost at how the order of the elements in the HTML is influenced by the placement of elements in the CSS, as explained in the documentation? Shouldn't the order in the HTML be insignificant?
The items are inserted one by one into the grid in the order of appearance in the html and according to their specified placement. The placement algorithm does not try to fill any previous gaps.
Note: By default, the auto-placement algorithm looks linearly through the grid without backtracking; if it has to skip some empty spaces to place a larger item, it will not return to fill those spaces. To change this behavior, specify the dense keyword in grid-auto-flow.
#grid {
display: grid;
height: 300px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 4/7;
}
#item3 {
background-color: blue;
grid-column: 2/4;
}
#item4 {
background-color: grey;
grid-column: 5/6;
}
#item5 {
background-color: orange;
grid-column: 1/7;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
<div id="item4"></div>
<div id="item5"></div>
</div>
In your example you could either make use of the grid-auto-flow property and set it to dense as suggested by the documentation:
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
grid-auto-flow: dense;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 4/7;
}
#item3 {
background-color: blue;
grid-column: 2/4;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
or you could make use of the order property to get the wished result:
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 4/7;
order: 3;
}
#item3 {
background-color: blue;
grid-column: 2/4;
order: 2;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>
or, as suggested by GCyrillus, force the third item to be placed in the first row by using the grid-row property:
#grid {
display: grid;
height: 100px;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px;
}
#item1 {
background-color: lime;
}
#item2 {
background-color: yellow;
grid-column: 4/7;
}
#item3 {
background-color: blue;
grid-column: 2/4;
grid-row: 1;
}
<div id="grid">
<div id="item1"></div>
<div id="item2"></div>
<div id="item3"></div>
</div>