CSS 盒子/阴影重叠问题 z-index

14

请查看此代码片段:http://codepen.io/anon/pen/JItLa

我试图显示两行方块,每行方块数量不同。鼠标悬停事件应该会显示 CSS 阴影,但是出现了一个问题:阴影的右边框与下一个方块重叠。 你可能会说这里的解决方案是使用 display:inline-block 来留出方块之间的间隙,但我不需要这些间隙。这些方块应该黏在一起,但右侧阴影应该在悬停时覆盖到下一个方块上。

html,
body {
  margin: 0;
  padding: 0
}
.wrapper {
  width: 100%;
  margin-top: 20px
}
.tile,
.tile2 {
  float: left;
  background: #f2f2f2
}
.tile {
  width: 25%
}
.tile2 {
  width: 33.3%;
  border-left: 1px solid #ddd
}
.tile:hover,
.tile2:hover {
  -webkit-box-shadow: 0 0 2px rgba(255, 255, 190, .75), 0 0 23px 1px #000;
  -moz-box-shadow: 0 0 2px rgba(255, 255, 190, .75), 0 0 23px 1px #000;
  box-shadow: 0 0 2px rgba(255, 255, 190, .75), 0 0 23px 1px #000
}
.header {
  padding: 20px 0px 10px;
  text-align: center
}
.clear {
  clear: both
}
<div class="wrapper">
  <div class="tile">
    <div class="header">some text</div>
  </div>
  <div class="tile">
    <div class="header">some text</div>
  </div>
  <div class="tile">
    <div class="header">some text</div>
  </div>
  <div class="tile">
    <div class="header">some text</div>
  </div>
  <div class="clear"></div>
</div>
<div class="wrapper">
  <div class="tile2">
    <div class="header">some text</div>
  </div>
  <div class="tile2">
    <div class="header">some text</div>
  </div>
  <div class="tile2">
    <div class="header">some text</div>
  </div>
  <div class="clear"></div>
</div>

怎么可能实现呢?

这里还有另一个问题:当我在块之间添加边框时,最后一个块移到了下一行,这是不好的。请参见上面给出的示例中的第2行。

3个回答

23

当悬停时,向元素添加z-index。此外,为了让z-index属性生效,该元素还必须定位。因此也需要添加position:relative

9.9.1 指定堆叠水平:'z-index' 属性

z-index: 应用于:定位元素

每个盒子在三个维度上都有一个位置。除了它们的水平和垂直位置之外,盒子沿着“z轴”排列,并且一个在另一个之上格式化。当盒子在视觉上重叠时,z轴位置特别相关。本节将讨论如何沿z轴定位盒子。

更新的Codepen - 现在可用。

.tile:hover, .tile2:hover {
    z-index: 1;
    position: relative;
}
为了解决您的第二个问题,元素出现在新行是因为它们的宽度不相等,这是由于边框造成了1px的偏差。

33.3% + 33.3% + 33.3% + 1px != 100%

您有几种选择:

  • 使用calc()减去宽度中的1px- width: calc(33.3% - 1px)

  • 将盒模型更改为包括元素的边框在宽度计算中-box-sizing

如果您选择使用box-sizing,则需要适当的厂商前缀以获得所有浏览器的支持。我建议使用类似于以下内容:

.tile2 {
    width: 33.3%;
    border-left: 1px solid #ddd;
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
}

更新的Codepen使用了box-sizing


2
非常感谢!这个方法很有效。我之前一直在试用z-index,但是不起作用。看起来'position:relative'非常好用。但是我不理解它的工作原理。如果您能够解释一下它的运作方式,我将不胜感激。我不仅想要复制/粘贴解决方案,更想了解它的起源。提前致谢。 - Andreas
@Andreas 好的,我更新了我的回答。根据W3的说法,z-index属性仅适用于DOM中定位的元素。至于原因,我只能猜测是因为该元素不存在于三维空间中,因为它没有被定位。因此,z-index没有任何效果。 - Josh Crozier
2
非常感谢您。我尝试了仅使用z-index,但当然它没有起作用。您刚刚解决了这里的许多问题。 :) - andreszs

0

在这里,我只是想为@Josh Crozier的答案提供一些额外的信息 - 我仍然认为他们的答案是正确的。

如果您没有将background-color或其他background样式设置到您希望置于顶部的项目上,并使用z-index,那么它就无关紧要了。

顺便说一下 - 如果我的CSS看起来很奇怪,那是因为我正在使用less.js的某些部分。

nav {
    .flex-column;
    padding: 5px;
    height: 100vh;
    width: fit-content;
    /**Could alternatively add a background-color here in lieu or 
    addition to the footer element below**/
}

footer {
    height: 1.5rem;
    position: fixed;
    bottom: 0px;
    width: 100%;
    font-size: 0.75rem;
    align-items: center;
    justify-content: center;
    z-index: 1;
    background-color: var(--background); //If this is not set, then they still show the crossing box-shadows
    .flex-row;
    .box-shadows;
}

.box-shadows {
    box-shadow: var(--boxShadow);
    -webkit-box-shadow: var(--boxShadow);
    -moz-box-shadow: var(--boxShadow);
}

:root {
    --background: #008080;
    --foreground: #ffffff;
    --boxShadow: inset 0px 0px 0px 1px #000000;
}

0

如果您不需要div之间的间隙,请添加以下CSS样式。

.wrapper {
  text-align: center;
  font-size: 0px;
}
.tile,
.tile2 {
  display: inline-block;
}
.tile:hover,
.tile2:hover {
  z-index: 1;
  position: relative;
}
.header {
  font-size: 12px;
}
`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接