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

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.

Related

CSS Image grid spacing issue

Im trying to add a image grid to a section in my page.
I've used this code:
<div class="champ-container">
<img src="image" />
<img src="image" />
<img src="image" />
<img src="image" />
<img src="image" />
</div>
CSS:
#champ-container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(3, max-content);
}
#champ-container img {
width: 100%;
}
here is what it currently doing:
There is a large space between each image, and I can't figure out why. I want maybe a 10px gap between the images. For this grid, I'm looking for three across and the rest wrapping to the next row. I dont understand how the third image ended up as its own row. all images are the same size: 288x164.
#champ-container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(3, max-content);
}
#champ-container img {
width: 100%;
}
<div id="champ-container">
<img src="image" />
<img src="image" />
<img src="image" />
<img src="image" />
<img src="image" />
</div>
You have used champ-container class in html but you have used it as an id. Change your css to this
Correct CSS:
.champ-container {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(3, max-content);
}
.champ-container img {
width: 100%;
}

Trying to get CSS grid layout correct

I am designing my own website using HTML and CSS. I have decided to use a grid as follows:
/* Style the grid container */
.item1 {
grid-area: logo;
}
.item2 {
grid-area: cta;
}
.item3 {
grid-area: menu;
}
.item4 {
grid-area: spacer;
}
.item5 {
grid-area: left;
}
.item6 {
grid-area: right;
}
.grid-container {
display: grid;
grid-template-areas: 'logo cta cta' 'menu menu menu' 'spacer spacer spacer' 'left right right';
grid-gap: 10px;
padding: 10px;
}
.grid-container>div {
border: 1px solid rgba(0, 0, 0, 0.8);
}
.item1 img {
min-width: 200px;
}
/* Responsive layout - makes the three columns stack on top of each other instead of next to each other */
#media (max-width: 600px) {
.grid-container {
grid-template-areas: 'logo' 'cta' 'menu' 'spacer' 'left' 'right';
}
}
<div class="grid-container">
<div class="item1">
<img src="Images/DN signatur es/dn_gold.png" style="width:25%" alt="" />
</div>
<div class="item2">
<p>dermot at dermotnolan dot ie</p>
</div>
<div class="item3">
<div class="topnav" id="myTopnav">
<a class="mnu active" href="#home">Home</a>
<a class="mnu" href="#about">About me</a>
<a class="mnu" href="#gallery">Gallery</a>
<a class="mnu" href="#imw">IMW</a>
<a class="mnu" href="#blog">Blog</a>
<a class="icon" href="javascript:void(0);" style="font-size:18px;" onclick="myFunction()">☰</a>
</div>
</div>
<div class="item4">
<br/>
</div>
<div class="item5">
<h2>Column 1 in Myriad</h2>
<h5>A heading in Consolas</h5>
</div>
<div class="item6">
<h2>Column 1 in Myriad</h2>
<h5>A heading in Consolas</h5>
<h2>Column 1 in Myriad</h2>
<h5>A heading in Consolas</h5>
<h2>Column 1 in Myriad</h2>
<h5>A heading in Consolas</h5>
</div>
</div>
My issue is that it looks like this:
Where I am expecting the left-most items (logo, left) to be one-column wide...
I'm certain I'm missing something simple, if anyone can make suggestions I'd be grateful.
Thanks in advance,
Dermot
I think you have forgotten to call your CSS file in the HTML document. you will need to call your CSS file in the head of your HTML file like the example below:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link type="text/css" rel="stylesheet" href="/css/styles.css">
<title></title>
</head>
I have attached a picture of my output.[screenshot of the picture][1]
[1]: https://i.stack.imgur.com/8LxGK.png
Actually I had referenced my CSS - what you see above is simply an excerpt from the code.
However, I managed to find a good solution which works perfectly:
=================================================
grid elemnent styling copied from
https://css-tricks.com/simple-named-grid-areas/#top-of-site
as well as W3Schools
=================================================
*/
/*HEADER area */
.gridheader {
display: grid;
grid-gap: 10px;
padding: 10px;
grid-template-columns: 300px 1fr 1fr;
grid-template-areas:
'logo logo cta'
'menu menu menu'
'spacer spacer spacer';
}
/*MAIN area */
.gridcolumns {
display: grid;
grid-gap: 10px;
padding: 10px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: 'left right right';
}

Two-Column Newspaper Layout with CSS Grid

I've got CSS grid to produce a two-column layout. But the problem is that it's not top-aligning content in each column.
For example, in the second column, the last element should top-align to but up against the other column-two element.
body>div {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: auto auto;
grid-auto-flow: column;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
body>div>div:nth-of-type(1) {
height: 300px;
}
body>div>div:nth-of-type(2) {
height: 100px;
}
body>div>div:nth-of-type(3) {
height: 200px;
}
<div style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
I couldn't use flex for this layout because I wanted to achieve this layout without defining the container height. column-count:2 would have worked without defining the container height but then I couldn't use div reordering.
So I'm using CSS grid because div reordering is still available (e.g./i.e. order:–1; works well) and it auto-divies up what to put in each of the two columns.
The gird is acting exactly as intended, to keep order and symmetry just like this. I can recommend using 2 grids side by side to achieve what you're looking for. Here's an example that I made to demonstrate this:
.left{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
float: left;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.right{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.left>div:nth-of-type(1) {
height: 300px;
}
.left>div:nth-of-type(2) {
height: 100px;
}
.right>div:nth-of-type(1) {
height: 200px;
}
.right>div:nth-of-type(2) {
height: 50px;
}
<div class="left" style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
</div>
<div class="right">
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
In fact, until a CSS technology arrives with the ability to automatically close the gaps, CSS in general has no solution. Something like this would probably require reflowing the document, so I'm not sure how useful or efficient it would be.
Source: https://stackoverflow.com/a/45200955/1625909

Scaling and aligning a simplistic website with image content

I am working on a simplistic website to show pictures in a single stream. To keep javascript to a minimum (just lazy loading), I only use a single relatively high-resolution version of each image and then rely on CSS to resize.
My question is how the rest of the website, at least the logo and the menu, can be best resized relative to the size of the images. After reading the CSS grid guide I decided to use a grid with grid-auto-flow: row.
The problem: I want the logo to flush left with the left of the top image and the menu to flush right with the right of the top image (all horizontal images have the same width).
My current code either aligns logo and menu to the corners of the page (as with the code below) or centers both (if I move the header into the grid as first item)
#main{
height: max-content;
display: grid;
grid-auto-flow: row;
grid-row-gap: 8em;
place-items: center center;
}
.photo_horizontal, .photo_vertical{
object-fit: contain;
height: auto;
}
.photo_horizontal{
width: 80vw;
max-height: 80vh;
}
.photo_vertical{
width: 60vw;
max-height: 90vh;
}
/* THE HEADER */
header{
display: grid;
grid-auto-flow: column;
}
#logo{
width: 15em;
justify-self: start;
}
header > div{
margin: auto 0 0 auto;
}
<header>
<img id="logo" src="https://via.placeholder.com/500x100/ff7f7f/333333?text=some%20website"/>
<div>
menu1
menu2
</div>
</header>
<div id="main">
<img class="photo_horizontal" src="https://picsum.photos/3000/2000"/>
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
</div>
Is there an elegant way to resize images relative to the viewport but still align other content accordingly? I tried to pad logo and menu left/right but the necessary padding depends on the actual size of the image.
A pen can be found here.
To clarify, this is how it currently is and this is what I want.
The main problem is setting .photo_horizontal's .max-height: 80vh; causes it to not always honor the width: 80vw; which means the width of the .photo_horizontal is not easily calculated. That makes it difficult to make the <header> the same width.
You can do this:
header {
width: 80vw;
margin: auto;
}
But it only works if you also get rid of the max-height: 80vh rule for .photo_horizontal.
https://codepen.io/km0ser/pen/LYpqeYB
Why not include the header within #main
/* Nothing wrong with CSS grid, just Flexbox is simpler */
#main {
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid;
}
/* height being auto will keep the aspect ratio */
/* horizontal photo take full width */
.photo_horizontal {
max-width: 100%;
}
/* horizontal photo take some portion of width */
.photo_vertical {
max-width: 80%;
}
header {
display: flex;
width: 100%;
}
#logo {
width: 15em;
}
header>div {
margin: auto 0 0 auto;
}
<div id="main">
<header>
<img id="logo" src="https://via.placeholder.com/500x100/ff7f7f/333333?text=some%20website" />
<div>
menu1
menu2
</div>
</header>
<img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
</div>
Thanks to the answers here I figured out a solution. There are three components:
As #Zohir Salak pointed out, much simpler CSS can be obtained using flexbox.
The header can be part of main even though this is not essential to the solution.
As #kmoser pointed out, the max-height constraint on images makes it hard to set a proper max-width constraint for the header, a problem that isn't solved by 1. and 2. yet. However, since all of my pictures are 3:2 ratio, a max-height constrained can be turned into a max-width constrained easily and then combined with a min via max-width: min(80vw, 3 / 2 * 80vh);.
/* Nothing wrong with CSS grid, just Flexbox is simpler */
#main {
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid;
}
/* height being auto will keep the aspect ratio */
/* horizontal photo take full width */
.photo_horizontal {
max-width: min(80vw, 3 / 2 * 80vh);
}
/* horizontal photo take some portion of width */
.photo_vertical {
max-width: min(80vw, 2 / 3 * 80vh);
}
header {
display: flex;
width: 100vw;
max-width: min(80vw, 3 / 2 * 80vh);
}
#logo {
width: 15em;
}
header>div {
margin: auto 0 0 auto;
}
<div id="main">
<header>
<img id="logo" src="https://via.placeholder.com/500x100/ff7f7f/333333?text=some%20website"/>
<div>
menu1
menu2
</div>
</header>
<img class="photo_horizontal" src="https://picsum.photos/3000/2000"/>
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_vertical" src="https://picsum.photos/2000/3000" />
<img class="photo_horizontal" src="https://picsum.photos/3000/2000" />
</div>
Alternatively, see the same code in a pen here.

Stretching an image inside a flex item to full width

I am playing around with CSS Flexbox and media queries and I stumbled across this issue. Considering the following code of mine, I can't get the last image in the last div item in the flex container to stretch to full width though I set the div item width to 100%. How can I achieve this? Here is my code:
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Playing with CSS Flexbox</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="layoutstyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<header>
<nav>
<div class="logo">
</div>
<ul>
<li>
</li>
</ul>
</nav>
</header>
<main id="container">
<div class="featured">
</div>
<div class="flexbox col-1">
<img src=images/singapore-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/singapore-x-small.jpg 400w,
images/singapore-small.jpg 600w,
images/singapore-medium.jpg 800w,
images/singapore-large.jpg 1000w,
images/singapore-x-large.jpg 1500w
"
/>
</div>
<div class="flexbox col-2">
<img src=images/skyscrapers-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/skyscrapers-x-small.jpg 400w,
images/skyscrapers-small.jpg 600w,
images/skyscrapers-medium.jpg 800w,
images/skyscrapers-large.jpg 1000w,
images/skyscrapers-x-large.jpg 1500w
"
/>
</div>
<div class="flexbox col-3">
<img src=images/sunset-small.jpg alt=""
sizes="(min-width: 650px) 70vw, 100w"
srcset="images/sunset-x-small.jpg 400w,
images/sunset-small.jpg 600w,
images/sunset-medium.jpg 800w,
images/sunset-large.jpg 1000w,
images/sunset-x-large.jpg 1500w
"
/>
</div>
</main>
</body>
</html>
////////CSS//////
* {
box-sizing: border-box;
}
body,html {
width: 100%;
height: 100%;
}
body {
margin: 0;
}
li {
padding: 0;
list-style-type: none;
}
header {
display: flex;
}
main {
display: flex;
flex-flow: row wrap;
justify-content: center;
width: 100%;
}
#media all and (max-width: 650px) {
.flexbox {
width: 100%;
}
}
#media all and (min-width: 651px) {
.col-1, .col-2 {
width: 50%;
}
.col-3 {
width: 100%;
}
}
Add this to your CSS to maximize your images:
.flexbox img {
width: 100%;
height: auto;
}
Demo at CodePen
If older browser compatibility isn't an issue, using just flex-box properties can achieve this. So regardless of the number of flex-items in the container, last odd-item always stretches.
flex-grow: unitless value;
Tells flex item how much space inside the flex container it should take if necessary (in proportion to others.)
If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least). source & more details: css-tricks.com
Following is the basic idea,
#container {
display: -webkit-box; /* OLD - iOS 6-, Safari */
display: flex;
flex-wrap:wrap;
}
.flexbox {
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari */
flex-basis: 50%;
flex-grow: 2;
}
.flexbox img {width: 100%;}
CodePen Example

Resources