css选择器分为四类:选择器、选择符(后代关系的空格、>、+、~、||)、伪类、伪元素(::before、::after、::first-letter等)。
css的优先级:
css的优先级有很多划分方法,所有的方法其实都大同小异。这里将CSS优先级划分为6个等级:
CSS优先级的计算规则:0级选择器优先级数值+0,1级选择器+1,2级选择器+10,三级选择器+100
#foo a:not([ref=nofollow]){} 优先级数值:100+1+0+10 = 111
tips1:增加CSS优先级的小技巧
重复自身选择器,如以下选择器即提高了优先级,又不会增加耦合:
.foo.foo
或者如下写法:
.foo[class] 、 #foo[id]
tips2: 实现类似:first-child的效果
有如下场景,我们希望列表除了第一个第一个以外其他的都有margin-top,一般我们会这样写:
1:.cs:not(:first-child){margin-top:1em;}
2:.cs{margin-top:1em};
.cs:first-child{margin-top:0}
下面我们利用兄弟选择器:
.cs+.cs{margin-top: 1em}
tips3:实现前面兄弟选择符的效果
如下场景:输入框聚焦时,前面文字高亮显示
1:flex布局;
2:float浮动;
3:absolute绝对定位;
4:direction属性实现,代码如下:
class="cs-direction">
class="cs-input">
.cs-direction{
direction: rtl
}
.cs-direction .cs-input,.cs-direction .cs-label{
direction: ltr;
}
.cs-label{
display:inline-block;
}
:focus + .cs-label{
color: darkblue;
text-shadow: 0 0 1px;
}
注意:使用direction属性时,针对的必须为内联元素,因此,对于块级元素需进行转化为内联
[attr]
[attr = ''val']
[attr ~= 'val']
[attr ^= 'val']
[attr $= 'val']
[attr *= 'val']
1:手型经过伪类:hover(支持所有HTML元素)
一个简单的应用场景:当鼠标经过a标签时,'显示' 文字显示,因为:hover是即时的,所以通过transition对visibility进行过渡(trantion对display不起作用)起到时延作用。
class="icon-delete" data-title="显示">删除
.icon-delete{
display: inline-block;
height: 20px;
position: relative;
}
.icon-delete::before{
content: attr(data-title);
position: absolute;
bottom: 30px;
left: 0;
}
.icon-delete::before,
.icon-delete::after {
transition: visibility 0s 0.2s;
visibility: hidden;
}
.icon-delete:hover::before,
.icon-delete:hover::after {
visibility: visible;
}
纯hover显示浮层的体验问题:纯hover显示浮层确实很方便,但是如果鼠标坏了,或者是触屏设备通过Tab来切换,如果是一个下拉列表,那么久完全瘫痪了,我们可以通过增加:focus来优化css,上述代码可以优化为:
class="icon-delete" data-title="删除">删除
.icon-delete{
display: inline-block;
height: 20px;
position: relative;
}
.icon-delete::before{
content: attr(data-title);
position: absolute;
bottom: 30px;
left: 0;
}
.icon-delete::before,
.icon-delete::after {
transition: visibility 0s 0.2s;
visibility: hidden;
}
.icon-delete:hover::before,
.icon-delete:hover::after {
visibility: visible;
}
.icon-delete:focus::before,
.icon-delete:focus::after {
visibility: visible;
transition: none;
}
但是,上述并没有解决所有的问题,如果浮层的内部有链接或者按钮的话,使用:focus浮层内的连接或者按钮是无法被点击的,因为Tab在切换焦点元素的时候,浮层会失焦而迅速隐藏。这时需要另外一个伪类:focus-within来解决,详细我们在下面讨论。
2:激活伪类:active
:active可以用于设置元素激活状态的样式,可通过点击鼠标主键,也可以通过手指或者触控笔点击触摸屏触发激活状态。具体表现为 点击按下触发,点击抬起取消。:active支持所有HTML元素
:active的不足之处:
按钮的通用:active样式技巧(主要应用移动端)
在桌面端可以通过:hover来反馈状态变化,移动端只能通过:active来反馈,移动端有很多需求点击反馈链接跟按钮,有如下通用技巧:
[href]:active,button:active{
box-shadow: 0 0 0 999px rgba(0,0,0,.05);
}
[href]:active,button:active,[type=reset]:active,[type=button]:active,[type=submit]:active{
background-image: linear-gradient(rgba(0,0,0,.05),rgba(0,0,0,.05));
}
3:焦点伪类:focus(支持IE8+)
:focus只能匹配特定的元素,包括:
那么如何让普通的元素也可以用:focus伪类呢?
设置HTML tabindex属性,如下写法:
<div tabindex='-1'>内容div>
<div tabindex='0'>内容div>
<div tabindex='1'>内容div>
如果期望
class="cs-small" tabindex='0'>
.cs-small{
display: inline-block;
width: 10px;
height: 10px;
background: green;
};
.cs-big{
display: inline-block;
width: 50px;
height: 50px;
background: green;
margin-left: 10px;
display: none;
};
:focus + .cs-big{
display: inline-block;
}
实际上,使用tabindex也并不是那么完美,在ios safari浏览器下,元素处于focus状态后,除非有其他可聚焦的元素转移焦点,否则会一直保持聚焦状态。解决方法只需要再套个父盒子,设置tabindex=‘-1’,同时该复盒子需要取消outline样式(outline:0 none;)
4:整体焦点伪类:focus-within(移动端以及非IE浏览器)
:focus-within功能通:focus类似,但是:focus是对当前元素而言,:focus-within在当前元素或者当前元素的子元素处于聚焦状态都会匹配。
例::focus-within 实现无障碍访问的下拉列表,解决上面:focus在浮层里也有链接无法Tab切换的问题:
class="cs-bar">
class="cs-details">
'javascript:void(0)' class="cs-summary">我的消息
class="cs-datalist">
class="cs-datalist-a">我的回答class="cs-datalist-sup">12
class="cs-datalist-a">我的私信
cs-bar {
background-color: #e3e4e5;
color: #888;
padding-left: 40px;
margin-bottom: 200px;
}
.cs-details {
display: inline-block;
text-align: left;
}
.cs-summary {
display: inline-block;
padding: 5px 28px;
text-indent: -15px;
user-select: none;
position: relative;
z-index: 1;
}
.cs-datalist {
display: none;
position: absolute;
min-width: 100px;
border: 1px solid #ddd;
background-color: #fff;
margin-top: -1px;
}
.cs-datalist-a {
display: block;
padding: 5px 10px;
transition: background-color 0.2s, color 0.2s;
color: inherit;
}
.cs-datalist-a:hover {
background-color: #f5f5f5;
}
.cs-datalist-a:active {
background-color: #f0f0f0;
color: #555;
}
.cs-datalist-sup {
position: absolute;
color: #cd0000;
font-size: 12px;
margin-top: -0.25em;
margin-left: 2px;
}
.cs-details:focus-within .cs-summary,
.cs-summary:hover {
background-color: #fff;
}
.cs-details:focus-within .cs-datalist {
display: block;
}
:link伪类(基本被a标签取代,不做讨论)
:visited伪类(怪癖最多的CSS伪类)
<a href=''>文字<small>small>a>
small{
color: white;
}
small:after{
content: 'visited';
}
a:visited small{
color: lightskyblue;
}
a{
color: blue;
}
a:visited{
color: red;
background-color: gray;
}
以上代码设置只会使color生效。
:any-link伪类(IE9+)
两大特性:
1.匹配所有设置了href的连接元素,包括、、
2.匹配所有匹配:link伪类或者:visited伪类的元素(:link只匹配没有访问过的连接)
目标伪类:target
URL锚点可以跟页面中元素的id匹配进行锚定,例:
<div>
<p id='cs-first'>第一行,id:cs-firstp>
<p id='cs-second'>第二行,id:cs-secondp>
<p id='cs-last'>第三行,id:cs-lastp>
div>
p:target{
font-size: bold;
color: skyblue;
}
通过链接的hash值就可以匹配到对应的元素
:root伪类
在html中:root等同于html元素;
:empty伪类
若元素有注释或者空格、换行等都是不能匹配到的
::before、::after都可以插入内容,但是不会影响:empty的匹配
:empty的实际应用
<dl>
<dt>姓名:dt><dd>张三dd><br/>
<dt>年龄:dt><dd>dd><br/>
<dt>身高:dt><dd>178cmdd>
<dl>
dt,dd{
display: inline-block;
}
dd:empty:before{
content: '暂无';
}
子索引伪类
适用于动态匹配场景,可以匹配制定索引序号的元素。参数可以是关键字(odd/even),也可以是函数符号。
函数符号形式如下:
表示当前标签类型元素第一个和最后一个
:nth-of-type与:nth-child的不同之处::nth-of-type匹配的是所有相同标签的兄弟元素,而另一个无视标签类型。
<div>
<h3>标题一h3>
<p>段落一p>
<p>段落二p>
<h3>标题二h3>
<p>段落三p>
<p>段落四p>
div>
p:nth-child(2n+1){
color: red;
}
p:nth-child(4n){
color: darkblue;
}
p:nth-of-type(2n+1){
color: skyblue;
}
图中,第2、5行为浅蓝色,第三行为红色。
否定伪类:not()
:not()主要的应用场景为重置CSS
例:input:not(:disabled):not(:read-only)()
表示匹配所有不处于禁用,也不是只读状态的input
例: 列表一行5个,每个都向右有空隙,每一行的最后一个没有空隙;
li:not(:nth-of-type(5n+1)){
margin-right: 10px;
}
任意匹配伪类:is()
例:
.cs-a img,.cs-b img,.cs-c img,.cs-d img{
border: 1px solid skyblue;
}
可以简化为如下:
:is(.cs-a,.cs-b,.cs-c,.cs-d) img{
border: 1px solid skyblue;
}
:where()、:has()
输入控件状态:
readonly与disabled的区别:
设置readonly的输入框不能输入内容,但是可以被表单提交;
设置disabled的输入框不能输入内容美也不能被表单提交。
表示当输入框的placeholder内容显示的时候,匹配输入框
由于其只在内容为空值状态的时候才显示,所以我们可以借助placeholder-shown伪类来判断一个输入框是否有值。
例: 输入框没有值得时候显示空值提示
input:placeholder-shown + small:before{
content: '尚未输入验证码';
color: red;
}
输入值状态:
输入值验证: