之前一段時間,基於對 next
與 graphql
的調研,再加上本人的興趣,我作了一個站點,也做爲我之後各類技術折騰,實踐以及興趣交匯的試驗田。javascript
最近我須要在個人實驗田使用 jwt
實踐校驗碼的功能。校驗碼,就是指註冊時郵箱或者短信的校驗碼。須要校驗碼則須要有登陸註冊,而在登陸註冊時,爲了多寫一些 CSS,我決定實現一個 Material Design 的表單過渡效果。css
實現效果見 詩詞絃歌 - 登陸html
開始以前,你先看看是否定識如下幾個選擇器。若是不,那麼經過本文你能夠學習到如下幾個選擇器,以及他們的試用場景html5
:not(:empty)
input:not([value=""])
input:valid
input:not(:placeholder-shown)
本文地址見 shanyue.tech/post/login-…java
至於 Material Design 是什麼樣的效果,如上所示。實現以上效果,能夠簡單把問題歸結爲如下兩點的實現node
直接把 html 和 css 代碼貼上來,先來完成簡單的功能瀏覽器
label 置於 input 後邊,方便經過 ~
與 +
選擇器定位。app
form
.input-wrapper
input[type="text"]
label
.input-wrapper
input[type="password"]
label
複製代碼
CSS 代碼以下,label 初始時經過絕對定位置於 input 的 placeholder 位置,input 得到焦點時的 label 的 CSS Selector 也很容易經過 input:focus + label
肯定ide
label {
/* 定位到input框中 */
position: absolute;
bottom: 10px;
left: 0;
font-size: 1.2em;
color: #ccc;
transition: all ease 0.3s;
pointer-events: none;
}
input:focus + label {
/* 定位到 input 上方 */
color: #f60;
font-size: 0.8em;
transform: translateY(-150%);
}
複製代碼
已經在 20% 的時間內完成了 80% 的工做量,還有剩下 20% 的問題總結以下post
input
非空值時的 CSS Selectorpointer-events
用來控制鼠標點擊的行爲,若是要實現透過 label
點擊,能夠設置該屬性爲 none
。
label {
pointer-events: none;
}
複製代碼
我條件性反射想到用這個來匹配值非空的 input。但我仔細查了下文檔,發現它是不適用的。
根據 empty-pesudo Selectors 描述爲
The :empty pseudo-class represents an element that has no children at all. In terms of the document tree, only element nodes and content nodes (such as DOM text nodes, CDATA nodes, and entity references) whose data has a non-zero length must be considered as affecting emptiness;
我來大體翻譯一下,若是一個元素, 它的子節點數爲 0,那麼它將匹配到 :empty
。這和 input 的 value 風馬牛不相及了。
那如何獲取元素 element
子節點的個數呢? 使用 element.childNodes.length
。
參考 stackoverflow :not(:empty) CSS selector is not working?
那麼再簡單粗暴些,直接匹配屬性 value 是不就能夠了。
No. 不能夠。input 中的顯示值並不等同與屬性 value。
那這就引出了下一個問題
用如下代碼測試一下
<input type="text" id="input">
複製代碼
input.value // ''
input.getAttribute('value') // null
input.setAttribute('value', 4)
input.value // '4',value 值同步過來了
input.getAttribute('value') // '4'
input.value = 3
input.value // '3'
input.getAttribute('value') // '4'
複製代碼
結論:
input.value
獲取值,而非 input.getAttribute('value')
input.value
爲空,那麼能夠經過 input.setAttribute('value', value)
設置值,而且會同時修改 input.value
input.value
賦值後,則使用 input.setAttribute('value', value)
無效那麼匹配值非空的 input,能夠更深理解爲 匹配input.value爲空的input
這說明在純css實現時沒法使用 input:not([value=""])
做爲選擇器
思路很簡單,同步 input.value
到 input.getAttribute('value')
<input onkeyup="this.setAttribute('value', this.value);" />
複製代碼
受控的 input
組件經過手動控制屬性 value
,來設置 input 的值。
這時再結合使用 input:not([value=""])
選擇器能夠成功控制 input 的過渡效果
而我項目中也是在使用 React
,使用這一選擇器能夠很好的知足個人需求
在 html5 中,input 的 type 新增瞭如下類型
而且添加了檢驗方式,如是否必須,正則等
這裏引入一個新的選擇器 input:required
,匹配全部擁有合法值的 input
咱們能夠對全部 input
添加 required
的標誌,此時 input:valid
的含義即匹配有值時的 input
,順利解決問題
可是使用 input:valid
也有一些限制,如如下兩點
required
,選填的也必須做爲 required
,失去了語義化,且提交時會有提示沒法正常提交在 form
的 submit
事件觸發後,會引起瀏覽器自帶的校驗提示
而 form
的 submit
事件觸發須要知足如下兩個條件
input[type="submit"]
或者 button
進行提交對於 input:valid
的兩點限制,能夠經過把 form
改爲 div
解決,此時沒法有 submit
事件,選填項也能夠正確處理。至於複雜表單校驗,則經過js控制
見名思意,:placeholder-shown
此選擇器匹配是否有 placeholder
,既然有 placeholder
,那麼 input
就沒有 value
。
它有一個必要條件,placeholder
屬性不能爲空,若是實在沒必要要能夠設置爲空字符串
<input placeholder=" " />
複製代碼
關注公衆號山月行,在這裏記錄了個人技術成長,歡迎交流