Documentation CSS

概要

inputmode属性は、HTML5で導入されたグローバル属性で、テキスト入力時にモバイルデバイスで表示される仮想キーボード(ソフトウェアキーボード)の種類を制御します。この属性を適切に使用することで、ユーザーが入力内容に最適なキーボードを使用でき、入力効率とユーザー体験が大幅に向上します。

例えば、電話番号を入力するフィールドでは数字キーボードを、メールアドレスを入力するフィールドでは@記号が含まれたキーボードを表示させることができます。

inputmodeとtype属性の違い

inputmode属性とtype属性は似た機能を持つように見えますが、目的が異なります。

type属性の役割

type属性は入力データの意味と検証を定義します。

<!-- type属性:データの意味と検証を定義 -->
<input type="email" name="email">
<!-- ブラウザがメールアドレス形式を検証する -->

<input type="number" name="quantity">
<!-- 数値のみ入力可能、スピナーボタンが表示される -->

inputmode属性の役割

inputmode属性は表示されるキーボードの種類のみを制御します。

<!-- inputmode属性:キーボードの種類を制御 -->
<input type="text" inputmode="numeric" name="zipcode">
<!-- テキストとして扱われるが、数字キーボードが表示される -->

両者を組み合わせる場面

<!-- 郵便番号:ハイフン付きで入力させたいがキーボードは数字 -->
<input
  type="text"
  inputmode="numeric"
  pattern="[0-9]{3}-[0-9]{4}"
  placeholder="123-4567"
  name="postal-code"
>

<!-- クレジットカード番号:スペース区切りで入力 -->
<input
  type="text"
  inputmode="numeric"
  pattern="[0-9\s]{16,19}"
  placeholder="1234 5678 9012 3456"
  name="card-number"
>

inputmodeの値と使用例

none - キーボードを非表示

独自のキーボードやカスタム入力UIを使用する場合に指定します。

<!-- カスタム数字パッドを使用する場合 -->
<input
  type="text"
  inputmode="none"
  id="pin-input"
  readonly
  placeholder="4桁のPINを入力"
>
<div class="custom-numpad">
  <!-- カスタムキーボードUI -->
</div>
// カスタムキーボードの実装例
const pinInput = document.getElementById('pin-input');
const numpad = document.querySelector('.custom-numpad');

numpad.addEventListener('click', (e) => {
  if (e.target.matches('.numpad-key')) {
    const value = e.target.dataset.value;
    pinInput.value += value;
  }
});

text - 標準キーボード(デフォルト)

通常のテキスト入力に使用します。デフォルト値のため、明示的に指定する必要はほとんどありません。

<!-- 標準テキスト入力 -->
<input type="text" inputmode="text" name="fullname" placeholder="お名前">

<!-- 省略可能(デフォルト値) -->
<input type="text" name="fullname" placeholder="お名前">

decimal - 小数点付き数字キーボード

小数を含む数値入力に使用します。数字と小数点(. または ,)が入力しやすいキーボードが表示されます。

<!-- 価格入力 -->
<label for="price">価格(税込)</label>
<input
  type="text"
  inputmode="decimal"
  id="price"
  name="price"
  placeholder="1234.56"
>

<!-- 体重入力 -->
<label for="weight">体重(kg)</label>
<input
  type="text"
  inputmode="decimal"
  id="weight"
  name="weight"
  placeholder="65.5"
  step="0.1"
>

<!-- 座標入力 -->
<label for="latitude">緯度</label>
<input
  type="text"
  inputmode="decimal"
  id="latitude"
  name="latitude"
  placeholder="35.6812"
>

numeric - 数字のみキーボード

整数を入力する場合に使用します。数字キー(0-9)のみが表示されます。

<!-- 郵便番号(ハイフンなし) -->
<label for="zipcode">郵便番号</label>
<input
  type="text"
  inputmode="numeric"
  id="zipcode"
  name="zipcode"
  pattern="[0-9]{7}"
  maxlength="7"
  placeholder="1234567"
>

<!-- 認証コード -->
<label for="verification-code">認証コード(6桁)</label>
<input
  type="text"
  inputmode="numeric"
  id="verification-code"
  name="verification-code"
  pattern="[0-9]{6}"
  maxlength="6"
  autocomplete="one-time-code"
  placeholder="123456"
>

<!-- 年齢入力 -->
<label for="age">年齢</label>
<input
  type="text"
  inputmode="numeric"
  id="age"
  name="age"
  pattern="[0-9]{1,3}"
  maxlength="3"
  placeholder="25"
>

tel - 電話番号キーボード

電話番号入力に使用します。数字に加えて+*#などの電話関連記号が入力しやすいキーボードが表示されます。

<!-- 携帯電話番号 -->
<label for="mobile">携帯電話番号</label>
<input
  type="tel"
  inputmode="tel"
  id="mobile"
  name="mobile"
  pattern="[0-9]{3}-[0-9]{4}-[0-9]{4}"
  placeholder="090-1234-5678"
  autocomplete="tel"
>

<!-- 固定電話(市外局番含む) -->
<label for="phone">電話番号</label>
<input
  type="tel"
  inputmode="tel"
  id="phone"
  name="phone"
  placeholder="03-1234-5678"
  autocomplete="tel-national"
>

<!-- 国際電話番号 -->
<label for="intl-phone">電話番号(国際形式)</label>
<input
  type="tel"
  inputmode="tel"
  id="intl-phone"
  name="intl-phone"
  placeholder="+81-90-1234-5678"
>

search - 検索キーボード

検索入力に使用します。「検索」や「Go」ボタンが表示されるキーボードになります。

<!-- サイト内検索 -->
<form action="/search" method="get">
  <label for="site-search">サイト内検索</label>
  <input
    type="search"
    inputmode="search"
    id="site-search"
    name="q"
    placeholder="キーワードを入力"
  >
  <button type="submit">検索</button>
</form>

<!-- 商品検索 -->
<label for="product-search">商品を検索</label>
<input
  type="search"
  inputmode="search"
  id="product-search"
  name="product-query"
  placeholder="商品名やカテゴリ"
  list="search-suggestions"
>
<datalist id="search-suggestions">
  <option value="スマートフォン">
  <option value="タブレット">
  <option value="ノートパソコン">
</datalist>

email - メールアドレスキーボード

メールアドレス入力に使用します。@記号や.comなどが入力しやすいキーボードが表示されます。

<!-- メールアドレス入力 -->
<label for="email">メールアドレス</label>
<input
  type="email"
  inputmode="email"
  id="email"
  name="email"
  placeholder="example@mail.com"
  autocomplete="email"
  required
>

<!-- 会社メール入力 -->
<label for="work-email">会社のメールアドレス</label>
<input
  type="email"
  inputmode="email"
  id="work-email"
  name="work-email"
  placeholder="name@company.co.jp"
  autocomplete="work email"
>

url - URLキーボード

URL入力に使用します。/..comなどが入力しやすいキーボードが表示されます。

<!-- ウェブサイトURL -->
<label for="website">ウェブサイト</label>
<input
  type="url"
  inputmode="url"
  id="website"
  name="website"
  placeholder="https://example.com"
  autocomplete="url"
>

<!-- SNSプロフィールURL -->
<label for="twitter">Twitterプロフィール</label>
<input
  type="url"
  inputmode="url"
  id="twitter"
  name="twitter"
  placeholder="https://twitter.com/username"
  pattern="https://twitter\.com/.*"
>

<!-- ポートフォリオURL -->
<label for="portfolio">ポートフォリオ</label>
<input
  type="url"
  inputmode="url"
  id="portfolio"
  name="portfolio"
  placeholder="https://your-portfolio.com"
>

実践的なフォーム例

ユーザー登録フォーム

<form id="registration-form" action="/register" method="post">
  <!-- 氏名(標準キーボード) -->
  <div class="form-group">
    <label for="name">お名前</label>
    <input
      type="text"
      id="name"
      name="name"
      autocomplete="name"
      required
      placeholder="山田 太郎"
    >
  </div>

  <!-- メールアドレス(emailキーボード) -->
  <div class="form-group">
    <label for="reg-email">メールアドレス</label>
    <input
      type="email"
      inputmode="email"
      id="reg-email"
      name="email"
      autocomplete="email"
      required
      placeholder="example@mail.com"
    >
  </div>

  <!-- 電話番号(telキーボード) -->
  <div class="form-group">
    <label for="reg-phone">電話番号</label>
    <input
      type="tel"
      inputmode="tel"
      id="reg-phone"
      name="phone"
      autocomplete="tel"
      placeholder="090-1234-5678"
    >
  </div>

  <!-- 年齢(numericキーボード) -->
  <div class="form-group">
    <label for="reg-age">年齢</label>
    <input
      type="text"
      inputmode="numeric"
      id="reg-age"
      name="age"
      pattern="[0-9]{1,3}"
      maxlength="3"
      placeholder="25"
    >
  </div>

  <!-- ウェブサイト(urlキーボード) -->
  <div class="form-group">
    <label for="reg-website">ウェブサイト(任意)</label>
    <input
      type="url"
      inputmode="url"
      id="reg-website"
      name="website"
      placeholder="https://example.com"
    >
  </div>

  <button type="submit">登録する</button>
</form>
/* フォームのスタイル例 */
.form-group {
  margin-bottom: 1.5rem;
}

.form-group label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 600;
  color: #333;
}

.form-group input {
  width: 100%;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  border: 1px solid #ddd;
  border-radius: 8px;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.form-group input:focus {
  outline: none;
  border-color: #3178c6;
  box-shadow: 0 0 0 3px rgba(49, 120, 198, 0.2);
}

/* モバイル向けの調整 */
@media (max-width: 768px) {
  .form-group input {
    font-size: 16px; /* iOSでズームを防ぐ */
  }
}

決済フォーム

<form id="payment-form" action="/checkout" method="post">
  <!-- カード番号(numericキーボード) -->
  <div class="form-group">
    <label for="card-number">カード番号</label>
    <input
      type="text"
      inputmode="numeric"
      id="card-number"
      name="card-number"
      pattern="[0-9\s]{16,19}"
      maxlength="19"
      autocomplete="cc-number"
      placeholder="1234 5678 9012 3456"
    >
  </div>

  <!-- 有効期限 -->
  <div class="form-row">
    <div class="form-group half">
      <label for="expiry-month">有効期限(月)</label>
      <input
        type="text"
        inputmode="numeric"
        id="expiry-month"
        name="expiry-month"
        pattern="[0-9]{2}"
        maxlength="2"
        autocomplete="cc-exp-month"
        placeholder="MM"
      >
    </div>
    <div class="form-group half">
      <label for="expiry-year">有効期限(年)</label>
      <input
        type="text"
        inputmode="numeric"
        id="expiry-year"
        name="expiry-year"
        pattern="[0-9]{2}"
        maxlength="2"
        autocomplete="cc-exp-year"
        placeholder="YY"
      >
    </div>
  </div>

  <!-- セキュリティコード -->
  <div class="form-group">
    <label for="cvv">セキュリティコード</label>
    <input
      type="text"
      inputmode="numeric"
      id="cvv"
      name="cvv"
      pattern="[0-9]{3,4}"
      maxlength="4"
      autocomplete="cc-csc"
      placeholder="123"
    >
  </div>

  <!-- 金額表示(decimalキーボード) -->
  <div class="form-group">
    <label for="amount">お支払い金額</label>
    <input
      type="text"
      inputmode="decimal"
      id="amount"
      name="amount"
      readonly
      value="1,234.00"
    >
  </div>

  <button type="submit">支払いを確定</button>
</form>

住所入力フォーム

<form id="address-form">
  <!-- 郵便番号(numericキーボード) -->
  <div class="form-group">
    <label for="postal">郵便番号</label>
    <div class="postal-input">
      <input
        type="text"
        inputmode="numeric"
        id="postal"
        name="postal"
        pattern="[0-9]{3}-?[0-9]{4}"
        maxlength="8"
        autocomplete="postal-code"
        placeholder="123-4567"
      >
      <button type="button" id="address-lookup">住所検索</button>
    </div>
  </div>

  <!-- 都道府県(標準キーボード) -->
  <div class="form-group">
    <label for="prefecture">都道府県</label>
    <input
      type="text"
      id="prefecture"
      name="prefecture"
      autocomplete="address-level1"
      placeholder="東京都"
    >
  </div>

  <!-- 市区町村(標準キーボード) -->
  <div class="form-group">
    <label for="city">市区町村</label>
    <input
      type="text"
      id="city"
      name="city"
      autocomplete="address-level2"
      placeholder="渋谷区"
    >
  </div>

  <!-- 番地(標準キーボード) -->
  <div class="form-group">
    <label for="address-line">番地・建物名</label>
    <input
      type="text"
      id="address-line"
      name="address-line"
      autocomplete="street-address"
      placeholder="1-2-3 サンプルビル 101"
    >
  </div>
</form>

contenteditable要素での使用

inputmode属性はinput要素だけでなく、contenteditable属性を持つ要素でも使用できます。

<!-- 編集可能なdiv要素 -->
<div
  contenteditable="true"
  inputmode="text"
  class="editable-content"
  role="textbox"
  aria-label="メモ入力エリア"
>
  ここに自由にテキストを入力できます
</div>

<!-- 数字のみ入力可能な編集エリア -->
<div
  contenteditable="true"
  inputmode="numeric"
  class="editable-number"
  role="textbox"
  aria-label="数値入力"
>
  100
</div>
.editable-content,
.editable-number {
  padding: 1rem;
  border: 2px solid #ddd;
  border-radius: 8px;
  min-height: 100px;
  outline: none;
  transition: border-color 0.2s;
}

.editable-content:focus,
.editable-number:focus {
  border-color: #3178c6;
}

ブラウザサポートと注意点

ブラウザサポート状況

inputmode属性は主要なモバイルブラウザでサポートされています。

ブラウザサポート状況
Chrome(Android)サポート
Safari(iOS)サポート
Firefox(Android)サポート
Samsung Internetサポート
デスクトップブラウザ物理キーボード使用のため効果なし

注意点

1. デスクトップでは効果がない

inputmodeは仮想キーボードを制御するため、物理キーボードを使用するデスクトップ環境では効果がありません。

<!-- デスクトップでも正しく動作するよう、patternと併用 -->
<input
  type="text"
  inputmode="numeric"
  pattern="[0-9]*"
  title="半角数字を入力してください"
>

2. バリデーションは別途必要

inputmodeはキーボードを制御するだけで、入力値のバリデーションは行いません。

<!-- inputmodeだけでは不十分な例 -->
<input type="text" inputmode="numeric">
<!-- 数字キーボードが表示されるが、他の文字も入力可能 -->

<!-- 適切なバリデーションを追加 -->
<input
  type="text"
  inputmode="numeric"
  pattern="[0-9]+"
  required
  title="数字のみ入力してください"
>

3. type属性との組み合わせに注意

一部のtype属性は独自のキーボードを持つため、inputmodeが無視される場合があります。

<!-- type="number"は独自のキーボードを持つ -->
<input type="number" inputmode="tel">
<!-- inputmode="tel"は無視される可能性がある -->

<!-- 代わりにtype="text"を使用 -->
<input type="text" inputmode="tel" pattern="[0-9\-+()]+">

アクセシビリティの考慮

inputmodeを使用する際は、アクセシビリティも考慮することが重要です。

<!-- アクセシブルなフォーム入力 -->
<div class="form-group">
  <label for="phone-accessible">
    電話番号
    <span class="required">*</span>
  </label>
  <input
    type="tel"
    inputmode="tel"
    id="phone-accessible"
    name="phone"
    aria-required="true"
    aria-describedby="phone-hint phone-error"
    pattern="[0-9]{3}-[0-9]{4}-[0-9]{4}"
    placeholder="090-1234-5678"
  >
  <p id="phone-hint" class="hint">
    ハイフンを含めて入力してください
  </p>
  <p id="phone-error" class="error" aria-live="polite"></p>
</div>
.hint {
  font-size: 0.875rem;
  color: #666;
  margin-top: 0.25rem;
}

.error {
  font-size: 0.875rem;
  color: #dc3545;
  margin-top: 0.25rem;
}

.required {
  color: #dc3545;
}

まとめ

inputmode属性は、モバイルデバイスでのフォーム入力体験を大幅に向上させる強力なツールです。

主なポイントをまとめると以下の通りです。

  • 適切なキーボードの表示: 入力内容に応じた最適なキーボードを表示することで、入力効率が向上します
  • type属性との使い分け: typeはデータの意味と検証を、inputmodeはキーボードの種類を制御します
  • バリデーションとの併用: inputmodeだけでは入力値の検証はできないため、pattern属性や JavaScript でのバリデーションを併用しましょう
  • アクセシビリティの配慮: ラベル、ヒント、エラーメッセージを適切に設定し、すべてのユーザーが使いやすいフォームを作成しましょう

モバイルファーストの現代において、inputmode属性を活用することで、ユーザーにストレスのない入力体験を提供できます。

参考文献

円