CSS实用技巧:伪元素/伪类的妙用

CSS实用技巧:伪元素/伪类的妙用在一个网页中 CSS 占着非常重要的地位 近年来随着 CSS 的发展 伪元素 伪类也开始被大量应用 在性能愈加被看中的当下 处于文档流之外的 CSS 伪元素 伪类是当之无愧的 无冕之王 下面笔者总结的一些关于 CSS 的 骚操作 希望能对你产生帮助 hover 和 focus 显示浮层我们完全可以只用 CSS 的父子选择器 用于 父子嵌套 兄弟选择器 用于 同级并列排列 伪类 hover 实现 当鼠标滑入显示 xxx 甚至不用 JS 比如 当鼠标滑入链接时显示图片

在一个网页中CSS占着非常重要的地位。近年来随着CSS的发展,伪元素/伪类也开始被大量应用:在性能愈加被看中的当下,处于文档流之外的CSS伪元素/伪类是当之无愧的“无冕之王”!

下面笔者总结的一些关于CSS的“骚操作”,希望能对你产生帮助:


:hover和:focus显示浮层
我们完全可以只用CSS的父子选择器(用于“父子嵌套”)/兄弟选择器(用于“同级并列排列”)+伪类 :hover 实现【当鼠标滑入显示xxx】,甚至不用JS!
比如:当鼠标滑入链接时显示图片




<a href="javascript:;">图片链接 
      a> <img src="xxx" alt="" /> 
img{ 
     visibility: hidden; position: absolute; transition: visibility .2s; / 设置延时 / } a:hover + img, img:hover{ 
     visibility: visible; } 

最后又加了 img:hover 是为了让鼠标在图片上滑动时也保持图片的显示状态 —— 防止图片覆盖链接显示的情况。

a:focus + img, img:focus{ 
     visibility: visible; transition: none; } 

:focus:hover

上面的代码想必你想到了更好的应用场景:纯CSS实现下拉列表(二级菜单)

<div class="y-table"> <a href="javascript:;" class="y-msg">我的消息 
      a> <div class="cs-list"> <a href="javascript:;">我的回答 
       a> <a href="javascript:;">我的私信 
        a> <a href="javascript:;">我的订单 
         a> <a href="javascript:;">我的关注 
          a> <a href="javascript:;">我的收藏 
           a>  
            div>  
             div> 
.cs-list{ 
     display: none; position: absolute; border: 1px solid red; background-color: #fff; } .y-table:focus-within .cs-list{ 
     display: block; } 

:focus-within


:not()判断显示元素
在网页的【搜索】按钮中,有这样一种场景:根据输入的关键字显示列表。
笔者曾写过一篇文章,用JavaScript阐述了其场景:(JavaScript)百度/Google 搜索的即时自动补全功能究竟是如何“工作”的?




其实我们也可以用CSS的 :not() 来优化显示 —— 判断不是xxx的符合条件的信息:

.list:not([class="show"]) { 
      display: none; } 

CSS3选择器中,有一个叫做属性选择器的东西,有:[attr](有该属性), [attr=xxx](属性值是xxx), [attr^=xxx](属性值是xxx开头), [attr$=xxx](属性值以xxx结尾), [attr*=xxx](属性值包含xxx) 这些用法。

var eleStyle = document.createElement("style"); // 文本框输入 document.querySelector("input").addEventListener("input", function() { 
      var val = this.value.trim().toLowerCase(); if (val !== '') { 
      // 改变CSS筛选规则 //list是返回值存放的列表(ul) eleStyle.innerHTML = '.list:not([data-index*="'+ this.value +'"]) { display: none; }'; } else { 
      eleStyle.innerHTML = ''; } }); 

:not


点击按钮显示菊花图
说一个很常见的使用场景:在表单里,当你点击提交按钮时,如果能够让用户看到“更多的反馈效果”似乎这个网页会更受欢迎一些。
那么,当你“提交表单”时让用户知道自己再等待状态似乎是个不错的选择:




button.loading{ 
       color: transparent; background: #f0f0f0 url(loading.gif) no-repeat center/50%; } 

但当你看到“点击时”(还有“移动到”、“xxx前/后”),我想你应该有那么一瞬间要想到比如:“伪类:focus”或者“伪类:active”,试着改写一下吧!


:active实现“数据上报”
其实网页中还有一个小问题:如果用户禁用了JavaScript/浏览器不支持JavaScript怎么办?
当然,后一种情况现在基本不会出现,但是这确实是一种令人感到棘手的问题,并且吸引了大量前端开发者为之倾覆心血!




我们通常会将active和after结合使用:

.button:active::after{ 
        content: url(xxx.gif?xxx=xxx&xx=xx); display: none; } 

这里为什么用url?
如果不用图片格式的话,after-content的字符串格式中只能写固定值。
这能说明什么?
可以肯定的一点是:这里证明了图片资源确实是发送请求得到的(包括img标签和css的background)!而且是GET请求。由此可引发一系列有趣的事情:






首先:判断如果是移动端,则显示一张图片,否则用颜色背景:

body{ 
        background: white; } @media only screen and (max-width: 768px) { 
        body { 
        background: url(xxx); } } / 或者你也可以用: */ @media (any-hover: none){ 
        body { 
        background: url(xxx); } } 

但是这样似乎没有用到上面的结论?

你当然可以这样做:

@media only screen and (max-width: 768px) { 
        body { 
        background-image: url(http://localhost:8080/mobile); } } 

在判断是移动端时向服务器指定接口请求数据 —— 至于是一张图片?或者是什么数据?就看你自己了:

const express = require("express"); const app = express(); app.get("/mobile", (req, res) => { 
        console.log("is mobile") res.end() )} app.listen(8080) 

事实上,这种“伪类/伪元素作为事件使用”的场景还是蛮多的,除了上面这例代码和常见的“表单校验”,还有一个【经典的示例】:

<p>您已选择<span class="counter"></span>个话题</p> body{ 
        counter-reset: topicCounter; } :checked + .counter{ 
        counter-increment: topicCounter; } .counter::before{ 
        content: counter(topicCounter); } 

::after和::before的场景
作为伪元素/伪类中的“扛把子”,after和before怎么能不说呢?
他们的使用场景太多了:常见的“文字之间的‘|’符号”、“文字前后的横线”、“一些特殊的图案乃至组合图案”中都能见到他们的身影:




.mxc-menu > .mxc-menu-item > .mxc-switch{ 
         position: relative; box-sizing: content-box; width: 2.6rem; height: 1.4rem; border: 1px solid #ccc; outline: 0; border-radius: .75rem; background-color: rgba(0,0,0,.1); /* 去掉webkit内核里默认的样式 */ -webkit-appearance: none; /* 去掉webkit内核里默认的点击效果 */ -webkit-tap-highlight-color: rgba(0,0,0,0); } .mxc-menu > .mxc-menu-item > .mxc-switch:checked{ 
         border-color: #07C160; background-color: #07C160; } .mxc-menu > .mxc-menu-item > .mxc-switch::after{ 
         content:" "; position: absolute; top: 0; left: 0; width: 1.4rem; height: 1.4rem; border-radius: .7rem; background-color: #FFFFFF; box-shadow: 0 0 2px #999; } .mxc-menu > .mxc-menu-item > .mxc-switch:checked::after{ 
         left: 1.2rem; } 

:after

(再给它们加上“过渡效果”就是笔者所写的UI库中的“ 开关按钮 ”的实现啦)

/* html */ "search"> /* css */ .search{ 
         position: relative; display: inline-block; width: 12px; height: 12px; border-radius: 50%; border: 1px solid #ccc; text-align: center; transform: rotate(-45deg); &::after{ 
         content: ''; display: inline-block; width: 1px; height: 4px; background-color: #ccc; } } 

search

(一个“搜索图标”样式的实现)

 
         
         Document 
          
        { 
         margin: 0; padding: 0; background-color: #34455a; height: 100vh; display: flex; align-items: center; justify-content: center; } .loading{ 
         width: 100px; height: 100px; box-sizing: border-box; border-radius: 50%; border-top: 5px solid #ff0000; position: relative; animation: a1 1s linear infinite; } .loading::before,.loading::after{ 
         content: ''; width: 100px; height: 100px; position: absolute; left: 0; top: -5px; box-sizing: border-box; border-radius: 50%; } .loading::before{ 
         border-top: 5px solid #10AEFF; transform: rotate(120deg); } .loading::after{ 
         border-top: 5px solid #5456db; transform: rotate(240deg); } .loading span{ 
         position: absolute; width: 100px; height: 100px; font-size: 13px; color: #fff; text-align: center; line-height: 100px; animation: a2 1s linear infinite; } @keyframes a1{ 
         to{ 
         transform: rotate(360deg); } } @keyframes a2{ 
         to{ 
         transform: rotate(-360deg); } } 
       
"loading"> loading...

:before:after

(一个纯CSS实现的很炫酷的“loading”)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/206958.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午3:06
下一篇 2026年3月19日 下午3:06


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号