How to Build a Responsive Image Gallery with Flexbox

How to Build a Responsive Image Gallery with Flexbox

You may have noticed I’ve updated the site to include a front page with a grid listing all the tutorials. As you resize the screen, it goes from three columns, to two columns, to a single column on mobile. Another great example of that is this really weird musical side project of mine, where I arrange all the songs as if they’re a Spotify album listing. The only real difference between those two is that one has margins, and the other doesn’t.

In this quick article, I’m going to go over how to create a responsive grid of images like that with flexbox.

Prerequisites

  • Basic knowledge of HTML and CSS.

Goals

  • Create a responsive, repeating grid (image gallery) with flexbox.
  • (Optional) Demonstrate how to integrate that into a custom WordPress loop.

Grid

Make sure before starting to include some sort of reset, or at least set box-sizing: border-box and margin: 0 to the body. (More about all that, if you’re not sure.) Now we can get started on the grid.

Mobile

We’ll start off by making the mobile page – mobile first layout means utilizing min-width @media queries for bigger screen sizes.

I’m just going to put everything inside a generic container to start.

.container {
  margin: 0 auto;
  max-width: 1200px;
  padding: 0 1rem;
}

The grid class will be the flex wrapping container. For mobile, everything is one column, so it doesn’t need to be defined as flex yet.

Inside that, I’m going to make a cell and place an image inside of that. We’ll make the image responsive by putting a max-width on it.

.responsive-image {
  max-width: 100%;
}

And the image should be a block level element.

.cell img {
  display: block;
}

So here’s our whole HTML code.

<div class="container">
  <div class="grid">
    <div class="cell">
      <img src="http://placehold.it/800x800" class="responsive-image">
    </div>
    <div class="cell">
      <img src="http://placehold.it/800x800" class="responsive-image">
    </div>
    <div class="cell">
      <img src="http://placehold.it/800x800" class="responsive-image">
    </div>
    <div class="cell">
      <img src="http://placehold.it/800x800" class="responsive-image">
    </div>
  </div>
</div>

It looks like this.

mobile

That’s all we need for mobile. Now we’ll move on to the medium screen devices.

Tablet

I’m going to choose 600px as the width to start showing the mid-screen view. We want the images to show up in rows of two now.

@media screen and (min-width: 600px) {
  .grid {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
  }
  .cell {
    width: 50%;
  }
}

The grid wrapping container is defined as a flex element, which will wrap in the direction of a row (horizontal). Since I now want the images to show up in rows of two columns, I’m going to set the width to 50%.

tablet

Desktop

At 1000px, I’m going to show the desktop view, which will display the images in rows of three.

@media screen and (min-width: 1000px) {
  .cell {
    width: calc(100% / 3);
  }
}

I write out the width as calc(100% / 3) instead of 33.33333%, because it’s easier to make sure it’s correct.

desktop

Margins

This gallery has no padding or spacing between the images. You have to make some slight adjustments if you want to add space between all the images.

First, add a margin around the cell for all screen sizes.

.cell {
  margin: 1rem;
}

Then edit the width of the cells on their respective sizes.

@media screen and (min-width: 600px) {
  .cell {
    width: calc(50% - 2rem);
  }
}

@media screen and (min-width: 1000px) {
  .cell {
    width: calc(33.3333% - 2rem);
  }
}

WordPress Gallery

The best part about this grid is it can be easily looped. If you’re not familiar with WordPress, here’s the article to get you started.

Instead of using a WordPress gallery plugin, you can pull images by category from the media gallery. The prerequisite to this is allowing categories for attachments, which you can do by adding this code to functions.php.

// Add Categories for Attachments
function add_categories_for_attachments() {
    register_taxonomy_for_object_type( 'category', 'attachment' );
}
add_action( 'init' , 'add_categories_for_attachments' );

There is one small, useful plugin that you might want to use that allows you to bulk add and delete categories from gallery images – Media Library Categories.

Here’s an example using the flex grid above and pulling all images from the gallery with the category of “Gallery”.

<div class="container">
	<div class="grid">
			<?php 
			$args = array(
				'post_type' => 'attachment',
				'post_mime_type' => 'image',
				'orderby' => 'post_date',
				'order' => 'asc',
				'posts_per_page' => '30',
				'post_status'    => 'inherit',
				'category_name' => 'Gallery'
			 );
			$loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post();
			$image = wp_get_attachment_image_src( get_the_ID(), 'full' ); // Full sized image
			$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'thumbnail' ); // Thumbnail size 
      ?>

				<div class="cell"><a href="<?php echo $image[0]; ?>"><img src="<?php echo $thumb[0]; ?>" class="responsive-image"></a></div>

			<?php endwhile; ?>
	</div>
</div>

Conclusion

This is a very basic, simplified version of a flex grid, but hopefully you have a good understanding of how a looping flex grid works now. Fluidbox is a great jQuery library I also like to combine with front end code for a beautiful gallery. Masonry is another useful library if you’re dealing with all differently sized images.

View Demo

Leave a Reply

Your email address will not be published.

Markdown is enabled in comments. If you would like to post code in your comments, please wrap it in a <pre><code>. HTML/PHP code must be escaped. Failure to do so will make me sad.

Example:

<pre><code>def print_hi(name)
  puts "Hi, #{name}"
end
print_hi("Tania")</code></pre>

7 comments on “How to Build a Responsive Image Gallery with Flexbox”

  • Rolf says:

    Thank you so much for to share Your Creativity. It’s very helpful for me – great stuff, plain and simple!

  • Xavier says:

    Thank you for this tutorial, really helped me to understand the basics of Flexbox :). I’ll check other articles as well as it seems are simple to follow, well written and updated. Being an autodidact myself and e-learning student I find your website quite useful, so thanks for your time and work.

  • Patrick says:

    I leave a gift here, as the flexbox definitions are not cross-broswer complete: for your class container, I usually use this broader definition:

    .wrapper{width:100%;overflow:auto;display: -webkit-box;display: -moz-box;display: -ms-flexbox;display: -webkit-flex;display: flex;-webkit-box-orient: horizontal;-moz-box-orient: horizontal;-webkit-box-direction: normal;-moz-box-direction: normal;-webkit-flex-direction: row;-ms-flex-direction: row;flex-direction: row;flex-flow: row wrap;}

    and a cell in my case has usually width: as desired, may be percentage or fixed width; height: the same; margin-left:auto; margin-right:auto

  • Roy Hen says:

    Brilliant! Simple to follow and understand. Well written.

  • Curious about why you didn’t just set it up so that flexbox takes care of everything, and skip the media queries:

    .container {
    display:flex;
    flex-wrap: wrap;
    justify-content: space-between;
    }
    
    .cell {
    flex: 1 1 300px;
    margin: 1rem;
    }

    Then you just need one media query, so that you don’t get 3 images of one size and 1 of another if you have 4 cells in rows of 3:

    @media screen and (min-width: 1000px) {
    .cell {
    flex: 0 1 300px;
    }
    }