1. 问题描述
今日看web前端视频之小米官网实战案例,过程中有一个效果(下拉层),讲师讲解时翻车了,最后讲师发现是css声明部分代码位置写反了,问题解决了,但暂停视频反复检查也不知道具体清晰的原因,虽然效果上可以满足案例效果,但还是一知半解,不知所措,本以为是哪些基础知识掌握不牢,于是想着私下做一个demo研究一下。对于基础阶段,任何问题,任何疑问都要尽可能的解决,不留疑惑。
本以为问题出现在选择器
方面,最后发现可能是某些原理之前理解错了,或者没有理解。明白之后,感觉对某些知识有了新的认知。
案例效果具体描述(简化)
HTML代码:
我是box
每个人都不得不面对这些问题。 在面对这种问题时, 在这种困难的抉择下,本人思来想去,寝食难安。 非洲在不经意间这样说过,最灵繁的人也看不见自己的背脊。
CSS代码:
/* 为span设置默认样式 */
.show {
color: red;
background-color: #bfa;
}
/* 当鼠标移入到 .show时,样式变成小手 */
.show:hover {
cursor: pointer;
}
/* 目的: 当鼠标移入到 .show时,显示 .box2的内容 */
.show:hover ~ .box1 > .box2 {
height: 100px;
cursor: pointer;
}
/* 当鼠标移出 .show外,仍显示下拉内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10=20 */
.box2:hover {
height: 100px;
cursor: pointer;
background-color: rgb(190, 190, 236);
}
/* 默认时 .box2的高度为0,且裁剪溢出内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10 =20 */
.box1 .box2 {
height: 0;
overflow: hidden;
background-color: orange;
}
效果(非预期效果):
预期效果:
2. 问题分析
关于实现非预期效果
,首先需要阐述一下关键一步,实现预期效果
的需求:
当鼠标移入span文字区域“我是box”时,弹出下拉层,当鼠标移出span时,下拉层继续显示。这要求hover
不能仅设置在span
,还需设置给这个下拉层本身。问题出现就出现在设置给下拉层本身box2
存在某些属性被覆盖了。
/* 当鼠标移出 .show外,仍显示下拉内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10=20 */
.box2:hover {
height: 100px;
cursor: pointer;
background-color: rgb(190, 190, 236);
}
/* 默认时 .box2的高度为0,且裁剪溢出内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10 =20 */
.box1 .box2 {
height: 0;
overflow: hidden;
background-color: orange;
}
当代码顺序设置如上,经过分析,上面样式表的选择器优先级是20
,而下面的选择器优先级也是20
,即存在对一个对象(元素)设置样式,优先级相等,根据优先级原则(就近原则),优先使用后面
编写的样式表。
模拟一下过程:
- 一开始
height:0
,overflow:hidden
则元素不显示,自然没有颜色orange
- 当鼠标移入时才使用到样式表(
hover
),此时注意此时才使用height:0
这个值,这个值和下面的0
冲突了,使用后面的代码的值,所以heigh
还是0
,并且overflow:hidden
,则元素不显示。
这样会导致鼠标移出box2
元素还是不显示。
将代码调换顺序,再看预期效果
代码:
/* 默认时 .box2的高度为0,且裁剪溢出内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10 =20 */
.box1 .box2 {
height: 0;
width: 100px;
overflow: hidden;
background-color: orange;
}
/* 当鼠标移出 .show外,仍显示下拉内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10=20 */
.box2:hover {
height: 100px;
cursor: pointer;
background-color: rgb(190, 190, 236);
}
模拟过程:
- 同样以下面的样式表为先,由于
hover
没有启用(只有鼠标移入才启用),而默认状态的设置.box1, box2
被启用,所以此时height
的值是0
。 - 当鼠标移入时,此时的
hover
才启用,height:100px
生效,因为是后面的代码,优先级高,所以采用这个值,效果上,元素显示。
3. 问题解决
将:hover
伪类的样式表放置后面
/* 默认时 .box2的高度为0,且裁剪溢出内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10 =20 */
.box1 .box2 {
height: 0;
width: 100px;
overflow: hidden;
background-color: orange;
}
/* 当鼠标移出 .show外,仍显示下拉内容 */
/* 给 .box2设置样式,此时 选择器优先级是 10+10=20 */
.box2:hover {
height: 100px;
cursor: pointer;
background-color: rgb(190, 190, 236);
}
对于这样的场景需求,首先调整优先级,如果优先级一样,则将伪类:hover
的样式表放置后面
的位置。
总结分析:
关于这个问题,主要不是优先级问题会踩坑,而是样式表什么时候生效
。
错误的以为: “当鼠标移入:hover
生效,则不用考虑下面的默认样式表,不用和下面的height:0
比较”
容易忽视的地方是,以为伪类:hover
和其他选择器可以独立处理: “既然:hover
是鼠标移入才生效,那等到该移入的时候生效就可以,不用考虑什么优先级
”。其实是优先级都是一样的原则,当冲突时都需要抉择,关键就是样式表生效时间,正是:hover
是鼠标移入才生效,样式表代码也生效,此时存在样式值的冲突,而不是一开始就有冲突。
所以并不是说当鼠标移入时,就直接
生效伪类选择器样式。
注意状态的不同:
- 伪类选择器是
非默认
状态,样式表的值当伪类生效才生效。 - 一般选择器是
默认
状态,即设置后,立即
生效。
⚠️也这说明选择器
并不是选择某个元素
,而是选择 某个状态下的元素
。即元素是存在默认样式的,就存在默认的状态。更贴近点,选择器是选择状态的,状态才有“可选性”,因为元素都是同一个。
这里案例错误,让我意识到了存在默认状态和非默认状态之分,对于选择器的「选择」也有更进一步的理解
优先级是当产生了冲突时,才需要考虑优先级(如正确代码的最后的样式表,伪类就不是一开始会和其他样式表产生冲突,哪怕伪类的样式表优先级高,也并不会选择height:100px
的,当使用到伪类,值生效,值发生冲突)。
记住当选择器生效时,值才生效,效果才生效。
相关文章: