【问题标题】:Is there a way in CSS to make a label get a different property when an input is focused without using JS? [duplicate]当不使用 JS 聚焦输入时,CSS 中有没有办法让标签获得不同的属性? [复制]
【发布时间】:2021-09-09 15:07:57
【问题描述】:

我要做的是在输入字段聚焦时更改标签字体颜色和边框颜色。有没有办法在不使用 JavaScript 的情况下实现这一点?

.input-label {
    display: flex;
    align-items: center;
    height: 16px;
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .1px;
    color: #989898;
    text-transform: uppercase;
}
.form-control{
    display: inline-block;
    max-width: 100%;
    word-wrap: normal;
    background: transparent;
    border: none;
    border-bottom: 2px solid #cacaca;
    color: #4a4a4a;
    font-size: 1.19em;
    height: 35px;
    letter-spacing: .2px;
    padding: 7px 0;
    width: 100%;
    resize: none;
}
input:focus{
  /* after the input is focused the labele font color and border color change to something else*/
}
<div class="firstname">
<label for="name" class="input-label" id="name-label">First Name</label>
<input type="text" class="form-control" id="name" placeholder="First Name" required>
</div>

【问题讨论】:

    标签: html css focus


    【解决方案1】:

    您可以使用:focus-within 伪类:

    如果元素或其任何后代具有焦点,则匹配该元素。

    您可能想通过caniuse.com检查浏览器兼容性是否符合您的要求

    然后像这样创建一个选择器:

        .firstname:focus-within .input-label {
          color: red;
        }
    

    .input-label {
      display: flex;
      align-items: center;
      height: 16px;
      font-weight: 700;
      font-size: 11px;
      letter-spacing: .1px;
      color: #989898;
      text-transform: uppercase;
    }
    
    .form-control {
      display: inline-block;
      max-width: 100%;
      word-wrap: normal;
      background: transparent;
      border: none;
      border-bottom: 2px solid #cacaca;
      color: #4a4a4a;
      font-size: 1.19em;
      height: 35px;
      letter-spacing: .2px;
      padding: 7px 0;
      width: 100%;
      resize: none;
    }
    
    .firstname:focus-within .input-label {
      color: red;
    }
    <div class="firstname">
      <label for="name" class="input-label" id="name-label">First Name</label>
      <input type="text" class="form-control" id="name" placeholder="First Name" required>
    </div>

    或者,您可以将 label 放在 input 之后并使用 CSS 重新排序。

    【讨论】:

    • 非常感谢您的工作,并感谢您解释其工作原理。
    【解决方案2】:

    CSS 没有选择器来爬上 DOM 树,要使用 CSS 来修改另一个被聚焦元素的样式,它必须作为兄弟或父级站在前面。

    但它有flexgridorder 允许在屏幕上重新排序元素,因此您可以重写您的HTML 并将label 设置在input 后面并仍然显示它,打印它在那个输入之前。

    这是一个带有grid 的示例(如果没有另外设置,则构建一个单列网格)order

    .firstname {
      display: grid;
    }
    
    .input-label {
      display: flex;
      align-items: center;
      height: 16px;
      font-weight: 700;
      font-size: 11px;
      letter-spacing: .1px;
      color: #989898;
      text-transform: uppercase;
      order: -1;
    }
    
    .form-control {
      display: inline-block;
      max-width: 100%;
      word-wrap: normal;
      background: transparent;
      border: none;
      border-bottom: 2px solid #cacaca;
      color: #4a4a4a;
      font-size: 1.19em;
      height: 35px;
      letter-spacing: .2px;
      padding: 7px 0;
      width: 100%;
      resize: none;
    }
    
    input:focus+label {
      color: red;
    }
    <div class="firstname">
      <input type="text" class="form-control" id="name" placeholder="First Name" required>
      <label for="name" class="input-label" id="name-label">First Name</label>
    </div>

    https://developer.mozilla.org/en-US/docs/Web/CSS/order

    order CSS 属性将order 设置为在flexgrid 容器中布置项目。容器中的项目按值升序排序,然后按其源代码顺序排序。

    如果您在表单中有两个输入/标签,那么within-focus 是最简单的选择。

    【讨论】:

    • 谢谢@G-Cyrillus
    【解决方案3】:

    所以在 html 中,只需让标签为空,然后将输入放在第一位,然后将标签放在第二位。

    然后这里是 CSS。目标是使用 css 选择器+ 将标签放回第一个位置。

    然后你改变标签 css 的方式:

    /* CSS ADDED */
    .firstname{
      display:flex;
    }
    .firstname > *:last-child {
      order:-1;
    }
    
    input:focus + label{
      color: red;
      border: 3px solid red;
      padding: 5px;
    }
    

    演示:

    .input-label {
        display: flex;
        align-items: center;
        height: 16px;
        font-weight: 700;
        font-size: 11px;
        letter-spacing: .1px;
        color: #989898;
        text-transform: uppercase;
    }
    .form-control{
        display: inline-block;
        max-width: 100%;
        word-wrap: normal;
        background: transparent;
        border: none;
        border-bottom: 2px solid #cacaca;
        color: #4a4a4a;
        font-size: 1.19em;
        height: 35px;
        letter-spacing: .2px;
        padding: 7px 0;
        width: 100%;
        resize: none;
    }
    /* CSS ADDED */
    .firstname{
      display:flex;
      flex-direction: column;
    }
    .firstname > *:last-child {
      order:-1;
    }
    
    input:focus + label{
      color: red;
      border: 3px solid red;
      padding: 5px;
    }
    <div class="firstname">
      <input type="text" class="form-control" id="name" placeholder="First Name" required>
      <label for="name" class="input-label" id="name-label">First Name</label>
    </div>

    【讨论】:

    • label 的目的是携带一些信息。在您的情况下,您可以删除label。如果您建议您的方法,您至少应该展示标签如何保持其用途。 :before:after 的问题在于它们只能用于装饰目的。因此,考虑到可访问性,这将是有问题的。
    • @t.niese 我同意,但是我看错了,因为我以为他想改变标签里面的文字,但他只是想改变标签字体颜色和边框颜色 所以我可以做到但不需要:before:after。现在看看我做了什么
    猜你喜欢
    • 2021-10-14
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2018-12-01
    相关资源
    最近更新 更多