背景
之前做了一个网页,网页中的一切输入框都被设想为“取得鼠标核心时外边框稳定蓝”。倏忽某一天,产物以为如许用户体验不好,不能很显著地通知用户当前鼠标停在那里,因而请求改成“当输入框取得鼠标核心时,外边框自动变蓝;落空核心时外边框恢复原样”。
浏览器自动会给输入框input
、textarea
的outline
属性设置一个默许值,效果就是当输入框取得鼠标核心时外边框会自动带上色彩,落空核心时外边框色彩消逝。由于差别浏览器outline
属性的默许值差别,致使外边框的色彩也差别。假如不想要浏览器的outline
默许设置,只需要将 outline
属性设置为none
即可。
所以一开始听到这个需求,觉得迥殊简朴,不就是纯 CSS 的题目嘛!我只要将一切输入框的 outline
属性设置为浏览器默许的值就好了,但我想的太无邪了。。。。
1、怎样复制浏览器默许的 outline 款式
由于网页中已有的输入框的款式遍及在各个文件中,有一种异常机器的要领,那就是到每一个文件中去删撤除输入框的 outline:none
款式,如许输入框就会运用浏览器默许的 outline 款式了。然则如许做要改的处所太多了,会疯掉的!再想想有没有更费事的要领,有了!在最基本的base.css
款式文件中给输入框增加一个focus
时候的outline
款式不就处置惩罚了么。那末题目来了,该将outline
设置何值,才自动运用浏览器默许的outline
款式呢?
我第一个想到的要领是将 outline
设置为auto
,但发明只要webkit 内核的浏览器才支撑这个属性值,firefox 不支撑,由于auto
并非范例的outline
值。所以要想直接复制浏览器默许的outline
款式是做不到的。岂非我要针对每一个浏览器设置差别的outline
值,为了这么一点破需求费那末大时间?!算了,费事点的体式格局照样直接摒弃浏览器的默许outline
款式,统一将outline
设置为一种款式好了。
2、避开 outline,挑选 border
但我发明了新题目,经由过程设置outline
款式为输入框增加外边框,效果并不好。由于 outline
没有相似 border-radius
的属性来转变边角的弧度。如许就致使了一个题目:当输入框设置了border
色彩,同时border-radius
为3px
以上时,能显著的看到outline
外边框并没有和border
重合。看来设置 outline
来到达边框变蓝效果并非最好的挑选,为何不选用设置 border
来到达一样的效果呢?只要将border
再设置下 border-shadow
,那末看起来也是和outline
效果一样的,而且border
还能设置border-radius
,显现效果更满足需求。
3、怎样让任何一个元素都能 focusable
经由过程设置 border 处置惩罚了大多数输入框,但发明又有了新题目。
网页中有些输入框实在并非单一运用 input
/textarea
来完成的,这类“输入框”看起来和平常输入框并没有两样,但实在 HTML 构造是一个 div
内里包含着一个 input
/textarea
来完成的。而且输入框的边框设置在了父元素 div
上,一切当输入框取得核心时,看到的应该是父元素 div
上的边框变蓝,而不是内里的input
/textarea
的边框变蓝。
要想取得核心时父元素 div
的边框变蓝,一定可行的要领是经由过程 JS 来完成:给input
/textarea
绑定一个 focus
和 一个blur
事宜,在focus
事宜处置惩罚函数中将父元素div
的边框置蓝,在blur
事宜处置惩罚函数中将父元素div
的边框恢复原样。这类要领时相对可行的,然则我总以为应该有更简朴的,地道运用 css 完成的要领。
假如想纯真经由过程css 完成,起首想到的是用挑选器div:focus
。然则发明div
上没法运用:focus
伪类。因而我就猜测:能够并非一切的元素都是 focusable的,那末得找一份申明哪些元素 focusable的范例。
哪些元素是 focusable的?
搜刮效果:
依据 DOM Level 2 HTML范例,focusable 的DOM元素都邑有一个原生的focus()
要领,只要 focusable 的DOM 元素才有 focus 事宜,才运用:focus
伪类。具有原生的focus()
要领的DOM元素包含几种:HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement and HTMLAnchorElement。很显著,范例中遗漏了HTMLButtonElement and HTMLAreaElement。
虽然范例这么定义,但浏览器在完成时倒是别的一套。浏览器给任何一个 HTMLElement 都定义focus()
要领,但并非任何一个HTMLElement 都能取得核心(取得核心术语叫 active, 详细请参考:http://help.dottoro.com/ljqmdirr.php)。平常来说,任何一个时候HTML 文档中只会有一个active元素,但并非任何一个元素都能成为active元素。能成为active 的元素包含:
表单元素(form controllers):
input/option/textarea/button
链接元素(links):
a
标签、area
标签(必需要带href
属性,包含href
属性为空)能够被编辑的元素(包含经由过程增加
contenteditable = "true"
属性变成可编辑的状况)设置了
tabindex
属性(tabindex
值非-1)的元素window
:当页面窗口从隐蔽变成前置可见时,focus
事宜就会触发
依据搜刮效果,要想将父元素div
变成focusable,只需要在元素上设置 tabindex 属性,然后经由过程:focus
伪类设置父元素div
取得核心时的border
款式。但我发明当鼠标点击内里的 input
元素时,父元素div
并没有取得核心,取得核心的是子元素input
。
所以末了照样没能经由过程纯 css 的要领来处置惩罚这个题目,无法之下我照样经由过程js去处置惩罚了。。。。。。