Autocomplete a předvyplňování formulářů

Atribut autocomplete se u tagu <input> používá pro automatické vyplňování formulářů. Přijde mi velmi důležitý a málo známý. Kromě input type="text", u kterého je nejčastější, se dá použít i u většiny jiných typů inputu a u tagu textarea. Budu i hodně psát o atributu name, se kterým autocomplete historicky souvisí.

Tento text byl původně součástí HTML příručky a popisoval jeden konkrétní atribut tagu input. Ale svým rozsahem už si zaslouží vlastní stránku. V některých textech se zaměňují slova autocomplete a autofill. Autofill je zjednodušeně řečeno starší označení pro tutéž funkcionalitu formulářových políček.

Příklad na autocomplete, který do prvního pole vyplní křestní jméno a do druhého telefon.

email: <input type="text" id="cokoli" name="blbost" autocomplete="given-name">
telefon: <input type="text" id="bflmpsvz" name="hchkrdtn" autocomplete="tel">

I když máte v id a name blbosti, dá se to zachránit atributem autocomplete. Ten určuje, jaká informace se uživateli do políčka předvyplní.

Ještě pár příkladů

Tohle je špatně, protože se nic automaticky nedoplní:

Zadejte email: <input name="nejaka_blbost">

Lepší by bylo mít tam třeba hodnotu "mail", protože je šance, že do takového políčka už uživatel v minulosti mailovou adresu vyplňoval. Na to je dobrý režim historických hodnot nebo režim hádání, že se tyhle věci občas podaří:

Zadejte email: <input name="mail">

Ideální by bylo změnit atributu name na hodnotu "email", protože "email" je standardní hodnota atributu autocomplete pro mailovou adresu. Pak bude správně vyplněná jak historicky, tak i v režimu vyplňování:

Zadejte email: <input name="email">

Ale ne vžcky lze name změnit, protože někdy nelze upravit aplikaci, která name následně zpracovává. Pak je nutné name nechat blbé. Může se ale doplnit autocomplete:

Zadejte email: <input name="nejaka_blbost" autocomplete="email">

A přesně tohle vám doporučuji udělat. Místo přepisování name doporučuju do svých formulářů doplnit hodnoty autocomplete. A ideálně tak, aby krom režimu hádání a historických hodnot fungovaly i v režimu vyplňování. O těch různých režimech je tahle stránka.

Proč je autocomplete důležité

V anglickém prostředí je slovo autocomplete také synonymum pro našeptávač (podobné spíše tagu datalist). V tomto textu se zabývám pouze autocomplete ve významu doplnění textového pole input.

Proč je autocomplete složité

Protože to je jedna z mála posledních věcí, které se v moderních prohlížečích opravdu liší.

Jak se ta hra vyhrává?

Je potřeba vždy používat pouze standardní hodnoty tagu autocomplete. Ty fungují všude.

Dvě úlohy autocomplete

Při předvyplňování řeší prohlížeč dvě odlišné úlohy:

  1. jak se dozvědět údaje o uživateli, tedy například jaký má telefon
  2. jak u políčka <input> poznat, že právě do něj má přijít telefon - na to právě slouží krom jiných signálů také autocomplete.

Údaje o uživateli

Údaje o uživateli se berou z různých míst.

Podrobněji zmíním tu první možnost, zadání adresy do prohlížeče.

Například v desktopovém Chrome je to v Nastavení > Automatické vyplňování hesel chrome://settings/addresses). Tam jsou tři sekce: "Správce hesel", "Platební metody" (tedy karty) a ta třetí jsou "Adresy a další". V adresách může být vyplněno více různých adres - v takovém případě se při vyplňování dá uživateli na výběr, kterou adresu chce použít. Když se přidává nebo upravuje adresa, vypadá to třeba takhle:


Úprava předvyplněné adresy v desktopovém Chrome. Můžete si všimnout, že tu spousta věcí chybí, takže je do desktopového Chromu není jak zadat (například doručovací adresu).

V prohlížeči je možné mít nastaveno více různých profilů s různými údaji - Chrome to chápe jako různé adresy. Ale není to moc praktické, protože to pak zdržuje při vyplňování a ne vždy je jasné, který profil je který (například když mají stejný email). Kdo nakupuje hodně letenky, tomu se vyplatí udělat si další profil s údaji bez háčků a čárek, protože je letecké společnosti neumějí zpracovat.

Rozpoznávání typu pole

To je druhá úloha, kdy prohlížeč potřebuje zjistit,

Pokud jsem to správně pochopil, automatické hodnoty ve formuláři mají více režimů, které jsem si pojmenoval vyplňování a hádání:

Dále existuje funkčnost, kterou jsem si pojmenoval režim historických hodnot. Kombinuje v sobě obě úlohy - jak zjištění informací, tak jejich použití. Pole se vyplňují na základě toho, co prohlížeč v minulosti viděl, že uživatel do stejně pojmenovaných polí vyplňuje na jiných webech

Autofill expectation mantle a autofill anchor mantle

V oficiální dokumentaci k autocomplete se objevují relativně složité pojmy Autofill expectation mantle a Autofill anchor mantle. Vypadají strašně důležitě. Trvalo mi asi dva roky, než jsem pochopil, že to je totální ptákovina a není potřeba se tím vůbec zabývat. Všechny případy jsou pokryté tím, čemu dokumentace říká autofill expectation mantle. Jediná podivná a velmi řídká výjimka je situace, kdy se autocomplete použije u skrytého pole, tedy <input type="hidden">. V takové situaci se používá autofill anchor mantle, ale fakticky to vůbec nic nedělá. Takže tyhle věci s mantle (plášť) můžete v klidu ignorovat.

Přesto mě to dovedlo k poznání, že autofill má spoustu různých režimů, které zde popisuju.

Režim vyplňování a standardní hodnoty

Režim vyplňování je moje označení. Používám ho na odlišení od jiných režimů (hlavně od režimu hádání a režimu historických hodnot - to jsou také moje termíny). Je to nejlepší režim.

Vyplňování jednoduše bere vyplňované hodnoty z nastavení prohlížeče nebo ze systému. Stejně jako v režimu historických hodnot se také kromě atributu autocomplete kouká i atributy name a id, ale tentokrát se standardními hodnotami. Výčet standardních hodnot autocomplete ve standardu HTML 5 obsahuje asi 50 různých typů informace.

Pokud uživatel při režimu vyplňování zvolí jedno políčko z formuláře, z nastavení prohlížeče se doplní všechna políčka, která mají shodu s atributem name nebo autocomplete. Očkává se totiž, že potvrzením jedné hodnoty uživatel zvolil celý uživatelský profil. To naneštěstí často vede k chybám, pokud autor stránky autocomplete přesně nezná nebo si hodnoty name ve formuláři zvolil nestandardně, jak ho napadlo.

Hodnotou atributu autocomplete může být i více standardních hodnot oddělených čárkou. Uživateli se potom při vyplňování nabídne všechno, co souhlasí.

Standardní hodnoty autocomplete, pár důležitých příkladů
autocomplete=" " Význam Poznámka
name celé jméno, křestní a příjmení dohromady včetně titulů častá chyba je používat hodnotu name pro křestní jméno;
naopak name="name" si právě křestní jméno vyžádá!
    given-name křestní jméno nefunguje mi v atributu name
    family-name příjmení nefunguje mi v atributu name
nickname přezdívka v nastavení Chrome není nickname jak předvyplnit
email emailová adresa  
street-address celá adresa = ulice a číslo popisné v případě, že chcete celou adresu v jednom poli, může se na to namísto input hodit tag textarea a dát autocomplete k ní. Street-address je sjednocením addres-line*.
    address-line1 první řádek adresy  
    addres-line2 druhý řádek adresy ještě existuje address-line3
address-level1 kanton, stát v USA stát ve federaci
address-level2 město city funguje jen v Chrome
postal-code poštovní směrovací číslo, ZIP kód zip funguje jen v Chrome
country kód země např. CZ, SK, US
contry-name název země např. Česko, Slovensko apod.
tel celé telefonní číslo včetně předvolby sjednocení tel-country-code a tel-national
    tel-country-code předvolba země začínající plusem u nás např. +420, na Slovensku +421 apod.
    tel-national telefonní číslo bez předvolby  
cc-* hodnoty týkající se platebních karet  
username uživatelské jméno uživatelská jména nemá ve správě autocomplete - to by byla chyba, protože na každém webu můžu mít uživatelské jméno jiné. Doplňuje je správce hesel.
current-password současné (staré) heslo jedině jako nápověda pro správce hesel, jiným způsobem to nemůže fungovat. Správce hesel by měl input vyplnit správně už jen na základě type="password"
new-password nové heslo nápověda pro prohlížeč, že toto pole nemá automaticky vyplňovat (například chybným starým heslem). Dost často se tohoto chování zneužívá pro vypínání autofillu místo autocomplete="off", které je ignorováno v režimu vyplňování.
Některé prohlížeče pro new-password nabídnou vygenerování nového silného hesla (a uložení do prohlížečového správce hesel).
one-time-code pole pro přepsání SMSky  
shipping označuje, že jde o údaj, kam se mají věci doručit typické použití je u adres a telefonů. Např. autocomplete="shipping street-address" označuje, že jde o adresu doručení. Normálně by se to řešilo přes section-*, ale je to natolik běžné, že se vyplácí to mít jako speciální hodnotu.
billing označuje údaj platícího nebo formálního příjemce, typicky při objednávce na firmu např. autocomplete="billing organization" označuje, že jde o název firmy, která si to dá du účetnictví. Opak shipping.
home, work, mobile, fax, pager hodnoty pro označení telefonů a emailů např. autocomplete="tel home" naznačuje, že chce číslo domů
off do pole se nebude nic doplňovat v režimu hádání ale nechá zapnutý režim vyplňování a také vyplní jméno a heslo, pokud je zná
on symbolická hodnota jako protipól off nic to myslím nedělá
section-* vlastní hodnoty pro případ nutnosti odlišení např. section-manzel a section-manzelka. Důležité například v situaci, kdy formulář obsahuje údaje o dvou lidech, dvou firmách a podobně.
více hodnot oddělených čárkou   podle specifikace někdy výběr zužuje, jindy rozšiřuje. Mně to prakticky nefunguje.

Jak už jsem zmínil, podrobný rozpis všech hodnot je ve specifikaci. Tohle byly jenom příklady.

V atributu name stačí, když je standardní hodnota uvedena jako podřetězec hodnoty. Například name="XXBS-name" bude fungovat jako celé jméno, protože obsahuje řetěžec "name". Hodnota name="hojzipx" bude fungovat jako PSČ, protože obsahuje řetězec "zip".

Hodnota atributu autocomplete má přednost před hodnotami uvedenými v name. Pokud atribut autocomplete odpovídá nějaké standardní hodnotě, tak se hodnoty atributů name i předchozí texty před políčkem ignorují. Výjimka je, když autocomplete obsahuje dvě nebo více platných hodnot, které se navzájem vylučují (například zip a email). Pak se obě (všechny) ignorují a vypňuje se případně podle jiných informací. Ale pozor, některé hodnoty se navzájem nevylučují (např. "billing address-line1").

Neznám žádnou hodnotu autocomplete, která by určovala například jméno bez diakritiky. To by se často hodilo u formulářů, které akceptují jenom latinku. Ale neexistuje to, pokud vím. Je potřeba vytvořit si další profil.

Section-*, více sekcí formuláře

Section slouží pro oddělení částí formuláře, které se týkají něčeho jiného. Například dvou různých osob. Takhle to dopadne, když máte ve formuláři údaje o více lidech, ale neumíte používat section-*

Co se tady Invii děje: protože formulář nemá vyznačené autocomplete a už vůbec ne section, přepnul se prohlížeč do režimu hádání (viz níže) a vyplnil pole blbě, protože druhé jméno a příjmení bylo k té adrese blíž než první. Zajímavé je, že v tomhle případě by nestačilo mít vyplněné jenom správně autocomplete. Důležité je mít označení, o kterou jde sekci (v tomto případě o kterého člověka), tedy začít autocomplete zápisem sekce a oddělit to mezerou. Správně tedy kód měl vypadat takhle:

Dospělý cestující (1)
Jméno <input autocomplete="section-person1 given-name" ... >
Příjmení <input autocomplete="section-person1 family-name" ...>
...
PSČ: <input autocomplete="section-person1 postal-code" ...>
...
Dospělý cestující (2)
Jméno <input autocomplete="section-person2 given-name" ... >
Příjmení <input autocomplete="section-person2 family-name" ...>

Režim hádání typu pole

Teď to začne být trochu složité.

Aby předvyplňování dobře fungovalo, snaží se je prohlížeče používat nejenom ve formulářích, které jsou udělané dobře (např. podle předchozího návodu pro režim vyplňování). Prohlížeče ve skutečnosti řeší následující zadání

Aby to fungovalo, i když to autor stránky nějak zvoral

Naprostá většina formulářů na internetech je nějak blbě. O autocomplete málokdo ví a atributy name fláká každý, jak se mu to líbí, takže když funguje režim vyplňování, je to spíš šťastná náhoda než záměr autora.

Kvůli tomu se prohlížeče snaží patřičný typ pole i hádat z jiných údajů, čemuž říkám režim hádání. Mají na to soustavu neveřejných heuristických pravidel. Například prohlížeč Chrome už je v tom tak dobrý, že většinu formulářů vyplňuje často dobře, aniž by autor webu musel cokoli udělat. Jenomže ne všichni mají chrom a i Chrome se často splete.

Z čeho režim hádání hádá?

Celé je to magie a blbě se to debuguje. Chrome má v DevTools i modul na debugování hádání autocomplete, ale nevysvětluje, proč si něco myslí - vysvětluje jenom, k čemu došel, což je skoro na nic. Naštěstí to není potřeba úplně chápat, protože snadné řešení je naflákat tam standardní hodnoty, čímž se to přepne z hádání na vyplňování, a jít dál.

Rozdíly v prohlížečích

Je potřeba upozornit na jednu důležitou věc. Zatímco u vykreslování HTML a CSS už se jednotlivé prohlížeče téměř neliší, protože skoro všechny (kromě Firefoxu) používají stejné nebo podobné vykreslovací jádro, v autocomplete funkcionalitě se mohou lišit zásadně. Proč? Protože to si každý prohlížeč implementuje sám.

Z toho plyne, že autocomplete je potřeba pečlivě testovat v různých prohlížečích, ne pouze ve Chrome. Například je nutné testovat v Safari. Podle mých zkušeností Safari akceptuje standardní hodnoty a nic si nevymýšlí, takže jenom standardní hodnoty považuju za bezpečné.

Tohle je nějaký můj starší text, který je mi líto smazat:

Asi nejdál v rozvíjení autocomplete v režimu vyplňování je prohlížeč Chrome. Krom standardních hodnot může mít další aliasy. U Chrome znám zip za postal-code (PSČ) a city za address-level2 (město). Prohlížeč Chrome kromě atributů autocomplete a name scanuje i texty nacházející se před tagem input (počínaje začátkem <form> nebo předchozím <input>). Pokud v textech najde odpovídající retězce, které zná (např. "postal code", "post code" či "postalcode", ale ne "zip"), bude následující input vyplňovat (v tomto případě jako autocomplete "postal-code"). Pokud najde známých řetězců více, buďto si nevybere, nebo vybere něco podle docela složitého algoritmu, který jsem nedokázal odhalit. ("name" je křestní jméno, ale nesmí být kolem něj jiný text; příjmení jsem nijak nevydráždil; "email" pro email; "phone" pro telefon.) Je možné, že Chrome umí scanovat i jazykové verze, ale nějak se to asi musí nastavit, neumím to. Pro debugování fungování autocomplete v Chrome existuje i podsekce DevTools. Ta je sice užitečná na základní věci, které ukazují co se kam vyplní, ale neříká, proč se co kam vyplní. Takže stejně je Chrome černá skříňka.

Předvyplňování hesel a uživatelských jmen

Do předvyplňování hesel jsem ještě úplně neproniknul. Je závislé na správci hesel, který je v prohlížeči oddělený od ostatní logiky autocomplete.

Kolem hesel tři významné hodnoty autocomplete:

Důležité je zmínit rozdíl mezi starým na novým heslem. Pokud hodnotu autocomplete nezadáte, nemáte v případě <input type="password"> úplnou kontrolu, čím ji prohlížeč bude vyplňovat. Typicky se bude snažit ji vyplnit současným heslem (tedy current-password), což je většinou správně, ale někdy taky ne.

Když chcete, aby si uživatel vytvořil nové heslo (nebo aby mu bylo prohlížečem vytvořeno), použijte vždy tenhle zápis:

<input type="password" autocomplete="new-password">

To je vlastně ta hlavní rada.

Některé prohlížeče se následně při aktivaci takového pole a autocomplete="new-password" pokusí vygenerovat tzv. silné heslo s bambiliónem speciálních znaků. Pokud uživate souhlasí, tohle heslo se použije a uloží do správce hesel.

Jak funguje správce hesel s autocomplete

Úplně nevím, ale funkci správce hesel v prohlížeči si představuju takhle: Když se někam přihlásím, prohlížeč se mě zeptá, jestli chci jméno a heslo uložit. Pokud souhlasím, uloží se do správce dvojice jméno a heslo.

Když na stejnou doménu přijdu příště, při focusu na input s autocomplete="username" (nebo při focusu na jiné formulářové pole, za kterým následuje input type="password") se objeví nabídka, zda chci uživatelské jméno vyplnit ze správce hesel. Pokud souhlasím, vyplní se jak uživatelské jméno, tak heslo.

Když se někde na stejné doméně objeví jiné input type="password", prohlížeč se po odeslání zeptá, jestli si má hodnotu hesla aktualizovat. To může být blbé chování, pokud je to heslo k něčemu úplně jinému.

Stejně tak se prohlížeč zeptá, jestli má aktualizovat heslo, když uživatel vyplnil jiné než to, které má uložené. To může být taky blbá situace, protože se tak občas zeptá i v případě, že se přihlášení nezdařilo. Nevím, jak to ošetřit jinak, než spoléhat na inteligenci uživatele, že si neuloží chybné heslo.

Režim historických hodnot

S atributem autocomplete tenhle režim myslím vůbec nesouvisí, ale uvádím to tady pro pořádek. Když jsem po dvou letech přišel na svou testovací stránku formulářů, nabídlo se mi vyplnění formuláře hodnotou, kterou jsem někde kdysi použil. To zařídila funkčnost, které říkám režim historických hodnot.

Jak funguje autocomplete v režimu historických hodnot v normálních případech:

Prohlížeč si v minulosti při odesílání ukládal hodnoty, které u tohoto uživatele viděl, a páruje si je k hodnotě atributu name nebo id vyplněného políčka. Uvidí-li v budoucnu ve formuláři input se stejným name, nabídne uživateli možnost vyplnit input již známou hodnotu. Proto je dobrý nápad používat v atributech name (nebo id) nějaké rozumné hodnoty, typicky krátká anglická slova -- častěji pak při hádání nastane shoda. Ideální je v atributech name používat standardní hodnoty (zmíním níže).

Zatím pořád píšu o atributu name. Podle něj prohlížeče od pradávna doplňování začaly dělat, protože to dává smysl. Atribut autocomplete pak vzniknul ze zřejmé potřeby používat nějaké úplně jiné hodnoty atributů name, které jsou často pevně dané, typicky pro potřeby aplikací. Aby se mohly doplňovat automatické hodnoty i do inputů, které mají divně nebo šíleně vyplněné name, vzniknul atribut autocomplete.

Myslím, že je zřejmé, co je na režimu hádání blbé. Ne vždycky funguje správně. Někdy do inputu na jméno vyplní celé jméno, jindy jenom křestní. Telefonní číslo se vyplní s předvolbou, i když jej formulář vyžaduje bez předvolby. A tak dále. Před příchodem na to autoři webů reagovali tak, že automatické doplňování vypínali zvláštní hodnotou autocomplete="off". To vypíná režim hádání.

Autocomplete="off"

Speciální hodnota autocomplete="off" zabrání tomu, aby se políčko doplňovalo historicky nějakou dříve zadanou hodnotou v nějaké jiné stránce (shoda se hádá podle shody atributu name a právě tohle hádání off vypne; také vypne, aby se zadaná hodnota do prohlížeče ukládala).

Prohlížeče autocomplete="off" ignorují ve dvou případech: 

  1. identifikované jméno a heslo - vyplňuje je přes svůj správce hesel, i když je autocomplete="off".
  2. Prohlížeče také autocomplete="off" ignorují, pokud uživatel zvolil automatické vyplnění formuláře - vypíná tedy jenom režim historických hodnot.

(Proto se někdy pro vypínání autocomplete také zneužívá hodnota new-password. Je to hloupý workaround (nedělejte to), ale vidím to velmi často při registraci do bank. Bankám asi narozdíl od eshopů významně vadí i drobné chybky, které může autocomplete udělat při vyplňování. I tak je to blbý nápad, protože prohlížeče teď nově u new-password nabízí vygenerované nové heslo.)

Lepší reakce na chyby hádání je opět umožnění režimu vyplňování, tedy zavedení atributu autocomplete a jeho standardních hodnot.

Alternativy k autocomplete

Pokud potřebujete vyplňovat něco jiného nebo složitějšího, autocomplete v HTML stačit nebude.

Původní text z roku 2022 byl v popisu tagu input. Stránka vytvořena 24. 5. 2024. Aktualizováno 29. 5. 2024

Reklama

www.webhosting-c4.cz, extra rychlý SSD webhosting s doménou v ceně
o tvorbě, údržbě a zlepšování internetových stránek

Návody HTML CSS JavaScript Články Ostatní

Základy Prvky stránek Tvorba webu

Jak psát web píše Yuhů, Dušan Janovský. Kontakt.