13-高级选择器和伪元素

伪类

: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,给当前元素的父级添加相对定位,这就是我们定位的知识了.

面试:如果问你伪元素和伪类的特点与区别

伪元素其实是凭空生成的一个元素,使用双冒号.

伪类:某种状态的原来的元素,使用单冒号

比如我们原来的元素鼠标悬浮上去改变样式,那我们就用伪类去表示它,只是元素处于第二状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值