Free Web Design Code & Scripts

CSS Grid Photo Gallery

CSS Grid Photo Gallery
Code Snippet:Image swap using anchor-positioning
Author:
Published: 3 weeks ago
Last Updated: 3 weeks ago
Downloads: 112
License: MIT
Edit Code online: View on CodePen
Read More

Do you want to display your images in a stunning and interactive way on your website? Creating a modern CSS Grid Photo Gallery can help you achieve this. This tutorial will guide you through building a responsive image gallery. It uses advanced CSS features like Grid layout and anchor-positioning for an engaging image swap effect. This method ensures a dynamic and visually appealing presentation of your content without needing JavaScript.

How to Create a CSS Grid Photo Gallery

Step 1: Create the HTML Structure

First, set up the basic HTML for your gallery. This includes a main container and several image links. Each link has an image and a title. The main-img div will serve as the container for the swapped image.

<div class="gallery">

  <div class="main-img"><h1>Image swap using <code>anchor-positioning</code></h1></div>
  
  <a href="#item-1" id="item-1">
    <img src="https://picsum.photos/id/34/400/400" alt="Aleks Dorohovich">
    <h2>Aleks Dorohovich</h2>
  </a>

  <a href="#item-2" id="item-2">
    <img src="https://picsum.photos/id/39/400/400" alt="Luke Chesser">
    <h2>Luke Chesser</h2>
  </a>

  <a href="#item-3" id="item-3">
    <img src="https://picsum.photos/id/56/400/400" alt="Sebastian Muller">
    <h2>Sebastian Muller</h2>
  </a>

  <a href="#item-4" id="item-4">
    <img src="https://picsum.photos/id/76/400/400" alt="Alexander Shustov">
    <h2>Alexander Shustov</h2>
  </a>

  <a href="#item-5" id="item-5">
    <img src="https://picsum.photos/id/124/400/400" alt="Anton Sulsky">
    <h2>Anton Sulsky</h2>
  </a>

  <a href="#item-6" id="item-6">
    <img src="https://picsum.photos/id/139/400/400" alt="Steve Richey">
    <h2>Steve Richey</h2>
  </a>

  <a href="#item-7" id="item-7">
    <img src="https://picsum.photos/id/159/400/400" alt="Shyamanta Baruah">
    <h2>Shyamanta Baruah</h2>
  </a>

  <a href="#item-8" id="item-8">
    <img src="https://picsum.photos/id/200/400/400" alt="Elias Carlsson">
    <h2>Elias Carlsson</h2>
  </a>
  
  <a href="#item-9" id="item-9">
    <img src="https://picsum.photos/id/441/400/400" alt="327">
    <h2>Ryan Schroeder</h2>
  </a>

</div>

Step 2: Apply CSS Styling

Next, we will style the gallery using CSS Grid. This CSS will arrange your images in a grid layout. It also handles the responsive behavior and the interactive image swap. Modern CSS features like anchor-positioning are used here for the dynamic image display.

@import url(https://fonts.bunny.net/css?family=jura:300,500);
@layer base, mouse, demo;

@layer demo{
  body{
    font-family: "Jura", sans-serif;
  }
  .gallery {
    --size: 100%;
    --grid-cols: repeat(3, 1fr);
    --grid-rows: repeat(6,1fr);
    --gap: .5rem;
		--main-image-columns: 1 / -1;
		--main-image-rows: 1 / span 3;
    --main-img-w: 100%;
    --main-img-h: auto;
    
   @media (width > 600px) {
      --size: 120px;
      --grid-cols: repeat(6, 1fr);
      --grid-rows: repeat(3,1fr);
			--main-image-columns: 4 / -1;
			--main-image-rows: 1 / span 3;
      --main-img-w: auto;
      --main-img-h: 100%;
    }
    width: min(100%, 900px);
    display: grid;
    grid-template-columns: var(--grid-cols);
		grid-template-rows: var(--grid-rows);
    gap: var(--gap);
    position: relative;
    
    > .main-img {
      position: relative;
      grid-column: var(--main-image-columns);
      grid-row: var(--main-image-rows);
      display: grid;
      place-content: center;
			padding: 1em;
      font-size: 2rem;
      anchor-name: --main-img;
      overflow: hidden;
			/* gradient to help with readability of the image title */
      border-image: fill 0 linear-gradient(transparent 50%, black); 
			& > h1{
				margin: 0;
				font-size: clamp(1rem, 2.5vw + 0.45rem, 1.2rem);
			}
      /* if any sibling has target - hide title */
      &:has(~:target) h1{
        display: none;
      }
    }
    > a {
      display: block;
      aspect-ratio: 1;
      border: 1px dotted steelblue;
      overflow: hidden;
      &:hover:not(:target) img{
        opacity: .5;
      }
      & > img{
        object-fit: cover;
        transition: opacity 300ms ease-in-out;
      }
			/* set anchor position on current :target image */
      &:target img{
        position: absolute;
        inset: anchor(top) anchor(right) anchor(bottom) anchor(left);
        position-anchor: --main-img;
        width: var(--main-img-w,0);
        height: var(--main-img-h,0);
        animation: --fade-in  750ms ease-in-out;
				z-index: -1;
      }
      > h2 {
        color: white;
        font-size: 1.2rem;
        font-weight: 300;
        opacity: 0;
        translate: 0 1lh;
        transition: all 300ms ease-in-out;
      }
      &:target h2{
        position: absolute;
        inset: auto;
        bottom:anchor(bottom);
        left: calc(anchor(left) + 1rem);
        position-anchor: --main-img;
        opacity: 1;
        translate: 0 0;
      }
    }
  }

  @keyframes --fade-in{
    from{
      opacity: 0;
    }
    to{
      opacity: 1;
    }
  }
}

/* general styling not relevant for this demo */
@layer base {
	* {
		box-sizing: border-box;
	}
	:root {
		color-scheme: light dark;
		--bg-dark: rgb(12, 10, 9);
		--bg-light: rgb(248, 244, 238);
		--txt-light: rgb(10, 10, 10);
		--txt-dark: rgb(245, 245, 245););
		--line-light: rgba(0 0 0 / .25);
		--line-dark: rgba(255 255 255 / .25);
    
    --clr-bg: light-dark(var(--bg-light), var(--bg-dark));
    --clr-txt: light-dark(var(--txt-light), var(--txt-dark));
    --clr-lines: light-dark(var(--line-light), var(--line-dark));
	}
 
	body {
		background-color: var(--clr-bg);
		color: var(--clr-txt);
		min-height: 100svh;
		margin: 0;
		padding: 2rem;
		font-family: "Jura", sans-serif;
		font-size: 1rem;
		line-height: 1.5;
    display: grid;
    place-items: center;
    gap: 2rem;
	}
  @supports not (position-anchor: --test) {
	 body::before {
			content:"Sorry, your browser doesn't support anchor-positioning";
			position: fixed;
			top: 2rem;
			left: 50%;
			translate: -50% 0;
			font-size: 0.8rem;
		}
	}
  img {
    max-width: 100%;
    display: block;
  }
}

That’s all! You have successfully created a dynamic CSS Grid Photo Gallery. If you have any questions or suggestions, feel free to comment below.

Loading... ...

Loading preview...

Device: Desktop
Dimensions: 1200x800
Lines: 0 Characters: 0 Ln 1, Ch 1

Leave a Comment

About W3Frontend

W3Frontend provides free, open-source web design code and scripts to help developers and designers build faster. Every snippet is reviewed before publishing for quality. Learn more.