【问题标题】:Show a tooltip when the input is invalid输入无效时显示工具提示
【发布时间】:2020-12-11 07:34:30
【问题描述】:

有一个类型为 number 的输入,用户可以在其中写一个数字。如果数字大于 4,它会将输入边框的颜色更改为红色。

我想在相同的情况下显示工具提示,而不是悬停。这是一种方法吗?

<div className="tooltip">
  <input
    className="partial-quantity-input"
    type="number"
    min="0"
    max="4"
    value={quantity}
    onChange={changeValue}
  />
  <span className="tooltiptext">Exceeds original ordered quantity.</span>
</div>

css:

.partial-quantity-input {
  background: rgb(255, 255, 255);
  border-radius: 0px;
  border: 1px solid rgb(255, 255, 255);
  height: 40px;
  width: 40px;
  outline: none;
  &:focus {
    border: 1px solid rgb(201, 200, 200);
  }
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type='number'] {
  -moz-appearance: textfield;
}

input:invalid {
  outline: none;
  border: 1px solid red;
}

.tooltip {
  position: relative;
  display: inline-block;
}

.tooltip .tooltiptext {
  visibility: hidden;
  bottom: 100%;
  left: 50%;
  margin-left: -60px;
  width: 120px;
  color: rgb(0, 0, 0);
  text-align: center;
  padding: 5px 0;
  background: rgb(255, 255, 255);
  border-radius: 3px;
  border: 1px solid rgb(220, 220, 220);
  height: 38px;
  width: 252px;

  /* Position the tooltip */
  position: absolute;
  z-index: 1;
}

.tooltip:hover .tooltiptext {
  visibility: visible;
}

就像在代码中一样,它在悬停时显示工具提示 (.tooltip:hover)。

我尝试了.tooltip:invalid.tooltip(input:invalid),但没有成功。

有什么想法吗?

【问题讨论】:

  • 使用通用兄弟组合器.partial-quantity-input ~ .tooltiptext {display: none;} .partial-quantity-input:invalid ~ .tooltiptext {display:inline;}

标签: javascript html css input tooltip


【解决方案1】:

不使用像 .element1 .element2 这样的组合器(更好的说法是:Descendant Combinator)将使 CSS 查找适合 .element2-selector 的任何元素,该选择器是 .element1 的后代。这意味着,.element2 可以是.element1 的直接或间接子代。
对于您的情况,您应该使用同级组合器 ~ (General Sibling Combinator) 或 + (Adjacent Sibling Combinator) 来选择 .tooltiptext,因为当 input 可以使用 :invalid-selector 选择时。

.tooltip input:invalid ~ .tooltiptext {
  /* Your CSS-rule to make `.tooltiptext` visible */
}

另一种解决方案

为了这个问题,我创建了一个 CSS 工具类 .tooltipped。只需将您的&lt;input&gt; 格式化为如下所示以合并工具提示(括号中的类是需要选择的选项之一):

<div class="tooltipped (top | bottom | left | right)">
  <input />
  <div class="(on-invalid | always)">
    <div>
      <div>
        (Place your content here)
      </div>
    </div>
  </div>
</div>

您在(Place your content here) 中放置的内容可以是一条简单的消息,最多可以是更多的 HTML 代码。简单地插入消息时,您可能希望设置 white-space: pre 以保留其格式,否则它会尝试使工具提示尽可能窄。

由于工具提示是使用position: absolute 放置的,因此您应该确保自己要显示的工具提示在显示时有足够的空间可供阅读。

更改应显示工具提示的一侧与更改 .tooltipped 的方向类一样简单。这甚至可以使用 JavaScript 轻松完成。
例如,当手机可能太小而无法在其初始方向上显示工具提示时,您可以更改方向类。

显然,您可以使输入元素为任何类型。如果您想自己使其无效(例如,当 :invalid 不会触发时),您可以使用 JS 给它类 .invalid,以获得与此工具提示功能相同的效果。

这是一个基本展示所有可用功能的示例:

/* For this example */
html, body {
  margin: 0;
  width: 100%;
  height: 100%;
}
body {
  display: grid;
  grid-template-areas:
    ". ."
    ". .";
  align-items: center;
  justify-items: center;
}
input:invalid {
  border-color: red;
  outline-color: red;
  background: pink;
}

/* Tool-class: Tooltip */
.tooltipped * {margin: 0}
.tooltipped {
  --tt-bg: #3f3f3f;
  display: flex;
  align-items: center;
}
.tooltipped > div {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  visibility: hidden;
}
.tooltipped > div > div {
  position: absolute;
  display: flex;
  align-items: center;
}
.tooltipped > div > div::before {
  content: "";
  border: 4px solid transparent;
}
.tooltipped > div > div > div {
  padding: 0.1rem 0.4rem;
  border-radius: 2px;
  color: white;
  background: var(--tt-bg);
}

/* Directional-classes */
.tooltipped.right > div > div {transform: translateX(50%)}
.tooltipped.right > div > div::before {border-right-color: var(--tt-bg)}

.tooltipped.left {flex-flow: row-reverse}
.tooltipped.left > div {justify-content: flex-end}
.tooltipped.left > div > div {flex-flow: row-reverse}
.tooltipped.left > div > div::before {border-left-color: var(--tt-bg)}

.tooltipped.top {flex-flow: column-reverse}
.tooltipped.top > div > div {
  flex-flow: column-reverse;
  transform: translateY(-50%);
}
.tooltipped.top > div > div::before {border-top-color: var(--tt-bg)}

.tooltipped.bottom {flex-flow: column}
.tooltipped.bottom > div > div {
  flex-flow: column;
  transform: translateY(50%);
}
.tooltipped.bottom > div > div::before {border-bottom-color: var(--tt-bg)}

/* "Listener"-classes */
.tooltipped input:invalid + .on-invalid,
.tooltipped input.invalid + .on-invalid {visibility: visible}

.tooltipped > .always {visibility: visible}
<div class="tooltipped top">
  <input type="number" min="0" max="4"/>
  <div class="on-invalid">
    <div>
      <div>
        <p>I am a tooltip!</p>
      </div>
    </div>
  </div>
</div>

<div class="tooltipped right">
  <input type="number" min="0" max="4"/>
  <div class="always">
    <div>
      <div>
        <p>I am a tooltip!</p>
      </div>
    </div>
  </div>
</div>

<div class="tooltipped bottom">
  <input type="number" min="0" max="4"/>
  <div class="on-invalid">
    <div>
      <div>
        <p>I am a tooltip!</p>
      </div>
    </div>
  </div>
</div>

<div class="tooltipped left">
  <input type="number" min="0" max="4"/>
  <div class="always">
    <div>
      <div>
        <p>I am a tooltip!</p>
      </div>
    </div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    你可以使用JavaScript实现工具提示部分:

    例如:

    let input = document.getElementById("quantity-input");
    let tooltip = document.getElementById("invalid_entry");
    input.addEventListener("keyup", function(e){
      if(e.currentTarget.value.length > 4){
        tooltip.innerHTML = "Exceeded length of 4";
        tooltip.style.display = "block";
        input.style.border = "3px solid red";
      }
      else if(e.currentTarget.value.length <= 4) {
      tooltip.innerHTML = "";
        tooltip.style.display = "none";
        input.style.borderColor = "1px solid black";
      }
    })
    .partial-quantity-input {
      background: rgb(255, 255, 255);
      border-radius: 0px;
      border: 1px solid rgb(255, 255, 255);
      height: 40px;
      width: 40px;
      outline: none;
    
      &:focus {
        border: 1px solid rgb(201, 200, 200);
      }
    }
    
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    input[type='number'] {
      -moz-appearance: textfield;
    }
    
    input:invalid {
      outline: none;
      border: 1px solid red;
    }
    
    .tooltip {
      position: relative;
      display: inline-block;
    }
    
    .tooltip .tooltiptext {
      visibility: hidden;
      bottom: 100%;
      left: 50%;
      margin-left: -60px;
      width: 120px;
      color: rgb(0, 0, 0);
      text-align: center;
      padding: 5px 0;
      background: rgb(255, 255, 255);
      border-radius: 3px;
      border: 1px solid rgb(220, 220, 220);
      height: 38px;
      width: 252px;
    
      /* Position the tooltip */
      position: absolute;
      z-index: 1;
    }
    
    .tooltip:hover .tooltiptext {
      visibility: visible;
    }
    
    #invalid_entry {
      display: none;
      background: orange;
      padding: 6px;
      color: #fff;
      position: absolute;
      left: 20px;
      top: 28px;
    }
    <div className="tooltip">
    <span id="invalid_entry"></span>
      <input
        className="partial-quantity-input"
        id="quantity-input"
        type="number"
        min="0"
        max="4"
      />
      <!-- <span className="tooltiptext">Exceeds original ordered quantity.</span> -->
    </div>

    Fiddle Code

    【讨论】:

    • 您确定它有效吗?我没有看到任何工具提示
    • 这不完全是工具提示,而是一个样式化的 div 来表示类似操作的工具提示
    • 我不知道,但我没有看到任何东西。我正在写一个大于 4 的值,边框变红,仅此而已。没有工具提示或 div
    • invalid_entry 有一个position absolute。您必须根据您的输入字段@JeanPierre 设置lefttop
    猜你喜欢
    • 2018-10-26
    • 2014-07-16
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多