『極限版』不摻水,用純 CSS 來實現超颯的表單驗證功能

去年的時候寫過一篇文章 純CSS實現表單驗證 ,在發表以後不久就有網友跟魚頭說,打算拿我這篇文章做團隊內部分享。css

當時聽到這個消息以後,在屏幕前的魚頭笑咧了嘴,但這位童鞋的下一段內容,就讓我立刻笑不起出來了。html

不過由於初始化狀態是這樣的:git

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation/invalid.png

因此但願我可以改一下,改爲這樣:github

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/1.png

只有在進行輸入且輸入內容不對的時候才展現錯誤信息。api

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/2.jpg

這位童鞋:「因此這功能能實現嗎?」瀏覽器

我:「。。。。。。」post

既然有童鞋這麼看得起魚頭,還打算拿魚頭的 DEMO 來做內部分享,那總得硬着頭皮來實現這個功能。ui

首先咱們來看一下最終成果圖:spa

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/3.gif

DEMO 在線查看地址:https://codepen.io/krischan77...code

各位讀者童鞋,來跟魚頭一塊兒拆分下功能實現:

HTML

首先咱們來看 HTML 的源碼

<form class="form" id="form" method="get" action="/api/form">
    帳號:
    <input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required />
    <span class="f-tips">請輸入正確的帳號</span>
    <br />
    密碼:
    <input data-title="密碼" placeholder="請輸入正確的密碼" pattern="\w{6,10}" name="password" type="password" required />
    <span class="f-tips">請輸入正確的密碼</span>
    <br />
    <input name="button" type="submit" value="提交" />
</form>

這裏面的 HTML 標籤都比較常規,可是咱們要注意下 <input /> 所攜帶的幾個屬性:

required

<input required/> 中的 required 是一個布爾屬性,用來告訴瀏覽器這個 <input> 是不是必填項。

咱們來康康DEMO:

<section class="section">
    <h1>請輸入信息</h1>
    <form action="/userInfo">
        <input name="text" type="text" required />
        <input name="submit" type="submit" value="提交信息">
    </form>
</section>

效果以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/4.gif

兼容性以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/7.png

原生樣式體驗也是不錯的。

pattern

再來 pattern 屬性。

<input pattern=""> 用於校驗輸入 value 是否有效。

咱們康康DEMO:

<section class="section">
    <form>
        <h1>請輸入 我愛魚頭</h1>
        <input name="text" type="text" pattern="我愛魚頭"  required />
        <button type="submit">提交信息</button>
    </form>
</section>

效果以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/5.gif

兼容性以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/css-form-validation2/6.png

不得不感慨,原生組件的能力也是很強的。

CSS

接下來咱們康康CSS的部分,源碼以下:

:root {
    --error-color: red;
}
.form > input {
    margin-bottom: 10px;
}
.form > .f-tips {
    color: var(--error-color);
    display: none;
}
input[type="text"]:invalid ~ input[type="submit"],
input[type="password"]:invalid ~ input[type="submit"] {
    display: none;
}
input[required]:focus:invalid + span {
    display: inline;
}
input[required]:empty + span {
    display: none;
}
input[required]:invalid:not(:placeholder-shown) + span {
    display: inline;
}

咱們重點介紹如下幾個 CSS 選擇器:

:invalid 與 :valid

判斷有效性的僞類選擇器(:valid:invalid)匹配有效或無效,<input><form>元素。

:valid僞類選擇器表示值經過驗證的<input>,這告訴用戶他們的輸入是有效的。

:invalid僞類選擇器表示值不經過經過驗證的<input>,這告訴用戶他們的輸入是無效的。

例子以下:

<style>
    input:valid {
        outline: 1px solid green;
    }

    input:invalid {
        outline: 1px solid red;
    }
</style>
輸入文字:
<input type="text" pattern="[\w]+" required />
<br />
輸入電話號碼:
<input type="tel" pattern="[0-9]+" required />

效果以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/selectors-4/valid-demo.gif

兼容性以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/selectors-4/valid.png

:placeholder-shown

:placeholder-shown 僞類 在 <input><textarea> 元素顯示 placeholder text 時生效。

例子以下:

<style>
    input {
        border: 2px solid black;
        padding: 3px;
    }

    input:placeholder-shown {
        border-color: silver;
    }
</style>
<input placeholder="Type something here!">

效果以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/selectors-4/placeholder-shown-demo.png

兼容性以下:

https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/css/selectors-4/placeholder-shown.png

實現邏輯

有了上面的幾個 <input /> 屬性以及 css 選擇器的僞類說明,那麼這個純CSS實現表單驗證的功能就變得簡單多了。

咱們先來整理下功能要求:

  1. 初始化狀態:不展現提交按鈕以及錯誤提示
  2. 清空輸入狀態:不展現提交按鈕以及錯誤提示
  3. 輸入錯誤狀態:輸入框輸入錯誤時,展現錯誤提示
  4. 輸入正確狀態:輸入框輸入正確時,隱藏錯誤提示,展現提交按鈕

初始化狀態

首先咱們知道,初始化 時,是沒有提示信息的,因此提示信息能夠直接隱藏,至於提交按鈕,咱們就利用 :invalid 來隱藏,由於初始化的 input.value 內容是不匹配的。因此咱們有:

<style>
    .form > .f-tips {
        color: var(--error-color);
        display: none;
    }
    input[type="text"]:invalid ~ input[type="submit"],
    input[type="password"]:invalid ~ input[type="submit"] {
        display: none;
    }
</style>
<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required />
<input data-title="密碼" placeholder="請輸入正確的密碼" pattern="\w{6,10}" name="password" type="password" required />
<span class="f-tips">請輸入正確的密碼</span>

清空輸入狀態

清空輸入狀態 也比較簡單,能夠直接用僞類選擇器 :empty 來判斷,只要內容爲空,則隱藏錯誤信息,因此咱們有:

input[required]:empty + span {
    display: none;
}

輸入錯誤狀態

初始化 時已經隱藏了錯誤信息,而 初始化 其實也是依賴於 輸入錯誤 這個狀態,不過好在咱們有僞類選擇器 :focus ,它表示得到焦點的元素(如表單輸入),因此咱們有:

input[required]:focus:invalid + span {
    display: inline;
}

雖然咱們不能經過 輸入錯誤 這個狀態來處理,可是咱們能夠監聽用戶聚焦的行爲來實現。

可是這麼作有個弊端,就是當我在另一個輸入框輸入信息的時候,錯誤提示也會消失,因此咱們還須要判斷是否有 placeholder,輸入了 value ,天然沒有 placeholder ,因此咱們有:

input[required]:invalid:not(:placeholder-shown) + span {
    display: inline;
}

輸入正確狀態

當完成上述三個狀態的實現以後, 輸入正確 的狀態就能夠不用編寫了,由於不匹配錯誤的,就是匹配正確。

總結

一個完整的 純CSS表單功能 就這麼完成了,DEMO地址在這:

https://codepen.io/krischan77...

因爲實際項目的複雜度,這個功能不必定直接用起來,可是裏面的知識點,思路咱們都是能夠複用的。

不得不感慨,現在 htmlcss 的能力變得強大了起來,只要咱們願意散發思惟,必定能編寫出更多有意思,有價值的效果。

歡迎你們多方嘗試!

參考資料

  1. whatwg 4.10.5 The input element
  2. 純CSS實現表單驗證
  3. 『真香警告』這33個超級好用的CSS選擇器,你可能見都沒見過。
  4. CSS 選擇器
相關文章
相關標籤/搜索