表单字段的四件事:51个站的邮箱框,全写上的只有6个

表单字段的四件事:51个站的邮箱框,全写上的只有6个
张文保 更新 26 分钟阅读 1,577 阅读
本文目录
  1. 浏览器本来准备替这一格做哪几件事?
  2. 这一轮量了什么,为什么要先去一次重?
  3. 邮箱那一格,四件事都写全的有几个?
  4. autocomplete用得最多的那个取值,为什么是off?
  5. 搜索框为什么是全场最不像框的那一个?
  6. 同一个站里的两个邮箱框,写法为什么不一样?
  7. 平台给的那一页,和自己后加的那个框,差在哪?
  8. 校验这件事,页面到底交给了谁?
  9. 这一轮尺子失效了三次
  10. 第一次:同一个框被数了四遍
  11. 第二次:读表单id,读回来一个输入框
  12. 第三次:跟踪像素往页面里塞了160个输入框
  13. 这些数字有几个边界
  14. 照着改,先动哪四处?
  15. 常见问题解答
  16. 写不写autocomplete,对SEO排名有影响吗?
  17. 我的表单是JavaScript接管提交的,还有必要写这些属性吗?
  18. type=email的浏览器校验太松,写了也拦不住乱填的邮箱,还写它干嘛?
  19. 搜索框的autocomplete写成off,到底该不该?
  20. 怎么快速查一遍自己站上这些属性写没写?
  21. 这些属性会不会因为浏览器差异而不生效?
  22. 权威参考资料

摘要:把55个独立站的191个页面逐页拆开,数了一遍每个输入框身上写了什么。同一个站里重复渲染的框先合并,最后剩下1902个控件、422个真要用户打字的字段。收邮箱的那一格有160个,分布在51个站上——写了type=email的86.9%,写了autocomplete=email的只有45.6%,四件事(类型、代填、必填、名字)全都写上的42.5%。按站算更难看:51个站里,所有邮箱框都写全的只有6个。整批数据里autocomplete出现最多的取值不是任何一个字段名,是off。

页面上绝大多数东西是站点在单向说话:标题在说、图片在说、价格在说。只有一个地方反过来——输入框。那是用户往里写字的地方,也是这一页上唯一一处需要页面提前交代清楚的地方:这一格要什么。

交代给谁?不是给用户。用户看一眼旁边那行小字就知道该填邮箱。要交代的是浏览器。浏览器手里握着一整套现成的本事:调出带 @ 的键盘、把用户存过的地址一键填进去、在提交前拦下一个明显不成立的邮箱、告诉密码管理器这是新密码不是旧密码。这些本事一件都不需要你写代码,但每一件都需要你在标签上写一句话。不写,它就当你不需要。

这一轮就是去数这句话有没有人写。

浏览器本来准备替这一格做哪几件事?

先把机制摆清楚,后面的数字才有落点。一个输入框上能写的东西不少,真正会触发浏览器动作的是下面这几个,它们各管各的,互相替代不了。

写在哪儿浏览器拿它干什么不写会怎样
type决定用哪种控件、手机上弹哪种键盘、提交前做哪种最基本的格式检查当成一行普通文本,什么都不管
autocomplete认出这一格要的是邮箱、名字还是收货地址,把用户存过的值填进来只能靠猜,猜不准就不填
required空着不让提交,并且把这件事同步进无障碍树星号只有眼睛看得见
inputmode在type不变的前提下换一套软键盘手机上继续弹全键盘
patternmaxlength提交前挡掉明显不合规的输入全部推给后端和那段JavaScript

这五样东西有个共同点:它们都是声明,不是行为。你写下来,浏览器照做;你不写,页面照样长得一模一样,用户也照样能填——只是那些本来免费的帮助全都不会发生。视觉上没有任何代价,这正是它们容易被漏掉的原因。

还有一个容易混的点。MDN的autocomplete取值清单里,取值不是随便起的名字,是标准里定死的一份枚举。HTML标准的表单控件章节一共定义了65个取值,去掉section、shipping、billing这类修饰词和on、off两个开关,真正的字段名是54个。写在里面的浏览器认,写成autocomplete="phone-number"这种自己发明的,等于没写。

这一轮量了什么,为什么要先去一次重?

样本沿用手上那批英文独立站:55个站,每站抓首页、一个商品页,再从首页现场找出联系页和账号页各一个,凑成4个页面。实际拿到200并且能解析的是191个页面。取不回来的33个里,15个撞429被限流,13个是404(多数是账号页那条约定路径根本不存在),剩下几个是400、403、500。这些页一律不进分母,不凑数。

每个页面上,把所有input、select、textarea全都读出来,连同它的type、name、id、autocomplete、required、pattern、maxlength、inputmode、placeholder,以及它的名字到底是从label、aria-label还是placeholder上来的,一并记下来。原始数据是4393个控件实例。

然后就撞上了第一件麻烦事。

mackweldon的首页上有6个邮箱框,商品页上也是6个,联系页7个,登录页6个。翻开一看,其中5个每一页都长得一模一样:登录用的、找回密码用的、注册用的,全被主题塞进了同一个抽屉,抽屉挂在每一个页面上。按页面数,这一个框会被数四遍;哪个站的页面抓得多,哪个站的写法就自动获得更大的权重。

所以先去重:同一个站里,控件类型、name、autocomplete、required、名字来源、名字文本、占位符全都一样的,算作同一个字段的多次渲染。4393个实例合成1902个字段。合并的量不小——去重后的字段里,有31.3%是在三个及以上页面上重复出现的。

这个口径本身也是个发现:一个站的表单写得好不好,多数时候不是页级决策,是它主题里那几份模板的事。这一点后面还会再撞见一次。

1902个控件里,绝大多数是商品页上的颜色尺码单选钮和各种勾选项。真正要用户打字的(text、email、search、tel、password、number、textarea这些)是602个。这602个里还得再剔掉180个,剔掉的原因放在后面那节尺子失效里讲,最终422个,来自54个站。

邮箱那一格,四件事都写全的有几个?

先看最能横向比的那一格。422个字段里,能判定为收邮箱的有160个,来自51个站——比例之高说明了一件事:这批站上唯一一件人人都在做的事,是收邮箱。同一件事、五十多种实现,正好当尺子用。至于这个框本身该怎么设计、什么时候弹出来才不招人烦,邮件弹窗那篇邮件列表从零养起那篇都拆过,本文只管它在源码里说了什么。

四件事分开看:

这一格写没写写了的占比
type="email"13986.9%
有个正经名字(label或aria,不是只有占位符)14288.8%
requiredaria-required11672.5%
autocomplete="email"7345.6%
四件全写上6842.5%

单看每一项都不算灾难,凑到一起就塌了一半。而且组合分布很集中:写全的68个之外,第二多的是35个只差autocomplete那一项,第三多的是24个既没autocomplete也没required。四件事全都没写的有7个。

换个算法更难看。按站算,把一个站上所有邮箱框都要求写全,51个站里做到的只有6个:brooklynbedding、casper、dollarshaveclub、hellotushy、oclean、stanley1913。反过来,一个都没写全的站有16个。

顺带把这一格的名字文本也数了一遍,因为它经常被当成随手可以变的东西。160个邮箱框里,写了占位符的122个,原样不同的写法41种,忽略大小写和末尾标点后归一化,还剩27种:Email、Email Address、Your email address、Enter your email here...、your@email.com。可及名称那一列同样是34种原样、23种归一。同一个概念,在同一批页面上有二十多种叫法——这件事对用户没影响,对拿名字去认字段的程序有影响,也正是首页正文可读性那一轮实测里数过的另一层:那次数的是这一格有没有名字,这次数的是它写没写清楚自己要什么。

autocomplete用得最多的那个取值,为什么是off?

把范围放大到全部1902个控件,写了autocomplete的只有164个,8.6%。这个数字本身不奇怪——单选钮和勾选项本来就用不上它。奇怪的是取值分布。

164个里,取值合法的105个,写成off的55个,写on的2个,自己发明取值的2个(passwordphone-number,标准里都没有这两个名字)。也就是说,整批数据里autocomplete这个属性出现最多的单一取值不是email,是off:email 73次,off 55次,第三名current-password只有7次。

更值得念一遍的是覆盖面。标准给了54个字段名,覆盖到姓名分段、地址分级、信用卡有效期、生日拆成年月日、一次性验证码。这55个站实际用到的是13个:bday-day、bday-month、bday-year、country、current-password、email、family-name、given-name、name、new-password、postal-code、sex、tel。标准写了54格,行业只用了两成半。

那55个off也不是随便关的。按用途拆开,29个是搜索框,其余散落在邮箱、密码、姓名上。搜索框关掉浏览器的历史下拉,理由通常说得通:站点自己做了联想,两层下拉叠在一起确实难看。但邮箱框上那6个off就不太讲得通了——用户存过的邮箱不给填,省下的是他自己那几秒。

这里得说句公道话,off的语义在标准里也有点尴尬:它本意是“这一格不适合自动填充”,浏览器并不保证照做,密码管理器更是长期无视它。所以写off常常连它想要的效果都拿不到,只是让这一格彻底失去了被正确识别的机会。

搜索框为什么是全场最不像框的那一个?

把字段按用途分成几个桶,横着对比一次,差距一眼就看出来了。

这一格在要什么个数站数type写对写了autocomplete写了必填
邮箱1605186.9%50.0%72.5%
密码2623100%57.7%65.4%
姓名3826100%42.1%55.3%
留言212095.2%4.8%28.6%
电话121266.7%50.0%16.7%
数量181583.3%5.6%5.6%
搜索804530.0%33.8%(全是off)1.2%

密码框百分之百写对了type,因为写错就会把密码明文显示出来,第一次自测就会被发现。邮箱框写对86.9%,因为写错了手机上不弹 @ 键,测试的人多半也会察觉。写对的那些,几乎都是写错了立刻能看见的那些。

搜索框恰恰相反。type写成search还是text,页面上看不出任何区别——两者的差别只在于移动端的回车键变成“搜索”、部分浏览器会给一个清除小叉、以及它在无障碍树里的身份。看不出区别,就没人改,于是80个搜索框里56个还是type=text。至于那1.2%的必填,倒是合理,搜索框本来就不该拦人。

顺着这条线往后看还有一层:站内搜索页那一轮实测发现,四十个电商站里查得到和查不到长得几乎一模一样。入口这一格身份模糊,结果那一页身份也模糊,两头都没人当成一件正经事来写。

搜索这一格另有一层账。它是站上被点得最多的输入框之一,也是搜索框设计那篇反复讲过的高转化入口;而它在源码里恰恰是身份最模糊的那个。移动网页与App上提交按钮的那次对照量过它的外形差异,这一轮量的是它在标记层的自我介绍——两边的结论正好接上:这个框的实现,被当成了纯视觉问题。

同一个站里的两个邮箱框,写法为什么不一样?

这是本轮最干净的一次自基线。跨站比较总有借口——技术栈不同、团队规模不同、上线年份不同。那就在同一个站里比:同一个站的两个邮箱框,写法一致吗?

51个站里,有两种及以上不同邮箱框写法的是43个。这43个里,四件事写得前后不一致的有37个,86.0%。

不一致的形态高度一致。举几个(用四位数字表示四件事,顺序是type、autocomplete、required、名字):

  • allbirds:首页、商品页、联系页上的订阅框都是1010,登录页上的那个是1111;
  • brooklinen:首页与联系页的订阅框1001,登录页1111;
  • baseus:首页1001,联系页0000,登录页1111;
  • bollandbranch:三个订阅框全是1011,登录页1111。

规律很扎眼:登录页那个框永远是写全的,首页页脚那个订阅框永远缺一两样。不是同一批人写的,也不是同一天写的。

平台给的那一页,和自己后加的那个框,差在哪?

顺着上一节往下追,把字段按“是谁加上去的”分三档,差距就不是几个百分点了。

这个框来自哪儿字段数站数写了autocomplete写了必填type写对有正经名字
站点自己的表单2845449.3%56.3%89.3%86.6%
提交给第三方的表单37108.1%18.9%87.5%94.6%
不在任何表单里101376.9%5.9%33.3%89.1%

三档里最惨的不是第三方,是第三档。那101个字段压根不在任何一个form元素里——搜索框、弹层里的邮箱格、商品页上那个到货通知框,全靠JavaScript接管。这一档里type写对的只有三分之一,autocomplete 6.9%,必填5.9%。一个连自己属于哪张表单都没交代的框,自然也不会交代自己要什么。

第三方那一档有意思在别处:名字写得最好(94.6%),autocomplete最差(8.1%)。这两个数放一起,画像很清楚——那是营销工具生成的订阅表单,它非常在乎表单在视觉上和无障碍上过得去,但完全不在乎浏览器能不能替用户把邮箱填进去,因为那对它的转化归因没有任何帮助。第三方脚本自己会变这件事在这里同样成立:那一档的写法什么时候改、改成什么样,不由你定。

再按页面类型看一遍,同一件事从另一个角度冒出来:

页面字段数写了autocomplete写了必填type写对
平台默认的登录页2972.4%72.4%96.6%
注册页2458.3%58.3%91.7%
站内链接过去的账号页10656.6%58.5%81.8%
首页16447.0%40.9%77.3%
联系页21127.0%30.8%75.6%
商品页21633.8%34.7%73.0%

顺序基本是按“这一页有多少是平台自带的”排下来的。登录页那29个字段里,name属性写着customer[email]、id写着CustomerEmail的一大片——那是电商平台默认主题里的原件,从模板里出厂就带着autocomplete和required。首页页脚那个订阅框、商品页那个到货通知框,才是各家自己后来加的。

所以本轮真正的结论不是“大家不懂”,而是:这些属性写没写,跟开发者知不知道关系不大,跟这个框是从哪儿来的关系极大。平台默认的模板替你写好了,你自己拼的那个没人替你写。这条线同样解释了为什么robots.txt里那些指令三分之一是白写的、为什么响应头里躺着248个死字段——出厂默认值的惯性,比任何一份最佳实践都强。

校验这件事,页面到底交给了谁?

把422个要打字的字段过一遍校验类属性,数字冷得有点好笑:

  • 写了required的142个,33.6%;另有31个只写了aria-required,也就是只告诉了读屏软件,没告诉浏览器;
  • 写了pattern的21个,5.0%;
  • 写了maxlength的33个,7.8%;
  • 写了inputmode的6个,1.4%。

那31个只写aria-required的挺说明问题。写这一行的人显然知道无障碍这回事——无障碍改造那份清单里这一条排得很靠前——但他把它当成了一条无障碍要求,而不是一条功能声明。同一件事写在required上,读屏软件照样读得到,浏览器还顺手帮你拦一次空提交。

再看表单这一级。360张去重后的表单里,有可见可填项的“真表单”120张,其中54张写了novalidate——45.0%的真表单,明确关掉了浏览器的内建校验。

关掉不见得是错。MDN关于客户端校验的那篇写得很清楚:浏览器自带的那个气泡提示样式改不动、文案不能自定义、多语言站上它按浏览器语言走而不是按页面语言走。想把错误提示做成自己的样子,第一步就得关掉它。这条路径完全正当。

问题在于关掉之后有没有补上。错误提示那一篇算过另一笔账:后端明明知道用户错在哪,页面上却只剩四个字。两件事连起来看是同一条链:先把浏览器能说的那句话关掉,再把自己该说的那句话省掉,最后用户面对的就是一个不肯说明理由的框。

inputmode那1.4%值得单独说一句。它是这批属性里成本最低的一个——MDN的inputmode说明里那一行属性,加上去就能让手机上弹出的键盘换一套。数量框、邮编框、验证码框都用得上。全样本422个字段里写了的6个,其中4个还是数量框。移动端那根手指本来就够忙了,多按几次切换键盘这件事,没人算进过成本。

这一轮尺子失效了三次

按老规矩,量之前先量尺子。这一轮尺子坏了三次,三次都是在写稿之前抓到的,每一次都会改掉结论。口径变更那篇讲的是同一条线上前后不可比,这里是同一次读数里分母被污染,性质一样:数字不会喊疼,只有你自己去翻明细才知道它坏了。

第一次:同一个框被数了四遍

就是前面讲的抽屉问题。不去重的话,主题里那几个隐藏表单会按页面数量翻倍,谁的页面抓得多谁的权重就大。按签名去重之后,“要打字的字段”从一堆实例收敛到422个,邮箱框从300多个收敛到160个。所有百分比都是在去重之后算的。

第二次:读表单id,读回来一个输入框

脚本第一版在44个页面上直接崩了,报的是“这个值上没有replace方法”。查下去才发现,HTML标准给form元素开了个后门:表单里那些控件的name会被挂到表单对象上,而且优先级高过表单自己的属性。商品页那张加购表单里通常有个<input name="id">装着变体ID,于是读form.id读回来的是那个输入框本身。全样本里有275张表单实例中招,出自33个站。改成getAttribute('id')之后重跑,那44个页面全部回来了。

第三次:跟踪像素往页面里塞了160个输入框

第一版算出来“提交给第三方的表单”有318个要打字的字段,其中242个来自两个站。翻开一看,parachutehome的商品页上有一张form,action指向https://www.facebook.com/tr/,整张表display:none,里面160个type=text的输入框,name是id、ev、dl、rl、ts、ud[external_id]这种——那是跟踪像素把自己的请求参数做成了输入框。它们既没有可及名称也没有占位符,从头到尾没打算给人看。

判据因此收紧了一道:从没可见过、又没有任何说明文字的字段,不算“用户要填的字段”。这一刀切掉180个,其中166个出自那个像素。切完之后,“第三方表单”这一档从318个字段变成37个,画像也跟着反转——原来算出来的是“第三方连名字都不写”(17.2%),真值是“第三方名字写得比谁都好”(94.6%),差的是autocomplete。如果没抓到这一刀,整节结论会写反。

这些数字有几个边界

三条,都得摆在明处。

第一,读数只是一个时刻的快照。页面载入后等9秒左右读一次,这是本轮的口径。另外挑了29个首页做对照:什么都不做、只多等20秒,17.2%的页面form数会变、20.7%的页面可填控件数会变;再替用户点一下那个订阅或搜索入口,56.5%的页面控件数会变,全样本可填控件从42个涨到70个。所以这里所有的百分比,量的是“不点、只等一会儿”那个状态下的页面。换个等法,分母就换了。

第二,样本偏平台。55个站里相当一部分跑在同一个电商平台上,前面那条“平台默认写得好”的结论,本质上是这批平台的默认模板写得好,换一套自研前端未必成立。

第三,这一轮只看声明,没看行为。写了type="email"不等于后端真的验邮箱,写了autocomplete="email"也不保证浏览器一定填得进去——它还要看这一格在不在一个form里、页面有没有别的东西挡着。声明是必要条件,不是充分条件。

照着改,先动哪四处?

按投入产出排,四步,前两步半小时能做完。

第一步,把站上所有收邮箱的框找出来,一个一个补齐四件事。找法很土但管用:全站搜type="text"加email这个词,再搜一遍页脚模板、弹层模板、到货通知模板。本轮51个站里只有6个通过了这一关,这一步的性价比高得离谱。四件事分别是type="email"autocomplete="email"required、一个真正关联上的label。

第二步,把autocomplete从“想起来才写”改成模板里的默认项。结账那一套尤其要注意收货与账单要分别加shipping和billing前缀,这件事结账流程那一篇已经拆得很细。做之前先照着标准的54个字段名过一遍,别自己发明取值——本轮就抓到phone-numberpassword这两个不存在的名字。

第三步,清点一遍不在任何form里的输入框。这一档的各项指标全场最差,而且它们多半是最近两年加的组件。搜索框、订阅弹层、到货通知,只要还在用div拼,就顺手把type和autocomplete补上,成本几乎为零。下拉框那篇讲过同一个道理的另一面:能用原生控件解决的,别自己造。

第四步,如果你关掉了novalidate,去看看错误提示补上了没有。关掉本身没问题,关掉之后什么都不补才是问题。顺手把inputmode加到数量框和邮编框上,两分钟的事。

再往前一步的话,值得把这件事塞进组件库而不是塞进checklist。本轮那86%的站内不一致说明得很清楚:靠人记,记不住;靠模板,才记得住。保哥自己那批工具页上的输入框,也是先补进模板才彻底不再漏的——之前每次新加一个页面就漏一次,checklist上写得再清楚都没用。

顺带一提,这件事跟AI时代那套讨论也接得上。智能体读的是无障碍树而不是页面截图,而type、required、名字这三样恰好就是那棵树上的节点属性;给代理适配站点这件事,起点不在于加什么新标记,而在于把二十年前就有的这几个属性写全。语义化标签那篇的老结论在这里依然成立:机器读到的东西,从来只有你写下来的那部分。

常见问题解答

写不写autocomplete,对SEO排名有影响吗?

没有直接影响,搜索引擎不会因为你写了autocomplete给你加分。它影响的是转化和可用性:用户少打十几个字符,表单完成率就不一样。真要说和搜索的关系,只有间接的一条——这些属性同时也是无障碍树上的节点信息,而读页面的程序越来越多地依赖那棵树。把它当成转化优化去做,别当成排名手段。

我的表单是JavaScript接管提交的,还有必要写这些属性吗?

有,而且更有必要。JavaScript接管的是提交那一步,type、autocomplete、required管的是提交之前的每一秒:弹哪种键盘、能不能一键代填、空着提交时提不提示。本轮那101个不在任何form里的字段,各项指标全场最差,正是因为团队默认“反正JS全管了”。

type=email的浏览器校验太松,写了也拦不住乱填的邮箱,还写它干嘛?

它确实很松,只要有 @ 就放行,MDN的input type=email文档里明确写了这一点。但它真正的价值在别处:手机上弹带 @ 的键盘、告诉浏览器这一格可以用存过的邮箱去填、在无障碍树里表明身份。校验只是它顺手做的第四件事。

搜索框的autocomplete写成off,到底该不该?

如果你自己做了搜索联想,写off是合理的,能避免两层下拉叠在一起。但要知道两件事:一是浏览器不保证照做,密码管理器基本无视它;二是别把这个习惯顺手复制到邮箱、姓名、地址那些框上。本轮55个off里有6个落在邮箱框上,那几个纯属抄模板抄过头了。

怎么快速查一遍自己站上这些属性写没写?

不用装工具。打开控制台跑一句document.querySelectorAll('input,select,textarea'),把type、name、autocomplete、required打出来看一眼就够了。要注意两个坑:一是同一个框可能在多个页面重复出现,别重复计数;二是页面上可能有跟踪像素注入的隐藏输入框,判据是“从没可见过又没有任何说明文字”,那些不算你的字段。

这些属性会不会因为浏览器差异而不生效?

type、required、pattern的支持度早就没有问题了。inputmode在主流移动浏览器上都能用。autocomplete的差异主要在“填不填”的策略上——各家浏览器和密码管理器有自己的启发式判断,你写对了它未必百分之百填,但你不写它基本就只能猜。web.dev那份登录表单最佳实践把这套判断讲得比较全,值得照着核一遍。

权威参考资料

分享到
标签
版权声明

本文标题:《表单字段的四件事:51个站的邮箱框,全写上的只有6个》

本文链接:https://zhangwenbao.com/form-field-declaration-audit.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交