伪类
:hover :focus :foucswithin
我们给任何选择器加上冒号就叫做我们的伪类,这种伪类的存在的意义是什么?
他会凭空去多出来元素或者选择其他的元素?其实是不会.
.box{
width: 100px;
height:100px;
background-color: black;
}
.box:hover{
background-color: green;
/*打开控制台,页面的结构不会发生改变,元素也不会发生增加或者减少.*/
}
<div class="box"></div>
**伪类核心 **
页面中的元素,状态发生改变,会有不同的样式
状态发生改变:初始状态 ==> 结束状态
状态时是什么?
比如这个Hover要么我鼠标处于悬浮状态,要么我鼠标没有处于悬浮状态.
与之对应我们还有样式还有初始样式 ===> 结束样式
当我们悬浮到这个盒子的时候背景颜色由黑色变为了红色.
伪类选择器是以冒号开始的选择器,描述元素当前所处的状态,这时候想个问题;
如果我们把冒号以及后面的hover删除后会出现什么?
然后盒子的的颜色就变成了绿色,不管加没加上hover,都是对盒子的样式进行描述
所以简单说.
当我们不写伪类选择器之后,他会变成普通的选择器.现在我们重新去写.
.box{
width: 100px;
height:100px;
}
/*现在我有一个需求,当我鼠标放在ul上面时我想要让li元素变成绿色*/
.box .list li:hover{
color:green;
}
/*把:hover去掉,可以看出这个本质上还是对li设置样式,
还是是对li设置样式,加上了hover之后也是对这个li设置样式.
所以说去掉伪类选择器它会变成一个普通的选择器,选中的元素和之前的是一样的.*/
<div class="box">
<ul class="list">
<li>111</li>
<li>222</li>
</ul>
</div>
.box .list li:hover;
.box .list:hover li;
这两个选择器是不是相同的选择器,选中的元素相不相同?选中的元素是相同.
但因为我们选中的条件不一样,最后呈现的效果也会不一样.
第一个选择器做了什么?
第一个首先选中类名为box下面的.list,.list下面的li.
当我鼠标放在这个li标签的时候我们将这个li里面的字体颜色变为绿色.
换而言之也就是这个样式我们是针对li这个元素去设置的.当鼠标放在自己的li上面才会变成绿色.
第二个选择器是当鼠标放在.list也就是ul的时候,这个条件就触发了.
只是我们是对里面的li进行样式设置.
ul是一个大盒子,只要我们鼠标进入这个大盒子,里面的所有lii的字都会变成绿色;*/
理解方式:学会翻译,下意识从左往右读
<div class="box">
<ul class="list">
<li class="item">
<a href="">我是a</a>
<p>p1</p>
<p>p2</p>
</li>
</ul>
</div>
.box > list > li.item > a:hover + p + p{
color: green;/*此时当我们鼠标放在a标签,p2变成了绿色*/
}
li.item是什么意思?
li是不是一个选择器,它叫标签选择器, .item他是一个类名选择器,
标签和类名都是选择器,这两个中间没有空格,所以他们是一个并列条件.
这里只有一个元素,标签名是li类名是item,所以我们简写成li.item,这个精确了我们选择的范围
介绍常见的的伪类选择器(介绍元素/标签的状态)
- :link 链接未被访问时
/*没有访问过的a标签的样式*/
a:link{
color: orange;
}
- :visited: 被访问过的,当我们a标签被访问过了之后,他会触发伪类选择器
a:visited{
color: green;
}
- :focus 当链接和Input被使用tab键选中或激活时
a:focus{
background-color: skyblue;
}
- :active 元素被激活时
a:active{
color: green;/*鼠标按下去未抬起就是激活状态*/
}
- :active适用于很多标签 除了a标签,input,div标签同样适用
div:active{
background-color: red;
}
<div>1111</div>
我们甚至可以做一些很神奇的操作
div{
width: 100px;
height: 100px;
background-image: url(1.jpg);
transition: .3s;
}
div:active{
width:500px;
height:500px;
background-color: red;/*会影响布局,加一些数字可以看到*/
}
<div></div>
- checked 被勾选的状态(适用于input type=“checkbox/radio” )
.checkbox:checked{
width: 100px;
height:100px;
}
<input type="checkbox" class="checkbox">
/*这个和刚才的active有什么区别?
active需要你鼠标不停的按住,鼠标按下去才能出现效果,鼠标抬起来就没有效果了.
然而这个input你只要点击一次就有效果了,这就是一个非常强大的进步.*/
.checkbox:checked +.box{
width:700px;
height:400px;
background-color:skyblue;
}
<input type="checkbox" class="checkbox">
<div class="box"></div>
/*点击图片放大和缩小*/
.box{
width: 100px;
height: 100px;
background-image: url(1.jpg);
transition: 0.5s;
}
.checkbox{
position: absolute;
margin: 0;
width:100px;
height:100px;
opacity: 0;
}
.checkbox:checked~.box{
width: 500px;
height: 500px;/*按下checkbox*/
}
.checkbox:checked{
width: 500px;
height: 500px;
}
<input type="checkbox" class="checkbox">
<div class="box"></div>
checkbox状态开启和状态关闭(单个区块)
radio(多个区域,选中一个,别的就不选中)
这里就可以去完成一个有意思效果
有三块区域正常颜色都为天蓝色,我点击哪一块就变成粉色,点击另一块其他块恢复天蓝色,这块又变成粉色.
<ul class="list">
<li>
<input type="radio" name="box">
<div class="box"></div>
</li>
<li>
<input type="radio" name="box">
<div class="box"></div>
</li>
<li>
<input type="radio" name="box">
<div class="box"></div>
</li>
</ul>
ul{
list-style: none;
}
.list > li {
position: relative;
}
.list > li > input{
position: absolute;
opacity: 0;
margin: 0;
width: 100px;
height: 100px;
}
.list > li > .box {
width: 100px;
height: 100px;
background-color: skyblue;
transition: .5s;
}
.list input:checked + .box {
background-color:pink;
}
:first-line 首行文本状态
.par{
width: 40px;
}
.par:first-line{
color: pink;
}
<p class="par">我要忘了你的样子</p>
:first-letter 首行首字
.par:first-letter{
font-size: 40px;
}
::selection 被选中的文本的样式修改
.par::selection{
color:red;
background-color: green;
/*其实伪类选择器都是两个冒号,一个冒号就是简单写法,这个可能没兼容好,强制规定*/
}
- :not(select)反选
ul>li:not(:first-child){
color: red;/*除了第一个其他全部变为红色*/
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
div:not(.box){
color: skyblue;
}
<div class="box">1</div>
<div>2</div>
<div>3</div>
结构性伪类选择器
选择器可以选择特定(类名)的元素,结构性伪类选择器可以通过序号来进行选择.
- nth-child 根据序号进行选择 优先按照序号选中元素,再判断类型(优先序号)
.list>li:nth-child(1){
color: red;
/*nth是第n个的意思,child是儿子的意思
根据序号进行选择.
这里表示选中ul下面的li. 第一个子元素且为li的元素
这里可以写2n表现2的倍数会被选择,3n表示3的倍数,这里写n+1表示的是所有元素,没有倍数默认从0开始把 所有元素选中*/
}
<ul class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
咋们来看看另外一种情况
li:nth-child(2){
color: purple;
}
/*2和5都变成了紫色,因为在我们没有规定父元素的情况下,页面中所有的li元素都会选中.
因此这里我们不但选中了ul下排在第二个并且是li的元素.
同时也选中了div下排在第二个并且是li的子元素.*/
/*如果要解决这种情况,得限制下li的选择范围*/
ul > li:nth-child(2){
color: purple;/*这时只有2变为了紫色*/
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div>
<li>4</li>
<li>5</li>
<li>6</li>
</div>
**第一种写法:an+b / an-b **
例如:2n+1 n会从0开始每次加1,因此2n+1的结果是:n为0时,2n+1=0*2+1=1;n为1时,2n+1=3
第二种写法: an 例如: 2n 选中所有满足2的倍数的子元素
第三种写法:Odd(符合条件的奇数子元素) / even选中所有满足条件的偶数子元素
- **nth-of-type 根据序号进行选择 **
- 忽略其他类型的标签,只看目标标签,直接给第几个染色.
- 优先类型
- 看起来和nth-child一样,一样的数字选中也行,但是还是有所区别的
nth-of-type精准识别,什么叫精准识别呢?我们来看一下:
<ul>
<li>1</li>
<p>1.1</p>
<li>2</li>
<li>3</li>
</ul>
<div>
<li>4</li>
<p>1.1</p>
<li>5</li>
<li>6</li>
</div>
<style>
li:nth-of-type(2){
color: orange;/*2和5都变为了橘色*/
}
ul > li:nth-of-type(2){
color: orange;
/*2变为橘色,它能找到所有子元素里的li,并且找到第二个li,不管它前面有没有其他元素*/
}
</style>
- :nth-last-child(),:nth-last-of-type ()倒数,支持公式
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div>
<li>4</li>
<li>5</li>
<li>6</li>
</div>
li:nth-last-child(1){
color: orange;/*3和6同时变为橘色*/
}
ul > li:nth-last-child(1){
color: orange;/*3变为橘色*/
}
属性选择器
- [attr]用的中括号[],
学完JS之后你们会非常喜欢它.因为我们去访问属性都是用中括号.
之前我们给一个元素加样式的方式是通过class,id或者标签名来选中这个元素.
除此之外我们还可以使用这个属性来选中元素给它添加样式。
.box{color: pink;} /*这个叫做简写*/
li[class="box"]{
color: pink;
}/*这样依然能够去选中*/
<ul>
<li class="box">1</li>
<li>2</li>
<li>3</li>
</ul>
<div>
<li>4</li>
<li>5</li>
<li>6</li>
</div>
自由度很高,可以只通过属性名去选中
input[type="submit"]{ color: pink;}/*input元素*/
input[name]{
color: pink;/*只有有name属性的input才会被选中*/
}
<input type="submit" name="box">
<input type="submit">
<!--首先我们可以使用属性名称来选中元素-->
<style>
div[class]{/*选中所有有class的div*/
color: pink;/*1和2都变为粉色*/
}
[class]{/*选中所有有class属性的元素*/
color: pink;/*1、2、3全变为粉色*/
}
</style>
<div class="main">1</div>
<div class="container">2</div>
<p class="box">3</p>
[attr^=""]`属性值以谁开头(模糊搜索)
1. li[class="box"]{/*这样不能选中以box作为类名开头的*/
color:red;
}
2. li[class^="box"]{
color:red;
/*^表示以什么开始,这里表现以box开始,以后我们去学正则表达式就会说到*/
}
3. li[class^="b"]{
color:red;/*也能选中*/
}
<ul>
<li class="box1">1</li>
<li class="box2">2</li>
<li class="smallbox1">3</li>
<li class="smallbox2">4</li>
<li class="smallbox3">5</li>
</ul>
<li class="smallbox1 box3">3</li>
li[class^="box"]{
color:red;
}
/*能不能去选中第三个元素,这里是不能去选中的.
这里是因为属性选择器选择的时候,不能按照普通的class/id这种东西划分.
大家可以把smallbox1 box3看成是属性值 这个属性值整体是以smallbox1开头,所有没有办法去 选中box3*/
[attr~=""]属性中包含某值:
<li class="smallbox1 box3">3</li>
li[class~="box3"]{
color: orange;/*3变为橘色,因为他有box3的类名值*/
}
我们来说以什么结束, ‘ [ a t t r `[attr ‘[attr=""]`属性值以谁结尾
li[class$="1"]{
color:red;/*此时第一个元素变成了红色*/
}
比如我们写在中间呢?[attr*=""]
属性值中包含某个字符
a[href*="baidu"]{
background-color: orange;
/*百度和百度网盘的颜色变为了橘色,因为只有这两个标签的href属性里有baidu*/
}
a[href*=".com"]{
color: green;/*三个a标签的字体都变为了绿色,因为他们的href属性里都有.com*/
}
<div>
<a href="https://www.baidu.com">百度</a>
<a href="https://pan.baidu.com">百度网盘</a>
<a href="https://www.google.com">谷歌</a>
</div>
伪元素
大家看到伪元素一定会想到伪类.
伪类表示元素所处的一种状态,用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的.
比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。
而伪元素表示为假的元素,难道页面还会有假的元素吗?
伪元素用于创建一些不在文档树中的元素,并为其添加样式。
虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。
如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。
伪元素和伪类的区别:
伪类的操作对象是文档树中已有的元素.
而伪元素则创建了一个文档树外的元素.使用css创建的标签
因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
:before :after
<p class="yunmu">云牧说 你好我好大家好</p>
<p class="students">同学们说:谢谢,你也好</p>
<p class="yunmu">云牧:天气不错</p>
<p class="students">:同学们说:天气不错</p>
/*所有的p标签主语都需要写出来,每一次写一个p标签手动添加主语还是挺麻烦.
那我这个`云牧说`这个字想要变一下颜色或者调大一点,可能我们还要单独写一个span把`云牧说` 包裹.
这里如果我们要加上一些导语和引语的时候,需要专门添加span.
其实重要的部分是云牧说后面的内容,前面只是一个解释说明是谁说的.
我们现在就给大家抛出一个问题,有没有更好的办法解决写元素部分公共的部分*/
什么是伪元素,
由CSS生成的元素就是伪元素
.yunmu::before{
content: "云牧说:"
}
/*页面此时也有云牧说这个字,但是在html结构中有没有云牧说这个字.
也就是云牧说这个字不是由html生成而是由css生成的*/
:before伪元素的特性
在选中元素正文内容之前插入一段文本
打开控制台,这个伪元素是一个什么类型的元素,他是一个行内元素看computed,
其实这里其实不止插入一段文本,而是在选中元素正文内容之前插入行内元素
.yunmu::before{
content: "云牧说:";
color:pink;
background-color:green;
border:1px solid red;
/*我们甚至可以去写文字颜色,背景颜色边框等,我们可以把伪元素完全当成行内元素*/
}
.yunmu::before{
width:100px;
heigth:100px
}/*不能设置宽高*/
before写完了我们来聊另一个需求.
我给大家剖析下我这个人,我喜欢在说话聊天结束之后添加摸摸哒.那我怎么解决这个需求
.yunmu:after{ content: "摸摸哒" }
:before和:after 最大的区别是一个在正文内容之前,一个在正文内容最后
拓展:
**它既然是一个行内元素,我们能不能把它变为一个块元素 **
可以变成块元素说明可以支持display, 不光可以支持display还可以去支持float和position.
这就相当于游览器每一个标签都默认送你了两个小盒子, 用来做css样式的拓展
页面中存在很多无意义的标签是不友好的
但是不是每个标签都存在before/after,这个盒子必须放得下内容,这个盒子必须是双标签*
单标签没有内部:就没有办法在内部创建before和after
.inner{
width: 100px;
height: 100px;
background-color: yellow;
}
.yunmu:before{
content: "云牧说"
}
.yunmu::after{
content: "摸摸哒"
}
<div class="yunmu">
<div class="inner"></div>
/*此时说明伪元素遇到块级元素,块级元素独占一行,这两行文本各自在上下两行把位置给占下来了*/
</div>
content的意义
content:是伪元素文本所在的区域
.yunmu:before{
content: "云牧说";
display:block;
width: 100px;
height: 100px;
background-color: pink
/*如果把content删掉伪元素就消失了,这里我们是不是证明我们一定要在content里面添加文本啊?
其实不是的.这里其实可以去推断content这条属性必须存在*/
}
.yunmu:before{ content=""}/*这个元素盒子依然存在*/
当不需要文本时,请写"",如果删除content样式,伪元素会消失
content:"";表示激活伪元素
我们再来看下定位position,大家肯定会想到绝对定位和相对定位,
我们但凡谈到绝对定位,我们往往会去想当前盒子所在的层级关系,我们来想想我们的伪元素的层级在哪里?
在我们选中元素之中.
A元素的伪元素在A元素的子元素的层级中.不是兄弟关系,而是父子关系
A(父) 伪元素(子)
假如我们伪元素想参照当前的盒子定位
伪元素:positon:absolute;
当前元素:position:relative;
但是我们写代码写的飘一点,我们给伪元素添加absolute,给当前元素的父级添加相对定位,这就是我们定位的知识了.
面试:如果问你伪元素和伪类的特点与区别
伪元素其实是凭空生成的一个元素,使用双冒号.
伪类:某种状态的原来的元素,使用单冒号
比如我们原来的元素鼠标悬浮上去改变样式,那我们就用伪类去表示它,只是元素处于第二状态