超连接的lvha原则

一.lvha
实际上应该是lvfha,即:浏览器

a:link {/* 未访问过的超连接的样式 */}
a:visited {/* 访问过的超连接的样式 */}
a:focus {/* 拥有焦点的超连接的样式 */}
a:hover {/* 鼠标悬停的超连接的样式 */}
a:active {/* 被用户输入激活的超连接的样式 */}

这5个都是伪类,表示5种状态,其中link与visited是超连接专用的,能够分类到连接伪类,而focus,hover和active除了用于超连接还适用于其它元素,称为动态伪类ide

lvfha原则是说对超连接(带href属性的a标签)应用上面的5个伪类时,应该遵照这种固定的顺序代理

二.伪类与伪元素
伪类像类同样,用来选择DOM树上本就存在的某个元素。选择条件有两种:code

状态:元素是否处于某种特定状态,例如用户曾访问过(link/visited),此刻拥有焦点(focus),处于某种语言环境(lang)事件

结构:元素是否知足某种DOM结构方面的要求,例如身为长子的元素(first-child),以及CSS3新增的身为根元素的元素(root)和一大堆的结构化伪类(nth--of-type等等)文档

伪元素更像元素一些,用来选择DOM树上本不存在的元素(或某个元素的一部分)。比起伪类的繁荣你们族,伪元素就显得有些伶仃了,到目前(2017/11/4)为止,CSS3规范中仍然只有4个伪元素(CSS2.1就是4个):it

首字母:选择元素包含的文本内容的首字母(文本内容包含来自子元素的,也就是说能够跨标签层级选择文本)io

首行:选择元素包含的文本内容的首行(同上)class

before:用于内容生成,在指定元素内容开头的位置生成一个元素(生成的内容位于元素内容区里)表单

after:用于内容生成,在指定元素内容结尾的位置生成一个元素(同上)

伪类与伪元素最大的区别是要选择的目标内容是否存在于DOM上,存在就是伪类,不存在就属于伪元素。换个角度看,想要为文档的某部份内容指定样式,那么先要(经过选择器)选中这部份内容,此时会遇到两种状况:

目标内容刚好被某个标签包起来了,对这整个标签设置样式就能达到目的

目标内容先后没有标签圈定范围,没法直接设置样式,须要插入一个临时标签把目标内容圈起来,再对这个临时标签设置样式

第一种状况经过伪类来处理,用伪类选择器把处于某种状态或具备某些结构特征的现有元素找出来,再应用样式。第二种状况要么手动插入额外标签,转化成第一种状况(有些场景经过添标签也作不到,好比首行,或者跨标签层级的场景),要么经过伪元素来解决,至关于请浏览器帮忙插入虚拟标签圈定目标内容,再应用样式

P.S.关于CSS3选择器的更多信息,请查看CSS选择器分类总结

三.a标签的6种状态
lvfha伪类给超连接提供了5种状态,第6种是指锚点,而不是超连接

link伪类存在的意义之一就是把超连接与锚点区分开,link伪类只匹配具备href的a标签(即超连接),而非锚点

通常桌面浏览器环境下,a标签的6种状态及对应的触发行为分别是:

a {/* 处于任意状态的a标签,不管是超连接仍是锚点 */}
a:link {/* 未访问过的超连接 */}
a:visited {/* 访问过的超连接,点击超连接再返回当前页,这个超连接就处于visited状态 */}
a:focus {/* 得到焦点的超连接,tab键选中超连接或者长按超连接再移开鼠标 */}
a:hover {/* 鼠标悬停的超连接,鼠标通过超连接时或悬停在超连接上时,这个超连接就处于hover状态 */}
a:active {/* 处于激活状态的超连接,鼠标在超连接上按下时 */}

其中focus, hover, active不太好区分,focus是一种延续性状态,而hover, active是短暂性状态,进一步细分hover, active的话,后者是前者的一种特殊状态(触摸设备除外),例如:

a:focus {border: 1px solid green;}
a:hover {border-color: red;}
a:active {border-style: dashed;}

那么下列连续操做对应的状态和样式分别是:

按下tab键 -> focus -> 绿色实线边框
点击其它空白处 -> a & link | visited -> 对应样式
鼠标划过期 -> hover -> 无边框
鼠标悬停时 -> hover -> 无边框
鼠标按下 -> focus & hover & active -> 红色虚线边框
鼠标移到超连接以外再抬起 -> focus -> 绿色实线边框
(不点击其它地方的话,超连接将一直处于focus状态)
鼠标划过期 -> focus & hover -> 红色实线边框

正由于focus是一种延续性状态,因此要放在短暂性的hover, active以前,不然最后鼠标划过期不会表现出hover样式(根据层叠规则,先声明的hover会被focus覆盖掉)

由于focus, hover, active3个状态有重叠,因此建议保持特定的声明顺序,让层叠结果符合样式表编写者的预期。而link和visited是互斥的,不存在重叠,因此两者的相对顺序并不重要(vlfha也是合理的,“爱恨”顺序只是好记)。一样,因为link/visited是永久性状态,为了让短暂性状态和持续性状态有表现机会,就把focus/hover/active放在后面,让长状态的层叠优先级更低一些,因此就有了lvfha原则

另外,规范没有明确说明focus, hover, active对应的状态的起止条件:

CSS没有定义哪些元素能够处于上面的状态,以及这些状态怎样进入和离开。脚本能够改变元素是否对用户事件作出响应,而且不一样的设备和UA指向和激活元素的方式不一样

CSS 2.1没有定义若是一个’:active’或者’:hover’元素的父级是否是也处于这种状态

(摘自5.11.3 动态伪类: :hover,:active与:focus)

因此不能肯定动态伪类的触发行为,也没法肯定这几个伪类适用于哪些元素(表单元素、div等可能支持也可能不支持),都取决于用户代理的实现

四.组合伪类
建议遵循lvfha顺序是考虑层叠规则,不然可能会被覆盖,致使同名规则无效。例如:

a:hover {text-decoration: underline overline;}
a:link {text-decoration: none;}
a:visited {text-decoration: none;}

hover样式(小技巧:鼠标划过期同时显示上划线和下划线)永远不会生效,由于text-decoration属性总会被下面两条之一覆盖掉

固然,前提条件是样式规则存在冲突(同名属性且来源、重要性、特殊性都相同)时,根据声明顺序来解决冲突,此时lvfha顺序才真正起做用。换句话说,若是不存在样式冲突,声明顺序并不重要

也就是说,经过其余方式避免样式冲突发生,就不用遵照lvfha顺序了,例如经过组合伪类来把状态展开:

/* 不要求顺序 */
:link
:visited
:link:hover
:visited:hover
/* 要求顺序 位于上2行以后 */
:link:active
:visited:active
/* 或者替掉上2行 不要求顺序 */
:link:hover:active
:visited:hover:active

展开以后就没有重叠状态了,让每条规则都变成严格互斥的,天然就没冲突了

P.S.注意:由于IE6-不能正确处理组合伪类,只认最后一个,因此lvha应用更广(实际上组合伪类的语义更明确,没有“隐藏的奇怪规则”)

另外,能够层叠规则来实现特殊效果,例如:

// 用lhva实现只有未访问的连接才有hover效果
a:link {}
a:hover {}
a:visited {}
a:active {}

颇有意思的小技巧,至关于:

a:link:hover {}

这就体现了组合伪类语义明确的优点

联系ayqy

相关文章
相关标签/搜索