<input type="tel">

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

型別為 tel<input> 元素用於讓使用者輸入和編輯電話號碼。與 <input type="email"><input type="url"> 不同,輸入的值在表單提交前不會自動驗證為特定格式,因為世界各地的電話號碼格式差異很大。

試一試

<label for="phone">
  Enter your phone number:<br />
  <small>Format: 123-456-7890</small>
</label>

<input
  type="tel"
  id="phone"
  name="phone"
  pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
  required />
label {
  display: block;
  font:
    1rem "Fira Sans",
    sans-serif;
}

input,
label {
  margin: 0.4rem 0;
}

儘管 tel 型別的輸入框在功能上與標準的 text 輸入框相同,但它們確實有其用處;其中最明顯的一點是,移動瀏覽器——尤其是手機上的瀏覽器——可能會選擇性地呈現一個為輸入電話號碼而最佳化的自定義鍵盤。為電話號碼使用特定的輸入型別也使得新增自定義驗證和處理電話號碼更為方便。

備註: 不支援 tel 型別的瀏覽器會回退為標準的 text 輸入框。

<input> 元素的 value 屬性包含一個字串,該字串表示一個電話號碼或者是一個空字串 ("")。

附加屬性

除了全域性屬性以及適用於所有 <input> 元素的屬性(無論其型別如何)之外,電話號碼輸入框還支援以下屬性。

list

列表屬性的值是位於同一文件中的 <datalist> 元素的 id<datalist> 為此輸入提供了一個預定義值列表,以供使用者建議。列表中與 type 不相容的任何值都不會包含在建議選項中。提供的值是建議,而不是要求:使用者可以從這個預定義列表中選擇,也可以提供不同的值。

maxlength

使用者可以在電話號碼欄位中輸入的最大字串長度(以 UTF-16 程式碼單元為單位)。這必須是一個 0 或更高的整數值。如果沒有指定 maxlength,或者指定了一個無效值,則電話號碼欄位沒有最大長度。該值也必須大於或等於 minlength 的值。

如果欄位中輸入的文字長度大於 maxlength UTF-16 程式碼單元,則輸入將無法透過 約束驗證。約束驗證僅在使用者更改值時應用。

minlength

使用者可以在電話號碼欄位中輸入的最小字串長度(以 UTF-16 程式碼單元為單位)。這必須是一個非負整數值,且小於或等於 maxlength 指定的值。如果沒有指定 minlength,或者指定了一個無效值,則電話號碼輸入框沒有最小長度。

如果輸入到欄位中的文字長度小於 minlengthUTF-16 程式碼單元,則電話號碼欄位將無法透過約束驗證。約束驗證僅在使用者更改值時應用。

pattern

當指定 pattern 屬性時,它是一個正則表示式,輸入框的 value 必須與該正則表示式匹配才能透過 約束驗證。它必須是有效的 JavaScript 正則表示式,如 RegExp 型別所使用,並記錄在我們的正則表示式指南中;在編譯正則表示式時指定 'u' 標誌,以便將模式視為 Unicode 碼點序列,而不是 ASCII。模式文本週圍不應指定正斜槓。

如果未指定或指定的模式無效,則不應用正則表示式,並且此屬性將完全被忽略。

注意: 使用 title 屬性來指定大多數瀏覽器將作為工具提示顯示的文字,以解釋匹配模式的要求。您還應該在附近包含其他解釋性文字。

有關詳細資訊和示例,請參見下文的模式驗證

placeholder

placeholder 屬性是一個字串,它向用戶提供一個簡短的提示,說明欄位中預期哪種資訊。它應該是一個詞或短語,演示預期的資料型別,而不是解釋性訊息。文字不能包含回車或換行符。

如果控制元件的內容具有單一方向性(從左到右從右到左),但需要以相反的方向性呈現佔位符,您可以使用 Unicode 雙向演算法格式字元來覆蓋佔位符內的方向性;有關更多資訊,請參閱如何使用 Unicode 控制元件處理雙向文字

注意: 如果可以,請避免使用 placeholder 屬性。它不如其他解釋表單的方式在語義上有用,並且可能導致您的內容出現意外的技術問題。有關更多資訊,請參閱<input> 標籤

readonly

一個布林屬性,如果存在,則表示該欄位不能由使用者編輯。但是,其 value 仍然可以透過 JavaScript 程式碼直接設定 HTMLInputElement value 屬性來更改。

注意: 由於只讀欄位不能有值,因此 required 對同時指定了 readonly 屬性的輸入沒有影響。

size

size 屬性是一個數字值,表示輸入欄位應該有多寬(以字元為單位)。該值必須是一個大於零的數字,預設值為 20。由於字元寬度不同,這可能不完全精確,不應依賴於此;最終的輸入可能比指定的字元數更窄或更寬,具體取決於字元和正在使用的字型(font 設定)。

限制使用者可以在欄位中輸入的字元數。它只指定一次大約可以看到多少個字元。要對輸入資料的長度設定上限,請使用maxlength 屬性。

使用 tel 輸入框

電話號碼是 Web 上非常普遍收集的一種資料型別。例如,在建立任何型別的註冊或電子商務網站時,你很可能需要詢問使用者的電話號碼,無論是出於業務目的還是緊急聯絡目的。鑑於電話號碼的輸入如此普遍,不幸的是,“一刀切”的電話號碼驗證解決方案並不可行。

幸運的是,你可以根據自己網站的需求,自行實現適當級別的驗證。詳情請參見下文的驗證

自定義鍵盤

<input type="tel"> 的一個主要優點是它能讓移動瀏覽器顯示一個專門用於輸入電話號碼的鍵盤。例如,以下是一些裝置上鍵盤的樣子。

適用於 Android 的 Firefox WebKit iOS (Safari/Chrome/Firefox)
Firefox for Android screen shot Firefox for iOS screenshot

一個基本的 tel 輸入框

在其最基本的形式中,tel 輸入框可以像這樣實現

html
<label for="telNo">Phone number:</label>
<input id="telNo" name="telNo" type="tel" />

這裡並沒有什麼神奇之處。當提交到伺服器時,上述輸入框的資料將表示為,例如,telNo=+12125553151

佔位符

有時候,提供一個上下文提示來說明輸入資料應採用何種格式是很有幫助的。如果頁面設計沒有為每個 <input> 提供描述性標籤,這一點尤其重要。這就是佔位符的作用所在。佔位符是一個展示 value 應採用格式的值,它透過呈現一個有效值的示例,在元素的 value"" 時顯示在編輯框內。一旦資料輸入到框中,佔位符就會消失;如果清空輸入框,佔位符會重新出現。

這裡,我們有一個帶有佔位符 123-4567-8901tel 輸入框。請注意當你操作編輯欄位內容時,佔位符是如何消失和重現的。

html
<input id="telNo" name="telNo" type="tel" placeholder="123-4567-8901" />

控制輸入大小

你不僅可以控制輸入框的物理長度,還可以控制輸入文字本身允許的最小和最大長度。

物理輸入元素大小

輸入框的物理大小可以透過 size 屬性來控制。透過它,你可以指定輸入框一次可以顯示的字元數。例如,在這個例子中,tel 編輯框有 20 個字元寬

html
<input id="telNo" name="telNo" type="tel" size="20" />

元素值長度

size 與輸入電話號碼的長度限制是分開的。你可以使用 minlength 屬性指定輸入電話號碼的最小長度(以字元為單位);同樣地,使用 maxlength 設定輸入電話號碼的最大長度。

下面的示例建立了一個 20 個字元寬的電話號碼輸入框,要求內容長度不短於 9 個字元,且不長於 14 個字元。

html
<input
  id="telNo"
  name="telNo"
  type="tel"
  size="20"
  minlength="9"
  maxlength="14" />

備註: 上述屬性確實會影響驗證——如果值的長度小於 9 個字元或超過 14 個字元,上述示例的輸入框將被視為無效。大多數瀏覽器甚至不允許你輸入超過最大長度的值。

提供預設選項

使用值屬性提供單個預設值

一如既往,你可以透過設定其 value 屬性為 tel 輸入框提供一個預設值

html
<input id="telNo" name="telNo" type="tel" value="333-4444-4444" />

提供建議值

更進一步,你可以提供一個預設電話號碼列表供使用者選擇。要做到這一點,請使用 list 屬性。這並不會將使用者限制在這些選項中,但可以讓他們更快地選擇常用的電話號碼。這也為autocomplete提供了提示。list 屬性指定了一個 <datalist> 元素的 ID,該元素反過來為每個建議值包含一個 <option> 元素;每個 optionvalue 是電話號碼輸入框對應的建議值。

html
<label for="telNo">Phone number: </label>
<input id="telNo" name="telNo" type="tel" list="defaultTels" />

<datalist id="defaultTels">
  <option value="111-1111-1111"></option>
  <option value="122-2222-2222"></option>
  <option value="333-3333-3333"></option>
  <option value="344-4444-4444"></option>
</datalist>

有了 <datalist> 元素及其 <option>s,瀏覽器會提供指定的值作為電話號碼的可能值;這通常以包含建議的彈出選單或下拉選單的形式呈現。雖然具體的使用者體驗可能因瀏覽器而異,但通常點選編輯框會顯示一個建議電話號碼的下拉列表。然後,隨著使用者的輸入,列表會調整以僅顯示篩選後的匹配值。使用者每輸入一個字元都會縮小列表範圍,直到使用者做出選擇或輸入一個自定義值。

以下是它可能看起來像的截圖

An input box has focus with a blue focus ring. The input has a drop-down menu showing four phone numbers the user can select.

驗證

正如我們之前提到的,為電話號碼提供一個“一刀切”的客戶端驗證解決方案是相當困難的。那麼我們能做些什麼呢?讓我們考慮一些選項。

警告: HTML 表單驗證不能替代伺服器端指令碼,後者確保輸入的資料在被允許進入資料庫之前格式正確。有人很容易就能對 HTML 進行調整,從而繞過驗證,或者完全移除它。也有可能有人完全繞過你的 HTML,直接向你的伺服器提交資料。如果你的伺服器端程式碼未能驗證它接收到的資料,當格式不正確的資料(或資料過大、型別錯誤等)被輸入到你的資料庫時,就可能引發災難。

將電話號碼設為必填項

你可以使用 required 屬性,使得空輸入無效並且不會提交到伺服器。例如,讓我們使用這個 HTML

html
<form>
  <div>
    <label for="telNo">Enter a telephone number (required): </label>
    <input id="telNo" name="telNo" type="tel" required />
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

然後我們加入以下 CSS,用對勾標記有效條目,用叉號標記無效條目

css
div {
  margin-bottom: 10px;
  position: relative;
}

input[type="number"] {
  width: 100px;
}

input + span {
  padding-right: 30px;
}

input:invalid + span::after {
  position: absolute;
  content: "✖";
  padding-left: 5px;
  color: darkred;
}

input:valid + span::after {
  position: absolute;
  content: "✓";
  padding-left: 5px;
  color: #009000;
}

輸出如下所示

模式驗證

如果你想進一步限制輸入的號碼,使其必須符合特定的模式,你可以使用 pattern 屬性,它的值是一個正則表示式,輸入的值必須與之匹配。

在這個例子中,我們將使用與之前相同的 CSS,但我們的 HTML 改為如下所示

html
<form>
  <div>
    <label for="telNo">
      Enter a telephone number (in the form xxx-xxx-xxxx):
    </label>
    <input
      id="telNo"
      name="telNo"
      type="tel"
      required
      pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" />
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

請注意,除非匹配 xxx-xxx-xxxx 模式,否則輸入的值會被報告為無效;例如,41-323-421 將不被接受。800-MDN-ROCKS 也不會被接受。然而,865-555-6502 將被接受。這種特定的模式顯然只適用於某些地區——在實際應用中,你可能需要根據使用者的地區來改變使用的模式。

示例

在這個例子中,我們提供了一個 <select> 元素,讓使用者選擇他們所在的國家,以及一組 <input type="tel"> 元素讓他們輸入電話號碼的每個部分;完全可以有多個 tel 輸入框。

每個輸入框都有一個 placeholder 屬性,向有視力的使用者顯示輸入內容的提示;一個 pattern 屬性,為所需部分強制執行特定數量的字元;以及一個 aria-label 屬性,包含一個要為螢幕閱讀器使用者讀出的提示,告訴他們該輸入什麼。

html
<form>
  <div>
    <label for="country">Choose your country:</label>
    <select id="country" name="country">
      <option>UK</option>
      <option selected>US</option>
      <option>Germany</option>
    </select>
  </div>
  <div>
    <p>Enter your telephone number:</p>
    <span class="areaDiv">
      <input
        id="areaNo"
        name="areaNo"
        type="tel"
        required
        placeholder="Area code"
        pattern="[0-9]{3}"
        aria-label="Area code" />
      <span class="validity"></span>
    </span>
    <span class="number1Div">
      <input
        id="number1"
        name="number1"
        type="tel"
        required
        placeholder="First part"
        pattern="[0-9]{3}"
        aria-label="First part of number" />
      <span class="validity"></span>
    </span>
    <span class="number2Div">
      <input
        id="number2"
        name="number2"
        type="tel"
        required
        placeholder="Second part"
        pattern="[0-9]{4}"
        aria-label="Second part of number" />
      <span class="validity"></span>
    </span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

JavaScript 包含一個 onchange 事件處理器,當 <select> 的值改變時,它會更新 <input> 元素的 patternplaceholderaria-label,以適應那個國家/地區的電話號碼格式。

js
const selectElem = document.querySelector("select");
const inputElems = document.querySelectorAll("input");

selectElem.onchange = () => {
  for (const e of inputElems) {
    e.value = "";
  }

  if (selectElem.value === "US") {
    inputElems[2].parentNode.style.display = "inline";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3}";

    inputElems[1].placeholder = "First part";
    inputElems[1].pattern = "[0-9]{3}";
    inputElems[1].setAttribute("aria-label", "First part of number");

    inputElems[2].placeholder = "Second part";
    inputElems[2].pattern = "[0-9]{4}";
    inputElems[2].setAttribute("aria-label", "Second part of number");
  } else if (selectElem.value === "UK") {
    inputElems[2].parentNode.style.display = "none";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3,6}";

    inputElems[1].placeholder = "Local number";
    inputElems[1].pattern = "[0-9]{4,8}";
    inputElems[1].setAttribute("aria-label", "Local number");
  } else if (selectElem.value === "Germany") {
    inputElems[2].parentNode.style.display = "inline";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3,5}";

    inputElems[1].placeholder = "First part";
    inputElems[1].pattern = "[0-9]{2,4}";
    inputElems[1].setAttribute("aria-label", "First part of number");

    inputElems[2].placeholder = "Second part";
    inputElems[2].pattern = "[0-9]{4}";
    inputElems[2].setAttribute("aria-label", "Second part of number");
  }
};

這個例子看起來是這樣的

這是一個有趣的想法,展示了處理國際電話號碼問題的一個潛在解決方案。當然,你必須擴充套件這個例子,為可能每一個國家提供正確的模式,這將是一項大量的工作,而且仍然不能完全保證使用者會正確輸入他們的號碼。

這讓你思考,是否值得在客戶端花費這麼多功夫,而你可以讓使用者在客戶端以任何他們想要的格式輸入他們的號碼,然後在伺服器上進行驗證和清理。但這個選擇由你來做。

技術摘要

一個表示電話號碼的字串,或為空
事件 changeinput
支援的常見屬性 autocompletelistmaxlengthminlengthpatternplaceholderreadonlysize
IDL 屬性 listselectionStartselectionEndselectionDirectionvalue
DOM 介面 HTMLInputElement
方法 select()setRangeText()setSelectionRange()
隱式 ARIA 角色 list 屬性:textbox 帶有 list 屬性:combobox

規範

規範
HTML
# telephone-state-(type=tel)

瀏覽器相容性

另見