在悬停一个伪元素时,让另一个伪元素出现?

Posted

技术标签:

【中文标题】在悬停一个伪元素时,让另一个伪元素出现?【英文标题】:On hovering one pseudo element, make the other pseudo element appear? 【发布时间】:2015-06-18 12:55:14 【问题描述】:

我试图生成一个使用 :before:after 伪元素的屏幕,但我想知道这样的功能是否真的可行。

我有一个包装器 div,它包装在输入周围(允许在此包装器上使用 pseudo elements)。

类似:

+-----------------------------------+
| +-------------------------------+ |
| |                               | | <-- wrapper div
| +-------------------------------+ <-- input element
+-----------------------------------+

但是,我希望在 div 之后放置一个伪元素。

+-----------------------------------++-------+
| +-------------------------------+ | |¯¯¯|  |
| |                               | |    /   |
| +-------------------------------+ |   !    |<--pseudo element
+-----------------------------------++-------+

我希望能够悬停这个伪元素,并让另一个伪元素出现。

.wrap 
  position: relative;
  height: 30px;
  width: 200px;
  display: inline-block;

.wrap input 
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;

.wrap:after 
  content: "?";
  position: absolute;
  top: 0;
  left: 100%;
  height: 30px;
  width: 30px;
  font-size: 30px;
  text-align: center;

.wrap:before 
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  height: 60px;
  width: 100%;
  background: tomato;
  opacity:0.2;
<div class="wrap">
  <input placeholder="input element" type="text" />
</div>

从上面的 sn-p 设计中,当我只悬停 :after 元素而不是 wrap div 本身时,有没有办法使 :before 元素改变其不透明度(注意:html 无法更改,所以为什么要问这个问题)?


我尝试使用类似的东西:

.wrap:not(input):hover:before

将输入的宽度更改为90%后,但这并没有什么不同

【问题讨论】:

一个有趣的例子,让伪元素算作简单的选择器,所以可以做类似.wrap:has(::after:hover)::before 的事情。但是唉…… @BoltClock ::after:hover 在选择器级别 4 中有效吗?如果我没记错的话,伪元素不能有伪类...... @Hashem Qolami:它处于第 4 级。它取决于伪元素和伪类——有些组合是可能的,而另一些则不是。请参阅dev.w3.org/csswg/selectors-4/#pseudo-elements,它说“伪元素是无特征的,因此不能被任何其他选择器匹配。它们也不影响结构伪类的解释,这些伪类仅基于真实元素进行评估。其他伪-classes 可以匹配伪元素,除非另有说明。" 我能做到的最接近的方法是将父元素的pointer-events 设置为none,然后将:before 重置为initial。然后您可以在父级上使用:hover:after,它会在:before 伪元素悬停时触发。这种情况下的缺点是,要使input 可用,您还需要重置它的pointer-events,这意味着它也会触发父级的:hover。你愿意使用额外的标记吗? @Raptor:如果 OP 在其原始问题中使用 :before 和 :after 之类的伪元素,您通常可以假设他们对支持 IE7 不感兴趣,除非他们另有说明。 【参考方案1】:

我知道这并不完全符合您的要求,但在 css 可以选择父母(即将到来)之前,您可以再添加一个 html 元素:

<div class="wrap">
    <div class="inner_wrap">
      <input placeholder="input element" type="text" />
    </div>
</div>

css:

.wrap 
  position: relative;
  height: 30px;
  width: 200px;
  display: inline-block;

.wrap input 
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;

.wrap:after 
  content: "?";
  position: absolute;
  top: 0;
  left: 100%;
  height: 30px;
  width: 30px;
  font-size: 30px;
  text-align: center;

.inner_wrap:before 
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  height: 60px;
  width: 100%;
  background: tomato;
  opacity:0.2;
    display:none;

.wrap:hover .inner_wrap:before
    display:block;

.wrap .inner_wrap:hover:before
    display:none;

http://fiddle.jshell.net/0vwn1w9t/

【讨论】:

【参考方案2】:

似乎因为伪元素不是“真实”元素,这意味着(当前)不能以这种方式使用。相反,使用“真实”元素将允许这样做,因此我选择使用 span 元素,直到此功能可能实现也可能不实现。

当前实现显示:

input 
  position: relative;
  display: inline-block;
  height: 30px;
  vertical-align: top;

span 
  position: relative;
  height: 30px;
  width: 30px;
  display: inline-block;
  text-align: center;
  border-radius: 50%;
  font-size: 25px;
  line-height: 30px;
  background: tomato;

span:after 
  content: "A Question Mark";
  position: relative;
  display: inline-block;
  top: 0;
  left: 0;
  height: 60px;
  width: 100px;
  background: tomato;
  opacity: 0;
  transition: all 0.8s;
  font-size: 16px;

span:hover:after 
  opacity: 1;
<input placeholder="input element" type="text" />
<span>?</span>

令我心爱的伪元素设计大失所望。

【讨论】:

以上是关于在悬停一个伪元素时,让另一个伪元素出现?的主要内容,如果未能解决你的问题,请参考以下文章

防止伪元素触发悬停?

如何调试悬停等伪元素?

CSS:如果 Last-Child <li> 悬停,如何影响:伪元素之后?

溢出:隐藏不适用于 Chrome 中的伪元素

CSS 伪元素的一些罕见用例

css伪类和伪元素