弹性项目是不是可以与它们上方的项目紧密对齐?

Posted

技术标签:

【中文标题】弹性项目是不是可以与它们上方的项目紧密对齐?【英文标题】:Is it possible for flex items to align tightly to the items above them?弹性项目是否可以与它们上方的项目紧密对齐? 【发布时间】:2016-04-01 13:11:24 【问题描述】:

这实际上是 Pinterest 布局。但是,网上找到的解决方案是用列包裹的,这意味着容器在不经意间会水平增长。那是不是 Pinterest 布局,它不适用于动态加载的内容。

我想要做的是有一堆固定宽度和不对称高度的图像,水平布局,但在满足固定宽度容器的限制时换成新行:

flexbox 可以做到这一点,还是我必须求助于像 Masonry 这样的 JS 解决方案?

【问题讨论】:

不清楚你的元素的顺序应该是什么,这很重要。你能给他们加数字吗? 我虽然是这样,但它可能会限制可能的答案。我确实知道前三名从左到右分别是 1、2、3,但我并不关心 4 是放在 1、2 还是 3 之下。(如果垂直放置是标准,它应该低于 3 ; 如果是水平放置,它应该在1以下。)随便吧! No flexbox 不是这个布局的好解决方案,你应该使用砖石或在最坏的情况下使用 css 列,它类似于我对这个问题的回答,所以它可能会帮助你***.com/questions/34417059/… ***.com/questions/8470070/… 聚会有点晚了,这里是 Pinterest 脚本的作者和 Pinterest 的联合创始人 Evan Sharp 的answer to a similar question,他解释了其中的逻辑。 【参考方案1】:

Flexbox 是一个“一维”布局系统:它可以沿水平或垂直线对齐项目。

真正的网格系统是“二维”的:它可以沿水平和垂直线对齐项目。换句话说,单元格可以跨越列和行,这是 flexbox 做不到的。

这就是为什么 flexbox 构建网格的能力有限的原因。这也是W3C 开发另一种 CSS3 技术 Grid Layout 的原因(见下文)。


在带有flex-flow: row wrap 的弹性容器中,弹性项目必须换行到新的

这意味着一个弹性项目不能包裹在同一行中的另一个项目之下

注意上面的 div #3 如何包裹在 div #1 之下,创建一个新行。它不能包裹在 div #2 之下。

因此,当项目不是该行中最高的项目时,会留下空白,造成难看的间隙。

图片来源:Jefree Sujit


column wrap 解决方案

如果您切换到flex-flow: column wrap,弹性项目将垂直堆叠,并且更容易实现类似网格的布局。但是,列方向容器立即存在三个潜在问题:

    它水平扩展容器,而不是垂直扩展(如 Pinterest 布局)。 It requires the container to have a fixed height, so the items know where to wrap. 在撰写本文时,它在 the container doesn't expand to accommodate additional columns 的所有主要浏览器中都存在缺陷。

因此,在许多情况下,列方向容器可能不可行。


其他解决方案

添加容器

在上面的前两个图像中,考虑将项目 2 和 3 包装在单独的容器中。这个新容器可以是第 1 项的同级容器。完成。

这里有一个详细的例子:Calculator keypad layout with flexbox

一个值得强调的缺点:如果您想使用 order 属性重新排列布局(例如在媒体查询中),此方法可能会消除该选项。

Desandro Masonry

Masonry 是一个 javascript 网格布局库。它 通过根据可用的元素将元素放置在最佳位置来工作 垂直空间,有点像石匠在墙上装石头。

来源:http://masonry.desandro.com/

How to Build a Site that Works Like Pinterest

[Pinterest] 确实是一个很酷的网站,但我觉得有趣的是这些插板是如何布置的......所以本教程的目的是我们自己重新创建这种响应式块效果......

来源:https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html

CSS Grid Layout Module Level 1

这个 CSS 模块定义了一个基于网格的二维布局系统,针对用户界面设计进行了优化。在网格布局模型中,网格容器的子项可以定位到预定义的灵活或固定大小布局网格中的任意槽中。

来源:https://drafts.csswg.org/css-grid/

网格布局示例:CSS-only masonry layout but with elements ordered horizontally

【讨论】:

【参考方案2】:

你想要的可以通过 3 2 种方式实现,CSS 明智:

1。 弹性框:

    .parent 
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        max-width: max-width-of-container /* normally 100%, in a relative container */
        min-height: min-height-of-container; /* i'd use vh here */
    
    .child 
        width: column-width;
        display: block;
    

2。 CSS 列

(此解决方案具有内置 column-span 的非常巧妙的优势 - 对于标题来说非常方便)。缺点是按列排序项目(第一列包含项目的前三分之一,依此类推......)。我为此做了一个jsFiddle。

    .parent 
        -webkit-columns: column width number of columns; /* Chrome, Safari, Opera */
        -moz-columns: column width number of columns; /* Firefox */
        columns: column width number of columns;
    
    .child 
         width: column width;
    
    /* where column width is usually fixed size 
     * and number of columns is the maximum number of columns.
     * Additionally, to avoid breaks inside your elements, you want to add:
     */
    .child 
        display: inline-block;
        -webkit-column-break-inside: avoid;
        page-break-inside: avoid;
        break-inside: avoid-column;
    

3。砌体插件

通过 JavaScript(砌体插件)计算渲染项目大小后的绝对定位。

【讨论】:

#1 在最新的 Firefox 上对我不起作用(我应该使用游乐场示例进行更新;会这样做)。 #2 实际上非常接近,需要解决一些怪癖,但我知道它使用了新的 CSS 网格系统,但浏览器支持很差。 你是对的#1。我无法使用 flex 使其工作。不确定“非常差的浏览器支持”是什么意思。请给我一些数字好吗?我认为#2 对不到 5% 的用户有问题。如果我错了,请纠正我。 如果您查看 Usage Relative 统计信息,大量用户不支持网格系统,因此它可能还没有准备好生产。不过,这是一个很好的解决方案,谢谢。 caniuse.com/#search=grid 令人着迷。你能发现grid 和columns 之间的区别吗?【参考方案3】:

column 方法似乎是一个不错的折衷方案,如果您通过 vminvmax 单位设置 column-width 并删除 column-count (first sn-p) 、 display:gridvmin 也是一个选项为了未来(第二次 sn-p)。

sn-p 灵感来自@Lanti 的回答。

用 vmin 测试演示

.container 



ul 
  margin: 0;
  padding: 0;


ul li 
  list-style: none;
  font-size: 0;


.portfolio ul 
  -webkit-column-width:50vmin;
     -moz-column-width:50vmin;
          column-width:50vmin;
  -webkit-column-fill:balance;
     -moz-column-fill:balance;
          column-fill:balance;
  -webkit-column-gap: 3px;
     -moz-column-gap: 3px;
          column-gap: 3px;


.portfolio ul:hover img 
  opacity: 0.3;


.portfolio ul:hover img:hover 
  opacity: 1;


.portfolio ul li 
  margin-bottom: 3px;


.portfolio ul li img 
  max-width: 100%;
  transition: 0.8s opacity;
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg"  /></li>
  </ul>
</section>

其他链接https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/


display:grid 可以通过自动填充使其变得容易,但需要将跨度值设置为最高图像,以便行和列可以融合

.container 

ul 
  margin: 0;
  padding: 0;


ul li 
  list-style: none;
  font-size: 0;


.portfolio ul 
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(50vmin, 1fr));
  grid-gap: 5px;
  grid-auto-rows: minmax(10px, 1fr);
  grid-auto-flow: dense;


.portfolio ul:hover img 
  opacity: 0.3;


.portfolio ul:hover img:hover 
  opacity: 1;


.portfolio ul li 
  margin-bottom: 3px;


.portfolio ul li img 
  max-width: 100%;
  transition: 0.8s opacity;


li 
  border: solid blue;
  grid-row-end: span 1;
  display: flex;
  align-items: center;
  background: lightgray;


li:nth-child(1),
li:nth-child(3),
li:nth-child(6),
li:nth-child(7),
li:nth-child(8),
li:nth-child(9),
li:nth-child(10),
li:nth-child(11) 
  border: solid red;
  grid-row-end: span 2
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg"  /></li>
  </ul>
</section>

你可以看到https://css-tricks.com/snippets/css/complete-guide-grid/

【讨论】:

第一个sn-p中的图片顺序不对,就是分列排列的问题。但第二个似乎是正确的!真不错【参考方案4】:

你可以根据你的截图实现砌体效果,但你已经动态设置了外部 div 的高度

html 
  box-sizing: border-box;

*,
*:before,
*:after 
  box-sizing: inherit;

.item-list 
  max-width: 400px;
  border: 1px solid red;
  display: -ms-flexbox;
	-ms-flex-direction: column;
	-ms-flex-wrap: wrap;
	display: flex;
	flex-direction: column;
	flex-wrap: wrap;
	height: 100vw;

.item-list__item 
  border: 1px solid green;
  width: 50%;
<div class="item-list" >
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
    county enough the figure former add. Do sang my he next mr soon. It merely waited do unable.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do.
  </div>
  <div class="item-list__item">
    Is we miles ready he might going. Own books built put civil fully blind fanny. Projection appearance at of admiration no. As he totally cousins warrant besides ashamed do. Therefore by applauded acuteness supported affection it. Except had sex limits
  </div>
</div>

【讨论】:

【参考方案5】:

我建议使用columns 代替flexbox 来处理这样的网格。如您所见,底部图像的间距可以更好,但对于原生 CSS 解决方案,我认为它非常整洁。没有更多的JS:

.container 
  max-width: 900px;
  width: 100%;
  margin: 0 auto;


ul 
  margin: 0;
  padding: 0;


ul li 
  list-style: none;
  font-size: 0;


.portfolio ul 
  -moz-column-count: 4;
  -webkit-column-count: 4;
  column-count: 4;
  -moz-column-gap: 3px;
  -webkit-column-gap: 3px;
  column-gap: 3px;


.portfolio ul:hover img 
  opacity: 0.3;


.portfolio ul:hover img:hover 
  opacity: 1;


.portfolio ul li 
  margin-bottom: 3px;


.portfolio ul li img 
  max-width: 100%;
  transition: 0.8s opacity;
<section class="container portfolio">
  <ul>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_2959-1400px.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-010.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/IMG_6188-dng-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151220-csaladi-peregi-046-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/20151230-csalad-szalai-0194-k.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/lantosistvan-portfolio-001(1).jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171819-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171829-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171938-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528171953-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528194754-portfolio.jpg"  /></li>
    <li><img src="http://lantosistvan.com/temp/freecodecamp/160528184948-portfolio.jpg"  /></li>
  </ul>
</section>

【讨论】:

看起来不错,但是元素的顺序是错误的。具有挑战性的部分是水平布局元素,然后垂直包裹。

以上是关于弹性项目是不是可以与它们上方的项目紧密对齐?的主要内容,如果未能解决你的问题,请参考以下文章

Tailwind/Vue 动态地将弹性项目对齐到与邻居相同的高度

如何使用 Flexbox 使一个弹性项目居中对齐并右对齐另一个

垂直对齐不适用于弹性项目

如何在容器中居中元素,同时保持它们垂直对齐?

删除/添加项目时是不是可以为弹性项目的位置设置动画?

如何将包装弹性项目显示为最后一行左对齐的空格?