技术实践

掌握有用的 CSS 伪类

CSS 伪类是一个选择器,它指定所选元素的特定状态。例如: hover 允许开发人员在元素悬停时锁定状态

羊先生的头像
羊先生2021.05.23 · 3 分钟阅读 · 69 阅读
掌握有用的 CSS 伪类封面
文章正文还需 3 分钟

什么是CSS伪类

CSS 伪类是一个选择器,它指定所选元素的特定状态。例如: hover 允许开发人员在元素悬停时锁定状态

下面的一些伪类可能大家都用到过,我们可以从中学习一些开发的技巧

Hover旋转

效果

html 复制代码
HTML CSS JSResult Skip Results Iframe
EDIT ON
<div class="hover-container">
  <img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=1953&q=80" class="img" />
  <div class="overlay"></div>
</div>
<div class="hover-container">
  <img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=1953&q=80" class="img" />
  <div class="overlay"></div>
</div>
css 复制代码
.hover-container {
  height: max-content;
  width: max-content;
  position: relative;
  margin: 12px 24px;
}

.overlay,
.hover-container::after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

/* Without the ::after on hovering would trigger .overlay:hover and not .hover-container:hover */
.hover-container::after {
  content: "";
}

/* Additional Styling */
* {
  transition: 0.1s;
}

html,
body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 0;
  margin: 0;
}

.img {
  display: inline-block;
  height: 200px;
}
js 复制代码
document.querySelectorAll(".hover-container").forEach((container) => {
  container.onmouseleave = (e) => {
    const overlayChild = e.target.querySelector(".overlay");

    e.target.style.transform = "rotateY(0) rotateX(0)";
    overlayChild.style.background = "transparent";
    overlayChild.style.borderImage = "none";
  };

  container.addEventListener("mousemove", (e) => {
    const rect = e.target.getBoundingClientRect();
    const x = e.clientX - rect.left; //x position within the element.
    const y = e.clientY - rect.top; //y position within the element.
    const width = e.target.offsetWidth;
    const height = e.target.offsetHeight;

    const overlayChild = e.target.querySelector(".overlay");

    e.target.style.transform = `rotateY(${
      -(0.5 - x / width) * 30
    }deg) rotateX(${(y / height - 0.5) * 30}deg)`;

    overlayChild.style.background = `radial-gradient(
        circle at ${x}px ${y}px,
        rgba(255, 255, 255, 0.2),
        rgba(0, 0, 0, 0.2)
      )`;
    overlayChild.style.borderImage = `radial-gradient(
            20% 75% at ${x}px ${y}px,
            rgba(255, 255, 255, 0.7),
            rgba(0, 0, 0, 0.2)
        )
        1 / 1px / 0px stretch`;
  });
});

Focus

: focus 用于在用户选择元素时选择该元素的状态。要使用这个伪类,您需要一个可选择的组件,如按钮或输入,或者使用 tabindex 手动将其转换为可制表符的元素

html 复制代码
<input type="text" placeholder="Select Me..." />
css 复制代码
input:focus {
  background-color: #bbb;
}

/* Additional styling */
input {
  background-color: #ddd;
  display: block;
  width: 240px;
  margin: 12px 0;
  padding: 12px 16px;
  border-radius: 20px;
  border: none;
  outline: none !important;
  transition: 0.1s;
}

html,
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
}

Checked

效果

html 复制代码
<form action="">
  <span>
    <label for="male">Male</label>
    <input type="radio" value="male" name="gender" id="male" />
  </span>
  <span>
    <label for="female">Female</label>
    <input type="radio" value="female" name="gender" id="female" />
  </span>
  <span>
    <label for="bike">I have a bike</label>
    <input type="checkbox" value="Bike" id="bike" />
  </span>
  <span>
    <label for="car">I have a car</label>
    <input type="checkbox" value="Car" id="car" />
  </span>
</form>
css 复制代码
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");

input:checked {
  transform: scale(1.6);
}

/* Additional styling */
form {
  display: flex;
  flex-direction: column;
}

form span {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 6px 0;
}

form span input {
  display: inline-block;
  margin-left: 32px;
  transition: 0.2s;
}

html,
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
  font-family: Roboto;
}

Disabled

html 复制代码
<input type="text" placeholder="I am enabled..." />
<input type="text" placeholder="I am disabled..." disabled />
css 复制代码
input:enabled {
  background-color: #9abdfd;
}

input:disabled {
  cursor: not-allowed;
  background-color: #aaa;
}

/* Additional styling */
input {
  display: inline-block;
  width: 240px;
  margin: 12px 0;
  padding: 12px 16px;
  border-radius: 20px;
  border: none;
  outline: none !important;
  transition: 0.1s;
}

input::placeholder {
  color: white;
}

html,
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
}

Valid and Invalid

效果

html 复制代码
<input type="text" placeholder="Enter anything (required)" required />
<input type="email" placeholder="Enter your Email" />
css 复制代码
input:valid {
  background-color: #68af68;
}

input:invalid {
  background-color: #ff6d6d;
}

/* Additional styling */
input {
  color: #fff;
  display: inline-block;
  width: 240px;
  margin: 12px 0;
  padding: 12px 16px;
  border-radius: 20px;
  border: none;
  outline: none !important;
  transition: 0.2s;
}

input::placeholder {
  color: white;
}

html,
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
}

Root

Root CSS 伪类匹配表示文档的树的根元素。在 HTML 中,: root 表示 < HTML > 元素,与选择器 HTML 相同,只是其特异性更高。它经常用于添加 CSS 变量。

html 复制代码
<button class="btn" id="toggleBtn">
  Toggle Dark Mode
</button>
css 复制代码
:root{
    --primary: #4240b4;
    --background: #dddddd;
}

.dark{
    --background: #222222;
}

html,
body{
    background-color: var(--background);
    /* Animated Color change */
    transition: 0.2s ease-in-out;
    /* Additional Styling */
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    margin: 0;
    padding: 0;
}

.btn{
    background-color: var(--primary);
    /* Additional Styling */
    color: #ffffff;
    border: none;
    border-radius: 8px;
    padding: 12px 16px;
    outline: none;
    cursor: pointer
}
js 复制代码
const body = document.querySelector("body")
const toggleBtn = document.querySelector("#toggleBtn")

toggleBtn.addEventListener("click", (e) => {
    body.classList.toggle("dark")
})

First Child, Last Child

: first-child、 : last-child 和: nth-child ()如果组件是父元素的第一个、最后一个和第 n 个子元素,则将其作为目标

html 复制代码
<div class="info">
  <span> Title </span>
  <p>
    Lorem ipsum dolor, sit amet consectetur adipisicing elit.
    Dolorem, quam iusto a iste tenetur hic natus sapiente,
    voluptates omnis consequuntur eaque, provident enim? Officiis
    optio sint voluptas nostrum tempore expedita. Lorem ipsum dolor
    sit amet consectetur adipisicing elit. Omnis placeat vitae
    ratione facilis veritatis animi, dolorum at accusantium qui
    asperiores tempore beatae architecto ipsum libero voluptatibus.
    Consequuntur culpa harum veritatis?
  </p>
  <span> Author </span>
</div>

<div class="info">
  <span> Title </span>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Hic
    nulla inventore quasi ad tempora harum voluptate eius delectus,
    asperiores similique totam nobis aliquam illo autem, quia, porro
    dolor laborum reprehenderit quo perferendis odio temporibus
    deserunt! Necessitatibus nesciunt laborum aperiam consectetur
    qui excepturi deserunt animi tenetur? Quos iusto maiores
    voluptate reiciendis unde possimus accusantium corporis repellat
    commodi cupiditate a, sed deleniti?
  </p>
  <span> Author </span>
</div>
css 复制代码
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");

span:first-child {
  font-size: xx-large;
  font-weight: 900;
}

span:last-child {
  display: block;
  margin-left: auto;
  color: grey;
  text-align: right;
}

/* Additional styling */
.info {
  margin: 24px 2vw;
}

.info span:last-child::before {
  content: "-";
}

html,
body {
  min-height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
  font-family: Roboto;
}

First of Type, Last of Type

: first-of-type、 : last-of-type 和: nth-of-type 分别选择给定元素在 HTML 主体中的第一个、最后一个和第 n 个出现次数

注意: : nth-of-type 可以用作: first-of-type,通过使用: nth-of-type (1)

html 复制代码
<div class="grid-container">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
  <div class="grid-item">6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">9</div>
</div>
css 复制代码
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");

.grid-item:nth-of-type(odd) {
  background-color: black;
  color: white;
}

/* Additional styling */
.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
.grid-item {
  background-color: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 20px 32px;
  font-size: 30px;
  text-align: center;
}

html,
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
  margin: 0;
  font-family: Roboto;
}

来自翻译计划
作者:羊先生
https://dev.to/ruppysuppy/master-useful-css-pseudo-classes-lh2