【CSS】几种好用的选择器

1. :focus-within

现有一段代码,期望input在聚焦时边框变为蓝色并将其父元素背景色变灰

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      font-size: 18px;
    }

    .row {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      margin-bottom: 20px;
      padding: 10px;
    }

    .ipt {
      width: 200px;
      height: 30px;
      border: 1px solid #ccc;
      outline: none;
    }

    .ipt:focus {
      border-color: #0052D9;
    }

    .row:focus {
      background: #eee;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="row">
      <span>姓名</span>
      <input class="ipt" type="text">
    </div>
    <div class="row">
      <span>年龄</span>
      <input class="ipt" type="text">
    </div>
    <div class="row">
      <span>性别</span>
      <input class="ipt" type="text">
    </div>
  </div>
  </div>
</body>

</html>

实际结果是只有input聚焦时边框变蓝,其父元素背景色并未改变,这是因为当前聚焦的并非父元素,而是它的后代元素。

可以使用 JS 监控 input 的聚焦事件,并手动修改其父元素的样式。

但也可以直接使用 CSS伪类选择器,它表示当自己或后代元素聚焦时的样式。

.row:focus-within {
  background: #eee;
}

2. :has()

继续使用上面案例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      font-size: 18px;
    }

    .row {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      margin-bottom: 20px;
      padding: 10px;
    }

    .ipt {
      width: 200px;
      height: 30px;
      border: 1px solid #ccc;
      outline: none;
    }

    .ipt:focus {
      border-color: #0052D9;
    }

    .row:focus-within {
      background: #eee;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="row">
      <span>姓名</span>
      <input class="ipt" type="text">
    </div>
    <div class="row">
      <span>年龄</span>
      <input class="ipt" type="text">
    </div>
    <div class="row">
      <span>性别</span>
      <input class="ipt" type="text">
    </div>
  </div>
  </div>
</body>

</html>

如果要在必填项添加红色标识,可以使用 ::after

.row span::after {
  content: '*';
  color: red;
}

可以追加伪类 :has() 约束哪些项需要显示必填项标识,如:该元素的下一个元素包含自定义属性 ipt-required 的。

  • + :表示下一个兄弟元素
  • input:为input类型
  • [ipt-required] :属性名为ipt-required
// css
.row span:has(+input[ipt-required])::after {
  content: '*';
  color: red;
}

// html
<div class="container">
  <div class="row">
    <span>姓名</span>
    <input ipt-required class="ipt" type="text">
  </div>
  <div class="row">
    <span>年龄</span>
    <input ipt-required class="ipt" type="text">
  </div>
  <div class="row">
    <span>性别</span>
    <input class="ipt" type="text">
  </div>
</div>

在这里插入图片描述

3. ::first-letter

首字母下沉的效果无需更改 html(单独封装首字母样式),可以通过 ::first-letter 直接修改首字母样式。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      font-family: 'Arial', sans-serif;
      line-height: 1.5;
      margin: 0;
      padding: 20px;
      background-color: #f4f4f4;
      color: #333;
    }

    .container {
      margin: auto;
      background: #fff;
      padding: 20px;
      border-radius: 5px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }

    p::first-letter {
      font-size: 3em;
      font-weight: bold;
      text-transform: uppercase;
      float: left;
      margin-right: 10px;
      line-height: 1;
    }
  </style>
</head>

<body>
  <div class="container">
    <p>In the past, I was a humble servant of the state, and I had the great honor of serving under the great Lord Liu
      Bei. He entrusted me with the affairs of the kingdom and treated me with kindness, which I will never forget. When
      he passed away, I took on the burden of the state with the utmost seriousness.

      Now, the Han dynasty has been in turmoil for many years, and the enemies have grown stronger. We are faced with a
      critical moment, and I can no longer delay in taking action. The people have suffered greatly, and the country is
      in a dire state. Therefore, I propose that we mobilize our forces and march to the north to restore order and
      peace.

      My plan is to gather all available resources, prepare the troops, and strategize effectively for the campaign. I
      deeply regret that I may not have the strength to complete this task, but I must try my utmost to serve the state
      and protect our people. I implore the Emperor to consider the situation and support this endeavor.

      I am aware that my humble efforts may not be sufficient to achieve victory, but I am willing to sacrifice my life
      for the sake of the country. The loyalty of the ministers and the strength of our soldiers are crucial for the
      success of this campaign.

      In conclusion, I ask for your support and approval for this expedition. Let us unite our strength to face the
      challenges ahead and bring peace back to our land.</p>
  </div>
</body>

</html>

在这里插入图片描述

4. ::selection

控制选中的文字的样式,在上例基础上添加 ::selection 伪类选择器

p::selection {
  background: #333;
  color: #fff;
  text-decoration: underline;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田本初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值