前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我可能学到了“假”的CSS:伪类伪元素

我可能学到了“假”的CSS:伪类伪元素

作者头像
江米小枣
发布2020-06-15 14:53:33
1.4K0
发布2020-06-15 14:53:33
举报
文章被收录于专栏:云前端云前端

CSS的选择器除了根据id、class、属性等从DOM中获取元素的以外,还有很重要的一类,用来获取元素的特别内容或特别状态,这就是 伪元素(Pseudo-elements) 和 伪类(Pseudo-classes)

[I] 伪元素

伪元素是对元素中的特定内容进行操作,选取诸如元素内容第一个字(母)、第一行,选取某些内容前面或后面这种普通的选择器无法完成的工作。它控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素

  • ::before 在元素内容之前插入额外生成的内容
  • ::after 在元素内容之后插入额外生成的内容
  • ::first–letter 选取元素的首个字符
  • ::first–line 选取元素的第一行
  • ::selection 对用鼠标键盘等已选取的文字部分应用样式
  • ::spelling-error
  • ::grammar-error

[1.1] ::before 和 ::after

相比于其他伪元素大都是对文档中已有部分的选择,::before 和 ::after 则是向文档树中加入内容,这些内容并不存在于HTML源代码中,但确是可见的,并且可以当作元素的子对象对待(正常的样式继承等)

  • 深度顺序:元素 < ::before < 内容 < ::after
  • 诸如 <input /><iframe />等不能包含子元素的标签,不支持 ::before 和 ::after
  • <img /> 正常情况下也符合上一条规则,但加载失败后其 ::before 和 ::after 就可生效
content
  1. 直接使用字符串
  2. 使用ASCII编码转义的特殊字符 (字符表) a:visited:before { content: "\2713 "; /*显示一个对勾 √ */ }
  3. 使用属性 @media print { a[href]:after { content: " (" attr(href) ") "; } }
场景1:指示表单中的必填域
代码语言:javascript
复制
:required::after {
   content: ' (Required) ';
   color: #c00;
   font-size: .8em;
}
场景2:清除浮动
代码语言:javascript
复制
.clearfix::after {
   content: " ";
   display: table;
   clear: both;
}
场景3:添加装饰性样式
代码语言:javascript
复制
h3::after {
   display: inline-block;
   content: "";
   position: absolute;
   left: 50%;
   top: -41px;
   width: 6px;
   height: 6px;
   background-color: #fb5211;
   border-radius: 50%;
   border: 2px solid #fff;
   box-shadow: 0 0 0 3px #fb5211;
   transform: translateX(-5px);
}
场景4:链接tooltip
代码语言:javascript
复制
a[data-tooltip] {
   display: inline-block;
   position: relative;
   text-decoration: none;
}
a[data-tooltip]::after {
   content: attr(data-tooltip) "@_@";
   position: absolute;
   bottom: 130%;
   left: 20%;
   background: #ffcb66;
   padding: 5px 15px;
   white-space: nowrap;
   opacity: 0;
   transition: all 0.5s ease;
}
a[data-tooltip]:hover::after{
   opacity: 1;
}
场景5:鼠标经过按钮时的闪光效果
代码语言:javascript
复制
.button {
   border-top: 1px solid #96d1f8;
   background: #65a9d7;
   background: -webkit-gradient(linear, left top, left bottom, from(#3e779d), to(#65a9d7));
   padding: 5px 10px;
   border-radius: 8px;
   box-shadow: rgba(0,0,0,1) 0 1px 0;
   text-shadow: rgba(0,0,0,.4) 0 1px 0;
   color: white;
   font-size: 14px;
   text-decoration: none;
   vertical-align: middle;
   position: relative;
   overflow: hidden;
   display: inline-block;
}
.button::before {
   content: "";
   width: 200%;
   height: 200%;
   position: absolute;
   top: -200%;
   left: -225%;
   background-image: -webkit-linear-gradient(135deg, rgba(255,255,255,0), rgba(255,255,255,0.6), rgba(255,255,255,0));
   transition: all 0.5s ease-out;
}
.button:hover::before {
   top: 200%;
   left: 200%;  
}

[1.2] ::first-letter

有效的首字符
  • 元素的display计算值必须是 block, inline-block, table-cell, list-item或者table-caption
  • 可以作为首字符伪元素的就是 数字,英文字母,中文以及 $ 以及一些运算符以及非常容易忽视的空格
  • ·@#%&()()[]【】{}:::"“”;;'‘’》《,,.。??!!…、/\ 等辅助类字符,无法被正确处理成首字符,会和第一个“有效字符”连带处理
  • 首字符前面不能有图片或者inline-table之类的元素存在
  • ::before也会参与到::first-letter的规则中,::before如果存在,其首字符会被应用样式
只有部分样式对 ::first-letter 有效
  • 所有字体相关属性:font, font-style, font-variant, font-weight, font-size, line-height以及font-family
  • 所有背景相关属性:background-color, background-image, background-position, background-repeat, background-size, 以及background-attachment
  • 所有margin相关属性:margin, margin-top, margin-right, margin-bottom, margin-left
  • 所有padding相关属性:padding, padding-top, padding-right, padding-bottom, padding-left
  • 所有border相关属性:缩写的border, border-style, border-color, border-width及普通书写的属性
  • color属性
  • text-decoration, text-transform, letter-spacing, word-spacing(合适情境下), line-height, float, vertical-align(只有当float为none的时候)这些CSS属性们

换句话说,如果尝试使用visibility:hidden或者display:none隐藏::first-letter伪元素,是不会生效的

开头的子元素支持部分display属性值标签嵌套
  • 如果是inline, block, table, table-row, table-caption, table-cell, list-item都是可以的,且支持多层嵌套
  • 如果是inline-block, inline-table,会直接无效
  • 如果是flex,则直接选择了下一行(纯文本而非相邻的子元素)的首字符
正确理解样式权重

同样以上例的HTML结构说明,因为 ::first-letter 是伪元素,相当于 ::first-letter 选择的“第”字成为了 span 的子元素,故其权重大于span样式权重

代码语言:javascript
复制
p::first-letter {
   color: red; /*红色会对首字符生效*/
}
p > span {
   color: blue!important;
}
场景1:英文首字下沉
代码语言:javascript
复制
p::first-letter {
   font: bold italic 3em / .5 serif;
   color: #607d8b;
   float: left;
   margin: 0.2em 0.25em .01em 0;
}
场景2:货币单位样式
代码语言:javascript
复制
.price::first-letter {
   margin-right: 5px;
   font-size: xx-large;
   vertical-align: -2px;
}
代码语言:javascript
复制
<p>¥399</p>

[1.3] ::first-line

  • 只对块级元素有效(display 设置为 block, inline-block, table-caption, table-cell)
  • 只支持有限的样式,常见的包括 font-*, background-*, line-height, color, word-spacing, letter-spacing, text-decoration, text-transform
  • 对元素中嵌套的块级元素,仍对其第一行有效
  • 对第一行中嵌套的 display:inline 元素有效
  • ::before也会参与到::first-line的规则,即便在样式上并不和第一行的内容连接(比如由一个diaplay:block的div子元素开头的内容)

[1.4] ::selection

也被称为“高亮”伪元素,因为只是用来高亮鼠标选择部分的

  • 只有 color, background-color, cursor, text-shadow, text-emphasis-color, text-decoration 等样式有效

[1.5] Javascript与伪元素的有限交互

  • 因其不在dom中,无法直接对伪元素绑定事件等
  • 可以获取伪元素的样式,如下:
代码语言:javascript
复制
window.getComputedStyle(
   document.querySelector('.element'), ':before'
).getPropertyValue('color')

[II] 伪类

由于元素状态是动态变化的,所以一个元素特定状态改变时,它可能得到或失去某个样式。因为功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类

  • :target
  • :link
  • :hover
  • :active
  • :visited
  • :focus
  • :not
  • :lang
  • :enabled
  • :disabled
  • :required
  • :optional
  • :checked
  • :in-range
  • :out-of-range
  • :valid
  • :invalid
  • :first-child
  • :last-child
  • :only-child
  • :nth-child()
  • :nth-last-child()
  • :empty
  • :first-of-type
  • :last-of-type
  • :only-of-type
  • :nth-of-type()
  • :nth-last-of-type()

[2.1] 用:target选中页面局部

如果URL中的hash部分和页面中的锚点元素匹配,则对应页面元素可应用到由:target定义的样式

代码语言:javascript
复制
<h2 id="rotnruin">Rot &amp; Ruin</h2>
<h2 id="romero">Romero Zombies</h2>
<ul>
   <li><a href="#rotnruin">Rot &amp; Ruin</a></li>
   <li><a href="#romero">Romero Zombies</a></li>
   ...
</ul>
代码语言:javascript
复制
h2:target {
   background: rgb(125,104,99);
   border: 0;
   color: rgb(255, 255, 255);
   padding-left: 10px;
}
  • 此时如果点击了href="#romero"的a标签,对应的h2就会高亮
  • 一些简单的tab切换等也可以在不借助js的情况下用:target实现了

[2.2] 用:not过滤掉不符合的元素

  • :not(x)括号中可以应用几乎所有的选择器语法
  • :not可以搭配其他伪类使用,如用 p:not(:empty) 选择非空元素
代码语言:javascript
复制
<p id="p1">aaa</p>
<p id="p2">bbbb</p>
<p id="p3">ccccc</p>
<p id="p4">dddddd</p>
代码语言:javascript
复制
p:not(#p1):not(#p3) {color: red;}

[2.3] 根据索引选择元素

==在*-child系列伪类中,索引是相对于所有同级兄弟元素计算的,而非特定类型==

:first-child:last-child
代码语言:javascript
复制
<div>
   <h1>Hi</h1>
   <h2>Apple</h2>
   <h2>Banana</h2>
   <h2>ApplePen</h2>
   <h2>Pen</h2>
</div>
代码语言:javascript
复制
h1:first-child {} /*Hi*/
h2:first-child {} /*匹配不到*/
h2:last-child {} /*Pen*/
:nth-child()

和 not() 一样,:nth-child() 和 :nth-last-child() 也是函数式的伪类选择器;接受一个单一参数,可取值为:

  • odd -- 奇数
  • even -- 偶数
  • 一个整数 -- 第n个
  • An+B -- n为必须的关键字,A可为默认为1的整数,B为可选的整数;表示“以A的若干倍数偏移B个为一组的若干分组”;n从0开始计算,计算结果小于1的元素忽略
:nth-last-child()

和 :nth-child() 规则相同,唯一的区别在于从最后一个元素反向计算

:only-child

匹配相对于其父元素类型唯一的子元素

:empty

匹配空的元素

  • 如果元素中有空格等内容,不会被认为是:empty

[2.4] 根据索引选择特殊类型的元素

  • 这一系列的伪类包括 :first-of-type,:last-of-type,:only-of-type,:nth-of-type(),:nth-last-of-type()
  • 基本用法和 *-child 一样
  • *-child 不同的是, 索引只针对选择器指定的类型,而非同级的所有兄弟元素

[2.5] 表单元素

:enabled:disabled
  • 匹配元素是否有 disabled 属性
:required:optional
  • 匹配元素是否有 required 属性
:checked
  • 只作用于 radio 和 checkbox
:in-range:out-of-range
  • 作用于 type = range|number|date 的 input
:valid:invalid
  • 依赖于 input 的 type类型 和 pattern约束,判断是否校验通过
  • 可以组合使用,如 input:focus:invalid

[2.6] jQuery选择器中支持的部分“伪类”

  • :checked
  • :focus
  • :disabled
  • :enabled
  • :empty
  • :first-child
  • :last-child
  • :nth-child
  • :nth-last-child
  • :only-child
  • :first-of-type
  • :last-of-type
  • :nth-of-type
  • :nth-last-of-type
  • :only-of-type
  • :not
  • :target
  • :lang
  • :root

参考资料

  • https://www.sitepoint.com/css-pseudo-elements/
  • https://www.sitepoint.com/getting-to-know-css3-selectors-structural-pseudo-classes/
  • https://www.sitepoint.com/getting-to-know-css3-selectors-other-pseudo-classes/
  • https://medium.freecodecamp.com/explained-css-pseudo-classes-cef3c3177361#.e8mlacikv
  • https://css-tricks.com/css-content/
  • https://css-tricks.com/pseudo-element-roundup/
  • http://blog.csdn.net/sadfishsc/article/details/7047595
  • http://www.zhangxinxu.com/wordpress/2016/09/css-first-letter-pseudo-element/
  • https://css-tricks.com/almanac/selectors/f/first-line/
  • http://www.cnblogs.com/xiaohuochai/p/5518943.html
  • https://web3canvas.com/an-in-depth-guide-to-css3-selectors/
  • http://www.cnblogs.com/kiracn/archive/2009/12/17/1626742.html
  • http://www.cnblogs.com/coco1s/p/5667853.html
  • https://davidwalsh.name/pseudo-element
  • http://stackoverflow.com/questions/7478336/only-detect-click-event-on-pseudo-element

[题图:凡尔赛宫园林](http://bbs.fengniao.com/forum/pic/slide_165_8734595_79759609.html)

* 原创文章转载请注明出处

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • [I] 伪元素
    • [1.1] ::before 和 ::after
      • content
      • 场景1:指示表单中的必填域
      • 场景2:清除浮动
      • 场景3:添加装饰性样式
      • 场景4:链接tooltip
      • 场景5:鼠标经过按钮时的闪光效果
    • [1.2] ::first-letter
      • 有效的首字符
      • 只有部分样式对 ::first-letter 有效
      • 开头的子元素支持部分display属性值标签嵌套
      • 正确理解样式权重
      • 场景1:英文首字下沉
      • 场景2:货币单位样式
    • [1.3] ::first-line
      • [1.4] ::selection
        • [1.5] Javascript与伪元素的有限交互
        • [II] 伪类
          • [2.1] 用:target选中页面局部
            • [2.2] 用:not过滤掉不符合的元素
              • [2.3] 根据索引选择元素
                • :first-child 和 :last-child
                • :nth-child()
                • :nth-last-child()
                • :only-child
                • :empty
              • [2.4] 根据索引选择特殊类型的元素
                • [2.5] 表单元素
                  • :enabled 和 :disabled
                  • :required 和 :optional
                  • :checked
                  • :in-range 和 :out-of-range
                  • :valid 和 :invalid
                • [2.6] jQuery选择器中支持的部分“伪类”
                • 参考资料
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档