原文連接:https://yunxiaomeng.blog.csdn.net/article/details/107575226css
背景html
前兩天在寫原生上傳文件時用到了input的 type="file" 按鈕,寫完之後就感受彆扭的一批:這玩意本身的樣式實在難看,可是它又不支持自定義樣式。最後「靈光一現」,想到:能夠設置其透明度爲 opacity: 0; 而後拿其餘的標籤覆蓋上去:好比 input type="text" 、好比 div、好比 label 。。。前端
項目地址:http://htmlpreview.github.io/?https://github.com/1314mxc/compress/blob/master/index.htmlgit
(這個工具中的全部「上傳框」皆是input) 最近正好在搞這個「圖片上傳」、「壓縮」的事情:H5之後,input就支持了accept —— 選擇文件類型,還有一些值好比:「multiple」 可設置「只選擇文件夾」。github
這兩個問題也造就了這篇文章:web
先說下input中的一些問題:瀏覽器
不是全部的 input 都支持「placeholder」,好比:type="date" 。嘗試了一下,雖然H5原生的date功能強大,但對placeholder還真沒有什麼解決方案。不過,參照本文開篇的思路,咱們一樣能夠先寫一個 type="text" ,而後用0級DOM事件 onfocus (在觸焦時)將其變爲date:onfocus="(this.type='date')" 。
這種方法在PC端簡直完美,但在一些手機上須要【點擊兩次】纔有效 —— 猜想可能仍是移動端響應click的問題。因此還有一種方案:在input上覆蓋一個div,當點擊時去操控 input 的事件和響應!微信
咱們都知道,在input中,當輸入過一次時,下一次輸入會有提示 —— autocomplete 。但這也會帶來一些效果:input 將背景「自動」變爲黃色。哦,這可不是什麼bug。是 input 對 paste 的響應樣式罷了。咱們能夠用「autocomplate='off'」 / 僞類:app
input:-webkit-autofill{ -webkit-box-shadow: 0 0 0px 1000px white inset; }
來去除效果。ide
上面這段CSS代碼意思爲:將邊框陰影設爲白色,而後向內擴展,覆蓋原來應該顯示的「黃色」。」
HTML5約束驗證
HTML5對於input增長了不少標籤屬性,和事件。其中最著名的莫過於「表單驗證validate」了:當你獲取到validitestate對象(經過DOM.validity)後,這裏面有幾個很重要的屬性:
input還有一個比較「特別」的:search。這種類型的input,在輸入時右側會有一個「帶圓圈的×」,那麼確定會有人以爲不想要 or 很差看了,咱們也能夠用僞元素來將其去掉:
input[type="search"]::-webkit-search-cancel-button{ -webkit-appearence: none; //下面可自定義樣式 }
一樣的還有input的button、普通input的邊框陰影均可以用相似代碼去除!」
看好了,上面是 -webkit前綴!幾乎不用想,在手機上必定會出現一些「彷佛莫名其妙的問題」:比較推薦的是,用div+absolute來從新寫一個「小叉號」,用JS控制對應事件。
這裏「比較推薦」是「在解決問題的辦法」中比較而得。事實上,仍是推薦用原生的「取消按鈕」。」
哦對了,既然有了maxlength,爲何W3C還保留了max?由於在 type="number" 中,maxlength是沒啥用的。。。(就很尷尬) 更尷尬的是:max只能控制「上限值」 —— 好比只能輸入5位,則寫爲:max="99999" ,並且他的效果仍是體現到「獲取到的值」上。這也就是說:你在沒有任何提示下,在你眼睛所能看到的input裏,你能夠輸入無限長度。
input的高度能夠用height或者padding來改變 —— 事實上,幾乎全部的行內(非替換)元素都是用padding改變高度的(行內替換元素能夠設置height)」
其實說了這麼多,HTML+CSS就能夠完成簡單的「表單校驗」:僞類「:valid」、「:invalid」直接做用到對應input上便可 —— 基於pattern + required的基礎功能驗證。
//HTML部分 <input id="mail" type="email" required placeholder="請輸入郵箱" /> <span class="title">郵箱</span> <label for="mail"></label> //css部分 input:focus,input:hover{text-indent: 2px;} input:focus +span.title,input:hover +span.title{transform: translateX(-120%);} input:valid ~label::after{content: '你輸入郵箱正確!';} input:invalid ~label::after{content: '你輸入郵箱錯誤';} input:valid{border: 1px solid green;} input:invalid{border: 1px solid red;}
甚至是用僞類 optional 、required 設置「選填」和「必填」的簡單樣式:
input:required +label::after{content:'(必填)';} input:optional +label::after{content:'(選填)';} input:required:focus{box-shadow: 0 0 3px 1px #aa0088;} input:optional:focus{box-shadow: 0 0 3px 1px #999;}
你甚至能夠在input中加入0級DOM事件oninvalid,在其中直接調用 this.setCustomValidity("...") 來做爲填錯時提示。這很方便。
作完這些,你很滿意。可是你的UI設計師可能要發火了 —— 不一樣的提示框UI實在是太... 咱們須要自定義提示氣泡!
function stopBubble(form){ form.addEventListener("invalid",function(e){ e.preventDefault() },true) //submit事件中監聽:若是提交時驗證不經過 form.addEventListener("submit",function(e){ if(!this.checkValidity()){ e.preventDefault() } },true) }