在弹性项目之间显示一个 div

Posted

技术标签:

【中文标题】在弹性项目之间显示一个 div【英文标题】:Show a div in between flex items 【发布时间】:2018-02-03 05:08:47 【问题描述】:

我正在创建一个填充有<div> 元素的页面。包含这个 div 的容器有display: flex;。所以项目自动换行到几行。现在我想点击一个项目,这样它会打开另一个<div>,其中包含有关所选项目的信息。但此信息 div 应位于包含所选 div 的行下方,并且具有容器的全宽。

我不知道如何进行这项工作。 我做了一个简单的 JsFiddle 开头:https://jsfiddle.net/44j4jnq4/3/

我正在获取点击事件,并通过 Angular 动态添加 dinfo div。 我的问题主要是关于如何设置它的样式,这样它就不会弄乱弹性项目并具有容器的宽度。

我也有这张图片来形象化我的目标。

希望你能帮我解决这个问题。

【问题讨论】:

使用 Angular,您需要找到所选项目行上的最后一项,在其后注入元素并将其 flex-basis 设置为 100%。这样做之后,注入的元素将参与到您的绘图显示中的布局中,在自己的一行上填充容器的宽度。 @LGSon 但是我如何连续获得最新的弹性项目。如果信息框打开并且我调整页面大小,那么这会起作用吗,所以最后一个元素会翻转下一行?如果可能的话,我宁愿看到更多基于 CSS 的东西,然后用 Angualr 简单地计算它。 由于没有 CSS 会知道哪个元素是最后一个并且能够在之后保留注入的元素,因此最接近的是在单击后注入它,并且绘图作为样本,你会得到这个:jsfiddle.net/44j4jnq4/4 如果点击第二个项目,你会得到这个jsfiddle.net/44j4jnq4/5 ...并且你可以看到他们不会平均每行的项目。为了克服这个问题,您需要一个脚本来找到行中的最后一个并在它之后注入它。您还需要使用调整大小事件并跟踪换行符并相应地调整注入的项目 @LGSon 我没有在两行之间注入新的div,而是希望扩大点击的div的高度并将信息框添加到该div。就像在这个Fiddle 中一样,但我现在不知道如何使它成为容器的宽度。我猜这样它总是连接到正确的div。 【参考方案1】:

我通过将.item 包裹在.item-container 中来稍微修改了html 以实现所需的样式。

我还使用:after 元素来显示来自title.infobox 的信息。

为了填充宽度,我添加了一个高度固定的 div 和一个绝对定位的 :after,它引用了 .container 以获取全宽,请单击 .item 以查看信息,请检查这个出来了。

$('.container').click(function(e)
	if(!$(e.target).next().hasClass('show'))
   $('.item-container .show').removeClass('show');
   $(e.target).next().addClass('show');
  
)
.container 
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  background-color: grey;
  position: relative;

.item 
  width: 300px;
  height: 150px;
  background-color: pink;
  margin: 0px 5px 10px 5px;


.infobox 
  height: 110px;
  display: none;

.infobox.show
  display: block;

.infobox.show:after
    content: attr(title);
    display: block;
    height: 100px;
    background: #FFF;
    width: calc(100% - 20px);
    position: absolute;
    overflow-y: scroll;
    left: 0;
    margin-left: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="container">
    <div class="item-container"> 
      <div class="item">Item 1</div><div class="infobox" title="Item 1 info"></div>
    </div>
    <div class="item-container">
      <div class="item">Item 2</div><div class="infobox" title="Item 2 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 3</div><div class="infobox" title="Item 3 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 4</div><div class="infobox" title="Item 4 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 5</div><div class="infobox" title="Item 5 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 6</div><div class="infobox" title="Item 6 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 7</div><div class="infobox" title="Item 7 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 8</div><div class="infobox" title="Item 8 info"></div>
    </div>
</div>

不使用:after 元素,试试这个

$('.container').click(function(e)
	if(!$(e.target).next().hasClass('show'))
   $('.item-container .show').removeClass('show');
   $(e.target).next().addClass('show');
   $(e.target).next().html('<div class="content"><h4>'+$(e.target).next().attr('title')+'</h4><img style="width:50px" src="https://olinuris.library.cornell.edu/sites/default/files/equipment/Draper%2050x50%20Template_1.jpg" /><button>Press</button></div>')
  
)
.container 
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  background-color: grey;
  position: relative;

.item 
  width: 300px;
  height: 150px;
  background-color: pink;
  margin: 0px 5px 10px 5px;


.infobox 
  height: 160px;
  display: none;

.infobox.show
  display: block;

.infobox .content
    height: 150px;
    background: #FFF;
    width: calc(100% - 20px);
    overflow-y: scroll;
    position: absolute;
    left: 0;
    margin-left: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="container">
    <div class="item-container"> 
      <div class="item">Item 1</div><div class="infobox" title="Item 1 info"></div>
    </div>
    <div class="item-container">
      <div class="item">Item 2</div><div class="infobox" title="Item 2 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 3</div>
      <div class="infobox" title="Item 3 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 4</div><div class="infobox" title="Item 4 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 5</div><div class="infobox" title="Item 5 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 6</div><div class="infobox" title="Item 6 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 7</div><div class="infobox" title="Item 7 info"></div>
    </div>
    <div class="item-container"> 
      <div class="item">Item 8</div><div class="infobox" title="Item 8 info"></div>
    </div>
</div>

【讨论】:

缺点是由于使用了绝对定位,因此信息不会推动紧随其后的元素 如果你检查你可以看到.infobox没有定位只有:after元素被定位。由于父级相对于.item,它会推送内容,唯一的限制是我们必须为.infobox 设置一个特定的高度,如果信息不是动态的,这不是问题。 这就是我所说的 info 不会推送后面的元素时的意思。这个解决方案需要在信息上设置一个固定的高度,这可能非常好,是一个纯 CSS 的解决方案 这个解决方案看起来很有希望,我想我可以在 Angular 中使用 ngIf 删除“隐藏”信息框。我会试一试,看看效果如何。 @SaravananI 我测试了你更新的代码,它可以工作。所以我想这已经解决了。谢谢你,以及所有其他人的帮助。

以上是关于在弹性项目之间显示一个 div的主要内容,如果未能解决你的问题,请参考以下文章

两个项目之间的弹性空间,但在包装时居中[重复]

使用 'order' 属性在兄弟姐妹之间定位弹性项目

如何动画显示:弹性项目上的无/块属性? [复制]

绝对定位的弹性项目不会从 IE11 中的正常流程中删除

左右对齐弹性项目

如何使用弹性框重新排序 div?