我有一个带有一些项目的网格,当我点击任何项目时,我将该项目的内容移动到模态。
模态效果很好,但是当我从项目中删除内容时,项目上方会出现一个空格。
我知道解决这个问题的方法可能是使用flexbox,它工作正常,但我想了解这里发生了什么。
这里可能关键的是每个项目有3个孩子。
我在其中两个中使用position: absolute
,另一个使用默认位置。
如果我在所有孩子中使用position: absolute
,问题就解决了。
有什么区别?
当我点击该项目时内容消失,那么结果如何根据内容而有所不同?
这是显示问题的JSFiddle。
基本上,结构如下:
<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如下:
.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,但基础相同,问题仍然出现在上面的代码中。
最后,将内容移动到模态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);
});
});
答案 0 :(得分:3)
使用vertical-align: top
到item
,当任何项目的内容为空时,您可以摆脱神秘空间。发生这种情况是因为grid
项目是inline
(inline-flex)。
请注意
vertical-align
适用于所有内嵌级和表格单元格 元素和用于垂直对齐内联级别元素 - 请参阅 文件 JURI::base()
将inline-flex
更改为inline-block
,您可以看到相同的行为。在下面的代码段中切换vertical-align
并自行检查:
.context {
text-align: center;
height: 400px;
border: 1px solid black;
}
#modal {
display: none
}
.grid {
margin-top: 100px;
font-size: 0;
border: 1px solid red;
}
.item {
width: calc(100% / 4);
height: 100px;
transform-origin: center;
position: relative;
display: inline-flex;
transition: box-shadow .3s, transform .3s;
font-size: 1em;
vertical-align: top;
}
.description {
display: flex;
flex-direction: column;
justify-content: space-around;
top: 0;
bottom: 0;
z-index: 100;
opacity: 0;
background-color: rgba(0, 0, 0, 0.6);
color: white;
padding: 20px;
transition: opacity .3s;
}
.img-wrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: white;
}
img {
height: 100%;
width: auto;
display: block;
margin: auto;
}
.cover {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
z-index: 1000;
cursor: pointer;
opacity: 1;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
text-align: center;
color: white;
transition: transform .3s, opacity .3s;
}
.cover-red {
background-color: #ff9f80;
}
.cover-green {
background-color: #66cc66;
}
.cover-blue {
background-color: #809fff;
}
.cover-yellow {
background-color: #ffff80;
}
.cover-mag {
background-color: hsl(338, 95%, 70%);
}
.cover-cyan {
background-color: hsl(214, 100%, 65%);
}
.item:hover {
box-shadow: 0 0 6px 3px rgba(0, 0, 0, 0.3);
z-index: 1100;
transform: scale(1.02);
}
.item:hover .cover {
opacity: 0
}
<div class="context">
<div class="grid">
<div class="item">
</div>
<div class="item">
<div class="cover cover-cyan">
<h1>Title 2</h1>
</div>
<div class="img-wrapper">
<img src="http://rs415.pbsrc.com/albums/pp236/Keefers_/Keffers%20Animals/funny-cats-a10.jpg~c200">
</div>
<div class="description">
<p>Description for item 2</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-mag">
<h1>Title 3</h1>
</div>
<div class="img-wrapper">
<img src="http://i1.kym-cdn.com/entries/icons/original/000/007/203/nononocat.jpg">
</div>
<div class="description">
<p>Description for item 3</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-green">
<h1>Title 4</h1>
</div>
<div class="img-wrapper">
<img src="https://media0.giphy.com/media/3o85xoi6nNqJQJ95Qc/200_s.gif">
</div>
<div class="description">
<p>Description for item 4</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-cyan">
<h1>Title 5</h1>
</div>
<div class="img-wrapper">
<img src="https://media0.giphy.com/media/o0vwzuFwCGAFO/200_s.gif">
</div>
<div class="description">
<p>Description for item 5</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-green">
<h1>Title 6</h1>
</div>
<div class="img-wrapper">
<img src="http://cdn.thecatsite.com/3/37/200x200px-ZC-379ffbad_anime-cat-cute-cuteness-overload-kitten-Favim_com-350157_large.jpeg">
</div>
<div class="description">
<p>Description for item 6</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-red">
<h1>Title 7</h1>
</div>
<div class="img-wrapper">
<img src="http://www.officialstarwarscostumes.com/~/media/products/oc/yoda-costumes/pet-yoda-costumes/9935319-yoda-cat-hood-pet-star-wars-costumes-000.ashx?w=200&h=200&bc=ffffff">
</div>
<div class="description">
<p>Description for item 7</p>
<p>More info</p>
</div>
</div>
<div class="item">
<div class="cover cover-mag">
<h1>Title 8</h1>
</div>
<div class="img-wrapper">
<img src="http://adst.org/wp-content/uploads/2014/02/cat-general-120-3-_tplq-200x200.jpg">
</div>
<div class="description">
<p>Description for item 8</p>
<p>More info</p>
</div>
</div>
</div>
<div id="modal">
</div>
</div>
我使用inline-block
创建了一个演示相同行为的演示。这是内联元素的一般行为 - 见下文:
.wrapper {
border: 1px solid;
}
.wrapper > * {
display: inline-block;
border: 1px solid;
height: 100px;
width: 100px;
}
<div class="wrapper">
<div></div>
<div>
<h1>kjk</h1>
</div>
</div>
答案 1 :(得分:3)
我知道解决这个问题的方法可能是使用flexbox ......
这是正确的。使项目的父项成为Flex容器可以解决问题:
.grid {
display: flex; /* new */
flex-wrap: wrap; /* new */
margin-top: 100px;
font-size: 0;
border: 1px solid red;
}
这里可能关键的是每个项目有3个孩子。我在其中两个中使用
position: absolute
,另一个使用默认位置。如果我在所有孩子中使用position: absolute
,问题就解决了。
另外,正确。通过从文档的正常流中删除第三个div,问题得以解决。
在涉及任何脚本并删除项目之前,网格中的每个项目都是人为定位的。
换句话说,在他们的初始状态中,项目的内容(三个孩子div)正在将每个项目转移到他们原本不会的地方。但是当脚本删除那些子div时,每个项目都移动到它应该的位置。
如您所料,问题在于每个网格项的第三个子div(.description
)。
如果您只是将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,baseline
使用vertical-align
以外的值也可以解决问题。
答案 2 :(得分:0)
这是因为使用visibility:hidden
,visibility:hidden
仅隐藏元素的可见性,而元素仍然获取空间,您应该使用display:none;
而不是visibility:hidden