为什么工具提示动画适用于标签而不适用于输入

Why does tooltip animation work with labels but not inputs

我正在尝试使用 this 动画为我的输入设置工具提示动画。谁能告诉我为什么它不起作用。

/* setup tooltips */

.tooltip {
  position: relative;
}

.tooltip:before,
.tooltip:after {
  display: block;
  opacity: 0;
  pointer-events: none;
  position: absolute;
}

.tooltip:after {
  border-right: 6px solid transparent;
  border-bottom: 6px solid rgba(0, 0, 0, .75);
  border-left: 6px solid transparent;
  content: '';
  height: 0;
  top: 20px;
  left: 20px;
  width: 0;
}

.tooltip:before {
  background: rgba(0, 0, 0, .75);
  border-radius: 2px;
  color: #fff;
  content: attr(data-title);
  font-size: 14px;
  padding: 6px 10px;
  top: 26px;
  white-space: nowrap;
}


/* the animations */


/* fade */

.tooltip.fade:after,
.tooltip.fade:before {
  transform: translate3d(0, -10px, 0);
  transition: all .15s ease-in-out;
}

.tooltip.fade:hover:after,
.tooltip.fade:hover:before {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}


/* expand */

.tooltip.expand:before {
  transform: scale3d(.2, .2, 1);
  transition: all .2s ease-in-out;
}

.tooltip.expand:after {
  transform: translate3d(0, 6px, 0);
  transition: all .1s ease-in-out;
}

.tooltip.expand:hover:before,
.tooltip.expand:hover:after {
  opacity: 1;
  transform: scale3d(1, 1, 1);
}

.tooltip.expand:hover:after {
  transition: all .2s .1s ease-in-out;
}


/* swing */

.tooltip.swing:before,
.tooltip.swing:after {
  transform: translate3d(0, 30px, 0) rotate3d(0, 0, 1, 60deg);
  transform-origin: 0 0;
  transition: transform .15s ease-in-out, opacity .2s;
}

.tooltip.swing:after {
  transform: translate3d(0, 60px, 0);
  transition: transform .15s ease-in-out, opacity .2s;
}

.tooltip.swing:hover:before,
.tooltip.swing:hover:after {
  opacity: 1;
  transform: translate3d(0, 0, 0) rotate3d(1, 1, 1, 0deg);
}


/* basic styling: has nothing to do with tooltips: */

body,
div {
  width: 100%;
  padding: 0px;
  margin: 0px;
}

div h1 {
  padding: 10px;
}

ul {
  margin-bottom: 40px;
}

li {
  cursor: pointer;
  display: inline-block;
  padding: 0 10px;
}
<div>
  <h1 class="tooltip fade" data-title="Works with headers">Header (Fade)</h1>
  <h1 class="tooltip expand" data-title="Works with headers">Header (Expand)</h1>
  <h1 class="tooltip swing" data-title="Works with headers">Header (Swing)</h1>
</div>

<div>
  <p class="tooltip fade" data-title="Works with headers">Paragraph (Fade)</p>
  <p class="tooltip expand" data-title="Works with headers">Paragraph (Expand)</p>
  <p class="tooltip swing" data-title="Works with headers">Paragraph (Swing)</p>
</div>

<div>
  <input class="tooltip fade" data-title="Works with headers" value='Paragraph (Fade)'>
  <input class="tooltip expand" data-title="Works with headers" value='Paragraph (Expand)'>
  <input class="tooltip swing" data-title="Works with headers" value='Paragraph (Swing)'>
</div>

<input> 元素也称为 self-closing or empty 元素。这意味着他们没有(也不能)有 children,影子 DOM 是一个特殊的例外。

这意味着 ::before::after 伪元素不会被放置在输入元素内,因为它们也可以被视为 children,尽管不是实际节点.

一个解决方案是在输入周围创建一个 <div> tooltip class。

/* setup tooltips */

.tooltip {
  position: relative;
}

.tooltip:before,
.tooltip:after {
  display: block;
  opacity: 0;
  pointer-events: none;
  position: absolute;
}

.tooltip:after {
  border-right: 6px solid transparent;
  border-bottom: 6px solid rgba(0, 0, 0, .75);
  border-left: 6px solid transparent;
  content: '';
  height: 0;
  top: 20px;
  left: 20px;
  width: 0;
}

.tooltip:before {
  background: rgba(0, 0, 0, .75);
  border-radius: 2px;
  color: #fff;
  content: attr(data-title);
  font-size: 14px;
  padding: 6px 10px;
  top: 26px;
  white-space: nowrap;
}


/* the animations */


/* fade */

.tooltip.fade:after,
.tooltip.fade:before {
  transform: translate3d(0, -10px, 0);
  transition: all .15s ease-in-out;
}

.tooltip.fade:hover:after,
.tooltip.fade:hover:before {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}


/* expand */

.tooltip.expand:before {
  transform: scale3d(.2, .2, 1);
  transition: all .2s ease-in-out;
}

.tooltip.expand:after {
  transform: translate3d(0, 6px, 0);
  transition: all .1s ease-in-out;
}

.tooltip.expand:hover:before,
.tooltip.expand:hover:after {
  opacity: 1;
  transform: scale3d(1, 1, 1);
}

.tooltip.expand:hover:after {
  transition: all .2s .1s ease-in-out;
}


/* swing */

.tooltip.swing:before,
.tooltip.swing:after {
  transform: translate3d(0, 30px, 0) rotate3d(0, 0, 1, 60deg);
  transform-origin: 0 0;
  transition: transform .15s ease-in-out, opacity .2s;
}

.tooltip.swing:after {
  transform: translate3d(0, 60px, 0);
  transition: transform .15s ease-in-out, opacity .2s;
}

.tooltip.swing:hover:before,
.tooltip.swing:hover:after {
  opacity: 1;
  transform: translate3d(0, 0, 0) rotate3d(1, 1, 1, 0deg);
}

.row {
  display: flex;
}

/* basic styling: has nothing to do with tooltips: */

body,
div {
  width: 100%;
  padding: 0px;
  margin: 0px;
}

div h1 {
  padding: 10px;
}

ul {
  margin-bottom: 40px;
}

li {
  cursor: pointer;
  display: inline-block;
  padding: 0 10px;
}
<div>
  <h1 class="tooltip fade" data-title="Works with headers">Header (Fade)</h1>
  <h1 class="tooltip expand" data-title="Works with headers">Header (Expand)</h1>
  <h1 class="tooltip swing" data-title="Works with headers">Header (Swing)</h1>
</div>

<div>
  <p class="tooltip fade" data-title="Works with headers">Paragraph (Fade)</p>
  <p class="tooltip expand" data-title="Works with headers">Paragraph (Expand)</p>
  <p class="tooltip swing" data-title="Works with headers">Paragraph (Swing)</p>
</div>

<div class="row">
  <div class="tooltip fade" data-title="Works with headers">
    <input value='Paragraph (Fade)'>
  </div>
  <div class="tooltip expand" data-title="Works with headers">
    <input value='Paragraph (Expand)'>
  </div>
  <div class="tooltip swing" data-title="Works with headers">
    <input value='Paragraph (Swing)'>
  </div>
</div>