javascript - 删除一项内的内容时在行上方创建的神秘空间

标签 javascript jquery html css flexbox

我有一个包含一些元素的网格,当我单击任何项​​目时,我将该元素的内容移动到模式。

模式效果很好,但是当我从元素中删除内容时,元素上方会出现一个空格。

我知道解决这个问题的方法是使用 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;
}

revised fiddle

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 use position: 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/

相关文章:

javascript - Bootstrap面板: collapsed on mobile but expanded on desktop,怎么办?

javascript - 初始化函数优化

jquery - 网址已添加到按钮

javascript - 如何访问选项标签

javascript - Raphaël.js 动画 resume() 在设置时失败

javascript - 从一个选择标签中选择一个值后禁用选择值

javascript - jQuery - 如果浏览器选项卡获得焦点,则执行 AJAX - 不起作用

javascript - 带有带有两个参数的 onclick 函数的 HTML 输入字符串 - 不起作用

javascript - 从 HTML 数据 ID 获取 PHP 变量值

html - 仅应用 CSS 的第一个元素?