首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >*在子边界后面的伪元素之前

*在子边界后面的伪元素之前
EN

Stack Overflow用户
提问于 2015-10-20 22:41:50
回答 1查看 2.5K关注 0票数 1

我有一个h1标签,我试图在其中添加一个很酷的动画,边框将从左上角和右下角“增长”。

为此,我将h1封装在两个div中,每个div都有一个::before::after伪元素。

当根div被滑动时,这些div的伪元素将“缩小”,显示下面的边框。

问题是,我的根div的::before伪元素位于边框后面,因此边界立即显示在mouseover上。设置z-index::befores和::afters将修复它;但是,我不想这样做--这是我为复制/粘贴而制作的代码片段。没有设置z-index,所以我很困惑为什么会发生这种情况。

在此之前,除了动画所需的内容之外,我没有任何div,而且它运行得很好--但是这与它有什么关系呢?

这似乎就是问题所在:*在伪元素堆叠顺序问题之前

然而,对于如何解决这一问题,没有人提出任何答案。当然,我可以再加一个第三层,但我想把它作为最后的手段。

问题之谜:https://jsfiddle.net/zppqgn6s/

要使用z-index修复它;要查看它应该是什么样子,请删除第34行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-21 06:36:58

伪元素边框低于子元素的原因:

关于为什么伪元素(:before)背景位于子元素(h1)后面的最初问题的答案可以在BoltClock的答案中找到(您在问题中已经链接过)。实际上,:before伪元素插入在根div (包括h1)的内容之前。

下面是演示中使用的元素的一般结构:

代码语言:javascript
运行
复制
#anim              /* This is the first element inside root and is positioned (relative) */
    #anim:before   /* This is positioned absolutely with respect to the parent */
    div            /* This element is positioned relatively */
        div:before /* This element is positioned absolutely with respect to the div */
        h1         /* This element doesn't have any positioning */
        div:after  /* This element is positioned absolutely with respect to the div */
    #anim:after    /* This is positioned absolutely with respect to the parent */

现在是基于可视呈现层的规范,下面是发生的情况:

代码语言:javascript
运行
复制
#anim              /* Parent element and its background, border gets painted first (Layer 0) */
    #anim:before   /* Positioned descendant, creates stacking context nested within parent (Layer 0.1)*/
    div            /* Positioned descendant of #anim, second child in flow (Layer 0.2) */
        div:before /* Positioned descendant of div, first child in flow (Layer 0.2.2) */
        h1         /* Non positioned, as per Point 3 gets positioned lowest (Layer 0.2.1) */
        div:after  /* Positioned descendant of div, second such child in flow (Layer 0.2.3) */
    #anim:after    /* Positioned descendant of #anim, third child in flow (Layer 0.3) */

可以看到,基于层号(在内联注释中提供),h1元素位于#anim:before上方(但位于产生边框收缩效应的其他三个元素之下)。

解决方案:

唯一的解决方案是在h1元素之后绘制子元素( :before )。这可以通过执行以下任何一项操作来实现(但这两种操作都需要设置z-index ):

  • 使用h1position: relative设置为z-index: -1 (使其落后于#anim:before)
  • z-index: 1 (或更高)设置为#anim:before元素(使其位于h1之上)

替代解决方案/方法:

实际上,对于这个特殊的动画,您不需要所有额外的元素(从左上角和右下角汇合的边框来相见)。它们可以使用单个h1元素本身来实现,我将通过这个答案来说明其中的两个方法。虽然你没有要求其他的方法,但我喜欢效果,这似乎是一个很好的地方张贴这个答案。

通过使用 linear-gradient 背景图像:

在这种方法中,我们为边框的每一侧创建一个渐变(实际上只创建一个实心颜色,因为它不会改变颜色),适当地定位它们,然后将大小从0%转换到100%。对于顶部和底部边框,X轴中的大小应从0%更改为100% on hover,而对于左右边框,Y轴中的大小应从0%更改为100%

代码语言:javascript
运行
复制
h1 {
  position: relative;
  display: inline-block;
  padding: 4px;
  background: linear-gradient(to right, #000, #000), linear-gradient(to right, #000, #000), linear-gradient(to bottom, #000, #000), linear-gradient(to bottom, #000, #000);
  background-position: 0% 0%, 100% 100%, 0% 0%, 100% 100%;
  background-size: 0% 2px, 0% 2px, 2px 0%, 2px 0%;  /* 2px is border thickness */
  background-repeat: no-repeat;
  transition: all 1s;
}
h1:hover {
  background-size: 100% 2px, 100% 2px, 2px 100%, 2px 100%;  /* 2px is border thickness */
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h1>Hover me</h1>
<br>
<h1>How about me?<br>I have dynamic height!</h1>

<div id="wrap">
  <h1>Look at me, I am responsive!!!</h1>
</div>

使用伪元素的

这也可以通过在hover上转换它们的高度和宽度来使用伪元素。你在这里已经走上了正确的道路,但不需要额外的元素。

代码语言:javascript
运行
复制
h1 {
  position: relative;
  display: inline-block;
  padding: 4px;
}
h1:after,
h1:before {
  position: absolute;
  content: '';
  height: 0%;
  width: 0%;
  transition: width 1s, height 1s, border .01s 1s;  /* border has a delay because it should become invisible only after height and width become 0 */
}
h1:before {
  left: 0;
  top: 0;
  border-top: 2px solid transparent;
  border-left: 2px solid transparent;
}
h1:hover:before {
  border-top: 2px solid black;
  border-left: 2px solid black;
}
h1:after {
  bottom: 0;
  right: 0;
  border-right: 2px solid transparent;
  border-bottom: 2px solid transparent;
}
h1:hover:after {
  border-right: 2px solid black;
  border-bottom: 2px solid black;
}
h1:hover:before,
h1:hover:after {
  height: calc(100% - 2px);
  width: calc(100% - 2px);
  transition: width 1s, height 1s, border .01s;  /* border has a shorter duration because it immediately needs to change colors */
}
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h1>Hover me</h1>
<br>
<h1>How about me?<br>I have dynamic height!</h1>

<div id="wrap">
  <h1>Look at me, I am responsive!!!</h1>
</div>

即使添加了额外的div元素(从代码片段中可以看到),这两种方法都可以工作。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33248066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档