CSS自动填充和验证

埃米尔·博尔科尼

我正在设计一些用户输入的样式,但遇到了一个绊脚石。

我没有反对用户使用自动完成功能(我个人讨厌在某些站点上将其关闭),因为我认为这非常方便。我知道如何用来样式化-webkit-autofill但是,自动完成将始终导致字段获得:valid状态,即使它们不应该如此。

例如,我将一个字段设置为至少5个字符长:

<input type="text" required class=namefileds id=first_name name=Name[] placeholder="Enter your first name" minlength="5">

我为有效/无效的情况设置了CSS样式:

#checkout_form input:invalid {
    padding-right: calc(1.5em + .75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: center right calc(.375em + .1875rem);
    background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}

    #checkout_form input:valid {
    padding-right: calc(1.5em + 0.75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

这很好。为了使自动填充样式更好地工作(在所有Webkit浏览器上),我添加了以下CSS规则:

@-webkit-keyframes autofillvalid {
     0%,100% {
         color: #ffcc00;
         background:none;
         padding-right: calc(1.5em + 0.75rem);
         background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
         background-repeat: no-repeat;
         background-position: right calc(0.375em + 0.1875rem) center;
         background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
    }
}

 @-webkit-keyframes autofillinvalid {
    0%,100% {
        background:none;
        padding-right: calc(1.5em + .75rem);
        background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
        background-repeat: no-repeat;
        background-position: center right calc(.375em + .1875rem);
        background-size: calc(.75em + .375rem) calc(.75em + .375rem);
    }
}

input:-webkit-autofill:valid {
     -webkit-animation-delay: 1s; /* Safari support - any positive time runs instantly */
     -webkit-animation-name: autofillvalid;
     -webkit-animation-fill-mode: both;
 }

 input:-webkit-autofill:invalid {
     -webkit-animation-delay: 1s; /* Safari support - any positive time runs instantly */
     -webkit-animation-name: autofillinvalid;
     -webkit-animation-fill-mode: both;
 }

我的问题是,如果自动填充的名称只有四个字符,那么它应该获取:invalid状态,但是自动填充始终会生成:valid状态。其他状态选择器看起来可以正常工作,例如::focus

我看了这个问题,但是我现在暂时不想触发其他的Java脚本,这全都与视觉有关,在用户与其他事物进行交互之后也会进行验证。这就是问题所在,如果自动填充给人以错误的感觉,即数据是有效的,那么在以后的阶段将其显示为无效可能会令人沮丧。

知道如何仅通过CSS设置样式吗?

如果我必须使用JS:另一个问题是在不手动更改值之前,样式不会.change()在字段上更新,在字段上触发jQuery事件无济于事

在编写问题时,我决定做一些进一步的挖掘,更糟糕的是,自动填充使元素document.getElementById("first_name").checkValidity()在不应该返回的情况下返回true。

因此,当我从一个CSS问题开始时,现在我更倾向于问这是否可以视为一种错误?

编辑1:由于checkValidity()返回的结果为true,所以我尝试提交表单(由于不满足验证条件,因此通常不应该提交该表单),并且确实没有任何打submit。当然,适用黄金法则的是永远不要信任用户数据,服务器端会拒绝它,但是我认为这不会发生,简单的自动填充不应自动意味着数据有效。

理查德

这是一个非常有趣的问题。但是,我对某些事情感到好奇。Chrome浏览器将只保存autocomplete(如提到的表单提交值在这里)。从逻辑上讲,如果输入有minlength5,你有长度为4输入的东西,你将无法提交表单摆在首位因此,不应保存无效的自动完成值。您是如何第一次遇到这种情况的?我只能通过设置minlength,提交然后设置minlength并尝试自动填充来重现它

要回答您的问题,此行为不是错误。minlength无法正常运作,因为其设计无法验证插入的值autofill在下面阅读更多内容。

为什么不起作用minlength

当值的长度小于指定的长度时,为什么不minlength使给定autocomplete的值无效minlength在提到由WHATWG HTML标准minlength有这种约束验证:

如果元素具有最小允许值长度,则其脏值标志为true,其值最后一次由用户编辑更改(与脚本所做的更改相反),其值不是空字符串,而JavaScript字符串元素的API值的长度小于元素的最小允许值长度,则该元素太短。

很明显,只有在用户编辑而不是脚本minlength更改值时才可以验证该值进一步阅读,我们可以推断出的值是由脚本插入的(在此处阅读)。通过执行以下操作(如果在输入中插入单词“ Testing”,我们可以测试输入的值是否被脚本更改),请执行以下操作:autofillminlength

const input = document.querySelector('input')
input.addEventListener('keyup', e => {
  if (input.value === "Testing") input.value = "Test"
})
input:invalid {
  outline: 1px solid red;
}
<input type="text" minlength="5">

您可以看到,input当脚本其值更改为“测试”时,它并不需要验证

使用 pattern

pattern另一方面,没有约束验证,即必须通过用户编辑来更改值。您可以在此处阅读有关其约束验证的信息因此,您仍然可以更改input使用脚本的值,它将仍然有效。尝试input再次输入“测试”

const input = document.querySelector('input')
input.addEventListener('keyup', e => {
  if (input.value === "Testing") input.value = "Test"
})
input:invalid {
  outline: 1px solid red;
}
<input type="text" pattern="[0-9a-zA-Z]{5,}">

当更改为“测试”时,它会被无效pattern并使CSS触发。这意味着您可以pattern用来验证给出的值autofill(仍然好奇如何autofill首先保存此错误值。)

这是一个pattern用于input通过autofill一些调整来验证您的给定值的解决方案

* {
  box-sizing: border-box;
  margin: 0;
  font-family: Helvetica;
}

body {
  padding: 20px;
}

#checkout_form * {
  display: block;
  margin: 1em;
}

#first_name {
  padding: 10px;
  border-radius: 5px;
  width: 400px;
  border: 1px solid #00000044;
  outline: none;
}

#first_name::placeholder {
  color: #00000040;
}

#submit_form {
  padding: 10px;
  border-radius: 5px;
  border: none;
  background: #7F00FF;
  color: #ffffffee;
  width: 200px;
}

#checkout_form input:invalid {
  padding-right: calc(1.5em + .75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: center right calc(.375em + .1875rem);
  background-size: calc(.75em + .375rem) calc(.75em + .375rem);
  
  border: 1px solid #CC0000ee;
}

#checkout_form input:valid {
  padding-right: calc(1.5em + 0.75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.1875rem) center;
  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
  
  border: 1px solid #00cc00ee;
}

@-webkit-keyframes autofillvalid {
  0%,
  100% {
    color: #ffcc00;
    background: none;
    padding-right: calc(1.5em + 0.75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
  }
}

@-webkit-keyframes autofillinvalid {
  0%,
  100% {
    background: none;
    padding-right: calc(1.5em + .75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: center right calc(.375em + .1875rem);
    background-size: calc(.75em + .375rem) calc(.75em + .375rem);
  }
}

input:-webkit-autofill:valid {
  -webkit-animation-name: autofillvalid;
  -webkit-animation-fill-mode: both;
}

input:-webkit-autofill:invalid {
  -webkit-animation-name: autofillinvalid;
  -webkit-animation-fill-mode: both;
}
<form id="checkout_form">
  <input type="text" required id="first_name" name="fname" placeholder="Enter your first name" pattern="[0-9a-zA-Z]{5,}" autocomplete="given-name" title="First Name should be at least 5 characters and must consist only of alphabets and/or numbers">
  <button id="submit_form" type="submit">Submit</button>
</form>

此外,我强烈建议您在此处阅读更多信息autofill以及如何更好地利用它

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章