水平居中一个flex容器

7
当使用flex创建图像网格时,如何在页面上水平居中网格本身?我仍希望每行的图像左对齐。我希望它能够根据每行元素的数量动态调整。 这是我目前的Jsfiddle

.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>


基本上...这很难...通常需要JS或隐藏的虚拟元素。 - Paulie_D
1
https://dev59.com/clwY5IYBdhLWcg3wRGBS#32811002 - Paulie_D
我不确定这里是否真的需要一份详细的规范答案。Flexbox并不是为网格而设计的,它的设计目的是通过分配空白空间来实现更灵活的布局。对于网格,W3C正在开发CSS Grid Layout模块。在它获得浏览器支持之前,您可以使用Masonry。 - Michael Benjamin
5个回答

2
这个解决方案可以适用于任意数量的元素和宽度。 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>


玩弄宽度可以使底部元素居中而不是向左移动。 - JacksonHaenchen

1
正如许多答案在这里和网上所述,您将需要(至少目前)使用虚拟元素。
以下是一种简单的方法,在纯JavaScript中进行操作而无需计算:

  • 添加与.gallery-artwork元素数量相同的虚拟元素
  • 为这些虚拟元素提供相同的样式,没有高度,也没有垂直边距

这种方法有一个优点:您不需要进行任何计算! 您可以确保始终有足够的虚拟元素(无论屏幕宽度,元素数量及其每行数量如何),以将您的元素推到容器的左侧。

所以这就是代码!

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>


刚才编辑了我的答案,我忘记使用 cloneNode() 函数了,抱歉。 - zessx

0
  • 你可以将一个元素包裹在整个内容周围,然后像平常一样居中。
  • 让 flex 项左对齐的问题就像使用默认值 justify-content: flex-start 一样简单,但它不会居中。因此,为了保持居中对齐的 flex 项,我们使用 justify-content: center
  • 它完美地居中,但如果第二行的 flex 项数量较少,则会看起来像this
  • 为了保持所有内容水平居中,并且对于最后一行具有良好的左对齐行为,我们可以添加一个额外的 flex 项并给它这个属性:visibility: hidden。如果 flex 项的数量是动态的,则使用以下选择器:.gallery-artwork:last-of-type { visibility: hidden; }

这里是演示

CSS

/* The wrap element that surrounds and centers everything */
.exhibition {
  padding: 10px;
  margin: 20px auto;
}
/* justify-content: center is needed for centering of the flex-items */   
.gallery {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
}

.gallery-artwork {
  width: 400px;
  margin: 10px;
}
 /* This is the last of the gallery-artwork (flex-item). 
 Being of the same dimensions as the other flex-items and hidden from site,
fills in the gap of an uneven row of flex-items. */

.gallery-artwork:last-of-type {
  visibility: hidden;
}

HTML

<section class="exhibition">
  <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 class="gallery-artwork">
      <img src="http://placehold.it/400x225">
    </div>
  </div>
</section>

0

这是您更新后的CSS:

.gallery {
  display: flex;
  flex-flow: row wrap;
  justify-content:center;
}

.gallery-artwork {
  width: 400px;
  display: flex;
  flex-flow: column;
  margin: 0.5em;
}

jQuery:

$(document).ready(function(){
var i = $('.gallery-artwork').length;
    if (i % 2 == 0){
    }else{
        $(".gallery").append("<div class='gallery-artwork'></div>");
    }
});

代码片段:https://jsfiddle.net/debraj/p01mx39h/9/


但是最后一张图片没有左对齐。 - Oskar Persson
您可以动态添加元素。它将计算 gallery 下的所有 div,如果总数为奇数,则仅追加 spacer div。 - DebRaj
这不是根据元素数量动态的。试试这个:https://jsfiddle.net/ceab4gts/13/show/ - Oskar Persson
仍然不够动态,请尝试移除一张图片。 - Oskar Persson
是的,这就是为什么我删除了该注释。 - DebRaj
显示剩余2条评论

-1
稍微修改您的画廊CSS:
justify-content: center;

我今天用了这个,所以我立刻把它放进来了。但是这个CSS-tricks页面真的对弹性位和其他部分有很大帮助。


但是最后一行没有左对齐。 - Oskar Persson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接