删除一个项目中的内容时,在行上方创建的神秘空间 [英] Mystery space created above row when removing the content inside of one item

查看:98
本文介绍了删除一个项目中的内容时,在行上方创建的神秘空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些网格与一些项目,当我点击任何项目我将该项目的内容移动到模态。



模态的工作伟大,但当我从项目中删除内容,该项目上方会显示一个空格。



我知道解决这个问题的方法可能是使用flexbox,它可以正常工作,但我想了解这里发生了什么。



这里可能关键的是,每个项目有3个孩子。



我在其中两个中使用 position:absolute ,另一个保留默认位置。



如果我在所有儿童中使用 position:absolute ,则问题已解决。



有什么区别?



当我点击项目内容消失时,结果会根据内容而有所不同。



这是一个显示问题的 JSFiddle



基本上,结构如下:



HTML



  ; div class =context> 
< div class =grid>
< div class =item>
< div class =cover> // has position:absolute
< h1>标题< / h1>
< / div>
< div class =img-wrapper> // has position:absolute
< img />
< / div>
< div class =description> //没有定义的位置
< p>说明...< / p>
< / div>
< div class =item>
// item content
< / div>
< / div>
< / div>

我总共有8个项目,每行包含两行,每行4个。 p>

CSS



CSS实现方法如下:

  .grid {
margin-top:100px;
font-size:0; //获取所有项目
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 => {
//缓存模态节点
let $ modal = $('#modal');
b $ b $('。item')。click(function(){
//首先缓存项目和内容
//在需要时将其放回
$ itemNode = $ this);
$ itemContent = $(this).children();

//隐藏项
$ itemNode.css({visibility:'hidden'});

//将项目内容转移到模态
$ itemContent.appendTo($ modal);
});

});


解决方案

解决方案




我知道绕过这个问题的方法可能是使用flexbox ...


这是正确的。使项目的父项成为flex容器解决了问题:

  .grid {
display:flex; / * new * /
flex-wrap:wrap; / * new * /
margin-top:100px;
font-size:0;
border:1px solid red;
}

revised fiddle


这里可能很重要的是每个项目都有3个子项。我在其中两个中使用 position:absolute ,另一个保持默认位置。如果我在所有的孩子中使用 position:absolute ,则问题是固定的。


另外,正确。通过从文档的正常流程中删除第三个div,问题得以解决。



说明





换句话说,在它们的初始状态下,项目的内容(即项目的内容)三个孩子div)正在将每个项目移动到他们将不是的地方。



正如你所怀疑的,问题出现在每个网格项的第三个子div中 .description )。



如果您只是应用 visibility:hidden 到网格项目–



但是用你的脚本,你不仅添加了 visibility:hidden



前两个div( .cover .img-wrapper )永远不会导致问题。它们是绝对定位的,因此它们已经从正常流程中移除了。



但是,第三个div( .description

此div包含两个 p 子X和更多信息)。当这些子项中的任何一个被移除时,是布局中断时



这是因为–因为我还没有确定–这个div在父级上抑制 vertical-align:baseline ,这是一个内联级元素,因此默认设置 vertical-align



当脚本删除div时,基线对齐将恢复到父对象,将其向上移动,从而创建间隙。






编辑:



As @ Kukkuz提到了一个回答,使用除 baseline 之外的值 vertical-align 也解决了问题。


I have a grid with some items, and when I click any item I move the content of that item to a modal.

The modal works great, but when I remove the content from the item, a space appears above the item.

I know that a way around this problem could be using a flexbox, which works fine, but I want to understand what is going on here.

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.

What is the difference?

When I click the item the content disappears, so how can the result be different depending on the content?

Here's a JSFiddle showing the problem.

Basically, the structure is the following:

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>

I have a total of 8 items, that are wrapped in two rows of 4 items each.

CSS

The CSS to achieve that is the following:

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

Note: The JSfiddle example has more CSS for styling, but the base is the same, and the problem still appears with the code above.

JavaScript

Finally, the JS to move the content to the modal div is the following:

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);
  });

});

解决方案

Solutions

I know that a way around this problem could be using a flexbox...

That is correct. Making the parent of the items a flex container solves the problem:

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

Also, correct. By removing the third div from the normal flow of the document, the problem is resolved.

Explanation

Each item in the grid, before any scripting gets involved and items are removed, is artificially positioned.

In other words, in their initial state, the content of the items (the three child divs) are shifting each item to a place where they would otherwise not be. But when the script removes those child divs, each item moves to where it should be.

As you suspected, the problem lies in the third child div of each grid item (.description).

If you simply apply visibility: hidden to the grid item – without removing the child divs – the layout doesn't break.

But with your script, you're not only adding visibility: hidden, you're also removing the child divs.

The first two divs (.cover and .img-wrapper) never cause a problem. They are absolutely positioned, so they're already removed from the normal flow.

However, the third div (.description) is an in-flow child.

This div contains two p children ("Description for this item X" and "More info"). When either of these children is removed, that's when layout breaks.

This is because – for a reason I haven't yet determined – this div was suppressing vertical-align: baseline on the parent, which is an inline-level element and, therefore, gets that vertical-align setting by default.

When the script removes the div, baseline alignment is restored to the parent, shifting it up and, therefore, creating the gap.


EDIT:

As @Kukkuz mentioned an answer, using values other than baseline for vertical-align also solves the problem.

这篇关于删除一个项目中的内容时,在行上方创建的神秘空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆