CSS 伪类、伪元素

伪类选择器(Pseudo-classes)

  • css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说,伪类和伪元素是用来修饰不在文档树中的部分,比如,一句话中的第一个字母,或者是列表中的第一个元素
  • 伪类用于 当已有元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。虽然它和普通的css类相似,可以为已有的元素添加样式,但是它只有处于dom树无法描述的状态下才能为元素添加样式,所以将其称为伪类
  • 注意:
    • 伪类名称对大小写不敏感

状态伪类

/* 静态伪类(只能应用于超链接) */
a:link {background-color: pink;} /* 选择未访问的链接 */
a:visited {color: orange;} /* 选择已访问的链接 */
/* visited 伪类只能设置字体颜色的样式 */
/* link 以及 visited 这两个伪类只能应用于超链接 */


/* 动态伪类(可应用于任何元素) */
a:focus {background-color: lightgrey;} /* 拥有焦点时 */ 
a:hover {background-color: lightblue;} /* 选择鼠标指针浮动在其上的元素 */
a:active {background-color: lightgreen;} /* 选择活动的链接。正被点击,即手指未松开,即还未跳转到新页面 */
/* IE7-浏览器不支持 :focus、:hover和 :active。在IE6-浏览器下只支持给<a>设置 */

/* 不仅可以使用单一伪类,也可以伪类结合使用 */
a:visited:hover:first-child {color: red;}
/* 注意:顺序无关 */

/* 伪类顺序 */
/*
对于伪类顺序,有一个口诀是 love-hate
代表着伪类的顺序是 link、visited、focus、hover、active。
但是否伪类的顺序只能如此呢?为什么是这个顺序呢?

link 和 visited 必须在最前面,且没有先后顺序,否则 link 或 visited 的效果将被覆盖

hover、active、focus 这三个伪类必须是 focus、hover、active 的顺序 
因为在 focus 状态下,也需要触发 hover 和 active,而要触发 active 一定要先触发 hover,所以 active 要放在 hover 后面

所以最终的顺序只有两种:link、visited、focus、hover、active 或 visited、link、focus、hover、active
*/

结构化伪类

否定选择器(IE8-不支持)
:not()  选择器匹配不符合参数的元素,参数可以是 元素/选择器。可以简单理解为:就它没有,其余都有
语法格式: 父元素:not(子元素/子选择器)   Father:not(Children/selector)
*/
/* nav直接子元素中,最后一个a类型元素不应用此样式 */
nav > a:not(:last-of-type) {
    border-right: 1px solid red;
}


/* 结构伪类(IE8-浏览器不支持) */
以下情况都是E为父元素,F为子元素:
E F:nth-child(n) 选择父元素的第n个子元素,第一个编号为 1
E F:nth-last-child(n) 选择父元素的倒数第n个子元素,倒数第一个编号为 1
E F:first-child(IE6-不支持)父元素的第一个子元素,且该子元素是F,与 E F:nth-child(1) 等同
E F:last-child (IE6-不支持) 父元素的最后一个子元素,且该子元素是F,与 E F:nth-last-child(1) 等同
E F:only-child    选择父元素中只包含一个子元素,且该子元素是F

E F:nth-of-type(n) 选择父元素的具有指定类型的第n个子元素
E F:nth-last-of-type(n) 选择父元素的具有指定类型的倒数第n个子元素
E F:first-of-type 选择父元素中具有指定类型的第1个子元素,与 E F:nth-of-type(1) 相同
E F:last-of-type  选择父元素中具有指定类型的最后1个子元素,与 E F:nth-last-of-type(1) 相同
E F:only-of-type  选择父元素中只包含一个同类型的子元素,子元素是F

注意:n可以是整数(从0开始),也可以是公式,也可以是关键字(even 偶数项、odd 奇数项)
比如:
Element.nth-child(n)  这里n就是一个简单表达式,取值从“0”开始计算。这里只能是小写字母“n”,不能用其它字母代替
也可以使用比如 2n + 1、3n + 1 等公式来达到我们想要的效果。注意:不能使用乘法 *,比如 n * n

实例:
p:first-child    代表的并不是<p>的第一个子元素,而是<p>元素是某元素的第一个子元素
p > i:first-child    匹配所有<p>元素中的第一个子元素,如果是 i 元素,则应用样式 
p:first-child i 匹配所有作为第一个子元素的<p>元素中的所有<i>元素
*/
/* first-child 与 first-of-type 的比较:*/
    <style type="text/css">
        /* 先把所有子元素集中,再数,如果恰好也是 div 类型,则运用样式 */
        div > div:first-child {
            color: #f00;  /* 红色 */    
        }

        /* 先把 p 类型集中,再数 */
        div > p:first-of-type {
            color: #00f;  /* 蓝色 */
        }
    </style>
</head>
<body>
<div>
    <div>第一个div中第一个元素</div>
    <p>第一个div中的第一个p类型,但不是第一个元素</p>
</div>
<hr>
<div>
    <p>第二个div中的第一个p类型,也是第一个元素</p>
    <div>第二个div中第二个元素</div>
</div>
</body>


:target 当URL带有锚名称,指向文档内某个具体的元素时,:target 匹配该元素(IE8-不支持)

表单相关伪类

/* UI元素伪类包括 :enabled、:disabled、:checked 三个,主要针对于HTML中的  form 元素(IE8-浏览器不支持) */
input:enabled {color: #ccc;}  /* 匹配没有设置 disabled 属性的表单元素 */  input:disabled {color: red;}  /* 匹配禁用的表单元素 */
input:checked {color: green;} /* 匹配被选中的input元素,这个input元素包括radio和checkbox) */


:default 匹配默认选中的元素

E:empty 匹配没有子元素的元素。如果元素中含有文本节点、HTML元素或者一个空格,则 :empty 不能匹配这个元素。


:in-range 匹配在指定区域内元素
input[type=number]:in-range {
        border: 1px solid green;   /* 当数字选择器的数字在5到10是,其边框变为指定样式 */
}
<input type="number" min="5" max="10">


:out-of-range 与 :in-range 相反,它匹配不在指定区域内的元素


:indeterminate
indeterminate 的英文意思是“不确定的”。当某组中的单选框或复选框还没有选取状态时,:indeterminate 匹配该组中所有的单选框或复选框


:valid  匹配条件验证正确的表单元素

 
:invalid  与 :valid 相反,匹配条件验证错误的表单元素


:optional  匹配是具有 optional 属性的表单元素。当表单元素没有设置为 required 时,即为 optional 属性


:required  与 :optional 相反匹配设置了 required 属性的表单元素


:read-only  匹配设置了只读属性的元素,表单元素可以通过设置“readonly”属性来定义元素只读


:read-write  匹配处于编辑状态的元素。input,textarea 和设置了contenteditable 的HTML元素获取焦点时即处于编辑状态


:scope(处于试验阶段)匹配处于 style 作用域下的元素。当 style 没有设置 scope 属性时,style 内的样式会对整个 html 起作用
注:目前支持这个伪类的浏览器只有火狐

语言相关伪类

:dir(处于实验阶段)
:dir 匹配指定阅读方向的元素,当HTML元素中设置了 dir 属性时该伪类才能生效。
现时支持的阅读方向有两种:ltr(从左往右)和rtl(从右往左)。
目前,只有火狐浏览器支持 :dir 伪类,并在火狐浏览器中使用时需要添加前缀( -moz-dir() )。
 
 
:lang 匹配设置了特定语言的元素(IE7-不支持)
设置特定语言可以通过为HTML元素设置 lang=“” 属性,设置 meta 元素的 charset=“” 属性,或者是在 http 头部上设置语言属性。
实际上,lang=“”属性不只可以在html标签上设置,也可以在其他的元素上设置

其它伪类

:root 匹配文档的根元素。一般的html文件的根元素是html元素,而SVG或XML文件的根元素则可能是其他元素


:fullscreen  匹配处于全屏模式下的元素。
全屏模式不是通过按F11来打开的全屏模式,而是通过Javascript的 Fullscreen API 来打开的,不同的浏览器有不同的 Fullscreen API。
目前,:fullscreen 需要添加前缀才能使用


新增伪类  :focus-within  匹配当前获得焦点的目标元素

伪类应用示例

  • 自定义 checkbox(这里是点击进行笑脸切换)
    <style type="text/css">
    input[type="checkbox"] {
        /* 默认样式是一个小方框,控制小方框是否出现 */
        -webkit-appearance: none;
        appearance: none;

        /* input 本身就属于 inline-block 元素,可以直接设置 宽高 */
        width: 20px;
        height: 20px;

        /* 去除点击后产生的轮廓 */
        outline: none;  
        vertical-align: middle;
        background: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/b6dcd011-23cc-4d95-9e51-9f10100103bd.png) 0 0/contain no-repeat;
    }

    input[type="checkbox"]:checked {
        background-image: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/538f26f0-6f3e-48d5-91e6-5b5bb730dd19.png);
    }
    </style>
</head>
<body>
今天的心情:<input type="checkbox" name="mood" value="bad">
</body>

伪元素选择器(Pseudo-elements)

  • 伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中
/* 在CSS3中,为了区分伪类选择器和伪元素选择器,伪元素选择器前用两个冒号 */

/* 用法: */
/* ::first-letter 匹配元素中文本的 首字母/第一个文字。被修饰的 首字母/第一个文字 不在文档树中 */
div::first-letter {color: red;}  
/* 所有前导标点符号应与第一个字母一同应用该样式 */
/* 只能与块级元素关联 */
/* 只有当选择器部分和左大括号之间有空格时,IE6-浏览器才支持。因为 first-letter 中存在连接符的原因 */


/* ::first-line 匹配元素中第一行的文本。这个伪元素只能用在块元素中,不能用在内联元素中 */
div::first-line {color: green;}
/* 只有当选择器部分和左大括号之间有空格时,IE6-浏览器才支持。因为 first-line 中存在连接符的原因 */


/* ::before 在被选元素前插入内容。需要使用 content 属性来指定要插入的内容。被插入的内容实际上不在文档树中(IE7-不支持) */
div::before {content: "是啊!";}  /* 这里是插入文字 */ 
/* 默认这个伪元素是行内元素,且继承元素可继承的属性 */
/* 所有伪元素都必须放在出现该伪元素的选择器的最后面。若写成 p:before em 就是不合法的 */


/* ::after 在被元素后插入内容,其用法和特性与 :before 相似(IE7-不支持) */
div::after {content: url(girl.jpg);}  /* 这里是插入图片 */
/* 默认这个伪元素是行内元素,且继承元素可继承的属性 */
/* 使用 :before :after 的主要目的是为了省略不必要的标签。其中 content 属性是必不可少的 */
/* 注意:通过 :before 或 :after 生成的元素并不在DOM文档树中,所以通过 :first-child 或 :last-child 是匹配不到它们的 */

/* 以上伪元素还支持单冒号写法 */


/* ::selection 匹配用户被用户选中或者处于高亮状态的部分。在火狐浏览器使用时需要添加-moz前缀(IE8-浏览器不支持) */
div::selection{color: red;  background-color: blue;}  /* 这里用户选择的内容文字颜色会变为红色,并有蓝色背景 */
/* firefox浏览器需要添加 -moz- 前缀 */
/* 只支持双冒号写法。只支持 color 和 background-color 两个属性 */

/* ::placeholder 匹配占位符的文本,只有元素设置了placeholder属性时,该伪元素才能生效 */
/* 该伪元素不是CSS的标准,它的实现可能在将来会有所改变,所以要决定使用时必须谨慎 */
input::-webkit-input-placeholder{color: lightblue;}   /* chrome 浏览器下建议采用这种写法。测试中发现,不加前缀也可以 */
/* 在一些浏览器中(IE10和Firefox18及其以下版本)会使用单冒号的形式 */


/* ::backdrop(处于试验阶段)*/
h1:fullscreen::backdrop {background: orange;}
/* 用于改变全屏模式下的背景颜色,全屏模式的默认颜色为黑色。该伪元素只支持双冒号的形式 */

content、quotes 属性

<style type="text/css">
/* content属性 */
/* content属性应用于 before 和 after 伪元素 */
div:before {
    content: normal;  /* 默认 */
}
/* content: <string>|<url>|attr(<identifier>) */
/* <string> 里面的内容会原样显示,即使包含某种标记也不例外。比如 content: "前缀<br>"; 页面上依然原样显示 */
/* 如果希望生成内容中有一个换行,则需要使用 \A */
/* 若是一个很长的串,需要它拆分成多行则需要用 \ 对换行符转义 */
div:before {
    content: "第一段\
              第二段";
}
div:after {
    content: "\A后缀";
}


/* url */
div:before {
    content: url(girl.jpg);
}


/* attr(<identifier>) */
div:before {
    content: attr(data-before);
}


/* counter 属性*/
/* 涉及到CSS计数器,会有专门的一节内容介绍 */


/* quotes 属性 */
/* 管理引号
前单引号 -> \2018
后单引号 -> \2019
前双引号 -> \201C
后双引号 -> \201D
*/
div: before {
    quotes:'201C' '201D' '2018' '2019';
}
/*
第一个值定义最外层开始引号(open-quote),第二个串定义最外层结束引号(close-quot)。
第三个值定义次外层开始引号,第四个值定义次外层结束引号。
第五个值定义次次外层开始引号,第六个值定义次次外层结束引号……
*/


/* open-quote|close-quote */
/* 测试前先把之前写的伪元素删除掉 */
div {
    display: inline-block;
    quotes: '\201C' '\201D' '\2018' '\2019' '\201C' '\201D';
}
div:before {
    content: open-quote;
}
div:after {
    content: no-close-quote;
}
</style>
</head>
<body>
<!-- <div data-before="前缀">测试文字</div> -->

<div>最外层
    <div>次外层
        <div>最里层</div>
    </div>
</div>  
</body>
  • 注意:IE8-浏览器仅支持单冒号表示法:

伪元素应用示例

    <style type="text/css">
    .bubble {
        position: relative;
        display: inline-block;
        border: 1px solid #ccc;
        border-radius: 3px;
        padding: 10px;
        margin: 20px;
        background-color: #fff;
    } 

    .bubble:before {
        content: "";
        display: inline-block;
        width: 10px;
        height: 10px;
        position: absolute;
        top: -6px;
        border-left: 1px solid #ccc;
        border-top: 1px solid #ccc;
        transform: rotateZ(45deg);
        background-color: #fff;
    }
    </style>
</head>
<body">
<div class="bubble">Hello world!</div>
</body>
  • 首字下沉
    <style type="text/css">
    div {
        width: 200px;
        border: 1px solid black;
    }

    div:first-letter {
        float: left;
        margin-left: 5px;
        margin-right: 5px;
        font-size: 30px;
    }  
    </style>
</head>
<body>
<div>亚冠联赛是亚洲最高等级的俱乐部赛事,相当于欧洲的欧洲冠军联赛及南美洲的南美解放者杯……</div>  
</body>
  • 钉子效果
    <style type="text/css">
    /* 使用 :before 伪元素画圆 */
    .box:before {
        display: block;
        content: "钉子";
        height: 50px;
        width: 50px;
        border-radius: 50%;
        background-color: black;
        color: white;
        font-weight:bold;
        text-align: center;
        line-height: 50px;
    }

    /* 使用 :after 伪元素画三角形 */
    .box:after {
        display: block;
        content: "";
        width: 0;
        height: 0;
        border: 25px solid rgba(0, 0, 0, 0.05); /* 为更易理解,没有将颜色设置为透明 transparent */
        border-top: 50px solid black;
        margin-top: -20px;
    }
    </style>
</head>
<body>
<div class="box"></div>
</body>
  • 图片叠加效果
    <style type="text/css">
    * {
        padding: 0;
        margin: 0;
    }  

    .box {
        position:relative;
        margin: 30px auto 0;
        width: 300px;
    }

    .box-img {
        position: absolute;
        z-index: 1;
        width: 300px;
        height: 200px;
        border: 5px solid gray;    
    }
 
    .box:before,
    .box:after {
        content:"";
        position: absolute;   
        width: 300px;
        height: 200px; 
        border: 5px solid gray;
        background-color: #D5B07C;
    }

    .box:before {
        left: -10px;
        top: 0;
        transform: rotateZ(-5deg);
    }

    .box:after {
        top: 4px;
        left: 0;
        transform: rotateZ(5deg);
    }
    </style>
</head>
<body>
<div class="box">
    <\img class="box-img" src="http://img5.imgtn.bdimg.com/it/u=2301672014,2503443361&fm=15&gp=0.jpg" alt="图片叠加效果">
</div>
</body>

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容