我有一个包含一些元素的网格,当我单击任何项目时,我将该元素的内容移动到模式。
模式效果很好,但是当我从元素中删除内容时,元素上方会出现一个空格。
我知道解决这个问题的方法是使用 flexbox,它工作正常,但我想了解这里发生了什么。
这里可能很关键的一点是每个元素都有 3 个子项。
我在其中两个中使用了 position: absolute
,另一个保持默认位置。
如果我在所有子项中使用 position: absolute
,问题就解决了。
有什么区别?
当我点击元素时,内容消失了,那么结果怎么会因内容而异呢?
这是一个 JSFiddle显示问题。
基本上,结构如下:
HTML
<div class="context">
<div class="grid">
<div class="item">
<div class="cover"> // has position: absolute
<h1>Title</h1>
</div>
<div class="img-wrapper"> // has position: absolute
<img/>
</div>
<div class="description"> // doesn't have a position defined
<p>Description...</p>
</div>
<div class="item">
// item content
</div>
</div>
</div>
我总共有 8 件元素,包裹在两排,每排 4 件。
CSS
实现该目标的 CSS 如下:
.grid {
margin-top: 100px;
font-size: 0; // to get all the items together
border: 1px solid red;
}
.item {
width: calc(100% / 4);
height: 100px;
position: relative;
display: inline-flex;
}
.description {
display: flex;
flex-direction: column;
justify-content: space-around;
top: 0;
bottom: 0;
}
.img-wrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
img {
height: 100%;
width: auto;
display: block;
margin: auto;
}
.cover {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
注意:JSfiddle的例子有更多的样式CSS,但是基础是一样的,问题还是出现在上面的代码中。
JavaScript
最后,将内容移动到模态div的JS如下:
let $itemNode;
let $itemContent;
$().ready(args => {
// Cache the modal node
let $modal = $('#modal');
$('.item').click(function() {
// First cache the item and content
// to put it back when needed
$itemNode = $(this);
$itemContent = $(this).children();
// Hides the item
$itemNode.css({visibility: 'hidden'});
// Transfer project content to the modal
$itemContent.appendTo($modal);
});
});
最佳答案
解决方案
I know that a way around this problem could be using a flexbox...
没错。将元素的父级设置为 flex 容器可以解决问题:
.grid {
display: flex; /* new */
flex-wrap: wrap; /* new */
margin-top: 100px;
font-size: 0;
border: 1px solid red;
}
Something that could be key here is that each item has 3 children. I use
position: absolute
in two of them, and the other one stays with the default position. If I useposition: absolute
in all the children, the problem is fixed.
另外,正确。通过从文档的正常流中删除第三个 div,问题得到解决。
解释
在涉及任何脚本和删除元素之前,网格中的每个元素都是人工定位的。
换句话说,在它们的初始状态下,元素的内容(三个子 div)正在将每个元素移动到它们原本不会出现的位置。但是当脚本删除这些子 div 时,每个元素都会移动到它应该在的位置。
如您所料,问题出在每个网格项 (.description
) 的第三个子 div 中。
如果您只是将 visibility: hidden
应用到网格项 – 而不删除子 div – 布局不会中断。
但是对于您的脚本,您不仅要添加 visibility: hidden
,还要删除子 div。
前两个 div(.cover
和 .img-wrapper
)永远不会造成问题。它们是绝对定位的,因此它们已经从正常流中移除。
但是,第三个 div (.description
) 是流入子元素。
此 div 包含两个 p
子项(“此元素 X 的说明”和“更多信息”)。当这些子项中的任何一个被移除时,布局就会中断。
这是因为——出于某种我尚未确定的原因——这个 div 抑制了父级上的 vertical-align: baseline
,这是一个内联级元素,因此是 gets that vertical-align
setting by default 。
当脚本删除 div 时,基线对齐将恢复到父级,将其向上移动,从而产生间隙。
编辑:
如 @Kukkuz mentioned an answer ,为 vertical-align
使用 baseline
以外的值也可以解决问题。
关于javascript - 删除一项内的内容时在行上方创建的神秘空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39791663/