Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontally centering a flex container

Tags:

html

css

flexbox

When using flex for creating a grid of images, how can I horizontally center the grid itself on the page? I still want the images to left-align on each row. I would like it to be dynamic to the number of elements per row.

Jsfiddle with what I have so far

.gallery {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-content: flex-start;
  align-items: flex-start;
}

.gallery-artwork {
  width: 400px;
  display: flex;
  margin: 10px;
}
<div class="gallery">
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
</div>
like image 964
Oskar Persson Avatar asked Feb 09 '16 15:02

Oskar Persson


2 Answers

This solution will work regardless of the number of elements and width.

https://jsfiddle.net/p01mx39h/14/

function addDummies() {
  imgsPerRow = Math.floor($(".gallery").width() / $(".gallery-artwork").outerWidth(true));
  if (imgsPerRow > 1) {
    missingImages = imgsPerRow - $(".gallery-artwork").length % imgsPerRow;
    while (missingImages > 0) {
      $(".gallery").append("<div class='gallery-artwork-dummy'></div>");
      $(".gallery-artwork-dummy").css('width', $('.gallery-artwork').outerWidth(true));
      missingImages--;
    }
  }
}

$(document).ready(function() {
	addDummies();
});
.gallery {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-content: flex-start;
  align-items: center;
}

.gallery-artwork {
  width: 400px;
  display: flex;
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gallery">
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
</div>
like image 84
Mikael Avatar answered Oct 20 '22 02:10

Mikael


As stated by many answer here and on the web, you'll need (at least, for now) dummies elements.
Here's a way to do it easily, without calculation, and in plain JavaScript:

  • Add as many dummies as the amount of .gallery-artwork elements
  • Give these dummies the same style, without any height, nor vertical margins

This method has an advantage: you don't need to do any calculation! You're sure to always have enough dummies (whatever the screen width, the number of elements and their amount per row) to push your elements on the left side of your container.

So here's the code!

var gallery = document.querySelector('.gallery'),
    artworks = gallery.querySelectorAll('.gallery-artwork'),
    dummy = document.createElement('div');
dummy.classList.add('gallery-dummy');

// One element = one dummy
[].forEach.call(artworks, function() {
  gallery.appendChild(dummy.cloneNode());
});
.gallery {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.gallery-artwork {
  width: 400px;
  margin: 10px;
}
.gallery-dummy {
  width: 400px;
  margin: 0 10px;
  height: 0;
}
<div class="gallery">
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
  <div class="gallery-artwork">
    <img src="http://placehold.it/400x225">
  </div>
</div>
like image 35
zessx Avatar answered Oct 20 '22 03:10

zessx