Skip to content

text 文本输入

type="text"<input>默认类型,用于接收单行纯文本输入。它是表单中最基础、使用最频繁的输入控件。虽然看似简单,但 type="text" 支持许多实用的属性,如 maxlengthlistpattern 等,可以实现强大的文本输入控制。

前置知识

阅读本节前,建议先了解:input 标签总览

基础概念

什么是 text 输入

type="text" 创建一个单行文本输入框,用户可以在其中输入任意文本。它是 <input> 元素省略 type 属性时的默认值。

html
<!-- 以下两种写法完全等价 -->
<input type="text" name="username">
<input name="username">

text 的核心特征

特征说明
输入方式键盘输入
数据类型纯文本字符串
自动验证无(不会自动验证格式)
多行支持不支持(多行使用 <textarea>
移动端键盘标准全键盘

语法

基本语法

html
<input
  type="text"
  name="字段名"
  id="唯一标识"
  value="默认值"
  placeholder="占位提示"
  maxlength="最大字符数"
  minlength="最小字符数"
  size="可见宽度"
  pattern="正则表达式"
  required
  readonly
  disabled
  autocomplete="token"
  list="datalist的id"
  spellcheck="true|false"
  dirname="dir"
>

属性说明

属性值类型默认值说明
name字符串提交数据的键名
value字符串空字符串输入框的当前值
placeholder字符串空值时显示的灰色提示文字
maxlength非负整数无限制允许输入的最大字符数
minlength非负整数验证所需的最小字符数
size非负整数20输入框可见宽度(字符数)
pattern正则表达式输入值的验证模式
readonly布尔属性false只读,值可提交
disabled布尔属性false禁用,值不提交
list字符串关联的 <datalist> 的 id
spellchecktrue/false浏览器默认是否启用拼写检查
dirname字符串提交文本方向的字段名
autocompletetokenon自动补全类型

详细说明

value 属性

value 属性设置输入框的初始值。用户修改后,value 跟着变化。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>value 属性</title>
</head>
<body>
  <form action="/search" method="get">
    <!-- 预填充搜索关键词 -->
    <label for="keyword">搜索:</label>
    <input type="text" id="keyword" name="q" value="HTML5 教程">

    <button type="submit">搜索</button>
  </form>

  <script>
    const input = document.getElementById('keyword');

    // 读取当前值
    console.log(input.value);  // 输出:HTML5 教程

    // 通过 JS 修改值
    input.value = 'CSS3 教程';

    // 获取用户输入前的默认值
    console.log(input.defaultValue);  // 输出:HTML5 教程
  </script>
</body>
</html>

placeholder 属性

placeholder 在输入框为空时显示浅灰色提示文字,用户开始输入后自动消失。它不能替代 <label>,只是辅助提示。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>placeholder 属性</title>
  <style>
    .form-group {
      margin-bottom: 16px;
    }

    label {
      display: block;
      font-weight: 500;
      margin-bottom: 6px;
    }

    input {
      width: 300px;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 14px;
    }

    /* 自定义 placeholder 样式 */
    input::placeholder {
      color: #999;
      font-style: italic;
    }

    input:focus::placeholder {
      color: #ccc;
    }
  </style>
</head>
<body>
  <form>
    <div class="form-group">
      <!-- label 是必需的,placeholder 只是辅助提示 -->
      <label for="username">用户名</label>
      <input type="text"
             id="username"
             name="username"
             placeholder="3~20个字符,字母或数字"
             required>
    </div>

    <div class="form-group">
      <label for="email">邮箱地址</label>
      <input type="text"
             id="email"
             name="email"
             placeholder="例如:user@example.com">
    </div>

    <div class="form-group">
      <label for="phone">手机号码</label>
      <input type="text"
             id="phone"
             name="phone"
             placeholder="11位手机号码">
    </div>
  </form>
</body>
</html>

不要用 placeholder 替代 label

placeholder 在输入框有值时就会消失,而且屏幕阅读器默认不朗读 placeholder 内容。始终使用 <label> 标签来标识输入框的含义。

html
<!-- 错误!缺少 label -->
<input type="text" name="name" placeholder="请输入姓名">

<!-- 正确:有 label + placeholder -->
<label for="name">姓名</label>
<input type="text" id="name" name="name" placeholder="请输入真实姓名">

maxlength 和 minlength

maxlength 限制用户最多输入的字符数,超出后无法继续输入。minlength 设置验证所需的最小字符数,仅在提交时触发验证提示。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>maxlength 和 minlength</title>
</head>
<body>
  <form action="/register" method="post">
    <div>
      <label for="username">用户名(3~20个字符):</label>
      <input type="text"
             id="username"
             name="username"
             minlength="3"
             maxlength="20"
             required
             placeholder="请输入用户名">
      <!--
        maxlength="20":实时限制,最多输入20个字符
        minlength="3":提交时验证,少于3个字符会阻止提交
      -->
    </div>

    <div>
      <label for="bio">个人简介(最多200字):</label>
      <input type="text"
             id="bio"
             name="bio"
             maxlength="200"
             placeholder="简单介绍一下自己">
      <!--
        只设置了 maxlength,不设置 minlength
        用户可以不填写(非必填),但填了不能超过200字
      -->
    </div>

    <div>
      <label for="code">邀请码(固定6位):</label>
      <input type="text"
             id="code"
             name="code"
             maxlength="6"
             minlength="6"
             pattern="[A-Z0-9]{6}"
             required
             placeholder="6位邀请码">
    </div>

    <button type="submit">注册</button>
  </form>

  <script>
    // 显示剩余可输入字符数
    const bioInput = document.getElementById('bio');

    bioInput.addEventListener('input', function() {
      const remaining = this.maxLength - this.value.length;
      console.log(`还可输入 ${remaining} 个字符`);
    });
  </script>
</body>
</html>

maxlength 不区分中英文

maxlength 按字符数计算,不区分中英文。一个汉字算一个字符,一个英文字母也算一个字符。如果需要按字节限制,需要使用 JavaScript。

list 关联 datalist

list 属性将输入框与 <datalist> 元素关联,为用户提供预定义的建议列表。用户可以从建议中选择,也可以自由输入不在列表中的值。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>list 与 datalist</title>
</head>
<body>
  <h2>输入城市名称</h2>
  <form action="/weather" method="get">
    <label for="city">城市:</label>
    <input type="text"
           id="city"
           name="city"
           list="citySuggestions"
           placeholder="输入或选择城市">

    <!-- datalist 提供建议选项 -->
    <datalist id="citySuggestions">
      <option value="北京">
      <option value="上海">
      <option value="广州">
      <option value="深圳">
      <option value="杭州">
      <option value="成都">
      <option value="武汉">
      <option value="南京">
    </datalist>

    <button type="submit">查询天气</button>
  </form>

  <!--
    用户行为:
    1. 输入"北" → 显示"北京"建议
    2. 点击"北京" → 输入框填充为"北京"
    3. 也可以输入列表中没有的城市(如"重庆")
  -->
</body>
</html>

pattern 正则验证

pattern 属性使用正则表达式对输入值进行验证。当表单提交时,如果输入值不匹配 pattern,浏览器会显示验证失败提示。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>pattern 正则验证</title>
  <style>
    .form-group {
      margin-bottom: 16px;
    }

    label {
      display: block;
      font-weight: 500;
      margin-bottom: 4px;
    }

    input {
      padding: 8px;
      border: 1px solid #ccc;
      border-radius: 4px;
      width: 300px;
    }

    /* 验证失败的样式 */
    input:invalid:not(:placeholder-shown) {
      border-color: #e74c3c;
    }

    input:valid:not(:placeholder-shown) {
      border-color: #27ae60;
    }

    .hint {
      font-size: 12px;
      color: #999;
      margin-top: 4px;
    }
  </style>
</head>
<body>
  <form action="/submit" method="post">
    <!-- 只允许小写字母和数字 -->
    <div class="form-group">
      <label for="username">用户名(小写字母+数字):</label>
      <input type="text"
             id="username"
             name="username"
             pattern="^[a-z0-9]+$"
             title="只允许小写字母和数字"
             required
             placeholder="如:zhangsan123">
      <p class="hint">只允许小写字母(a-z)和数字(0-9)</p>
    </div>

    <!-- 中文姓名(2~4个汉字) -->
    <div class="form-group">
      <label for="realname">真实姓名:</label>
      <input type="text"
             id="realname"
             name="realname"
             pattern="^[\u4e00-\u9fa5]{2,4}$"
             title="请输入2~4个汉字"
             required
             placeholder="如:张三">
      <p class="hint">请输入2~4个汉字</p>
    </div>

    <!-- 自定义编号格式:字母-数字-字母 -->
    <div class="form-group">
      <label for="code">编号(如 A-123-B):</label>
      <input type="text"
             id="code"
             name="code"
             pattern="^[A-Z]-\d{3}-[A-Z]$"
             title="格式:大写字母-3位数字-大写字母"
             placeholder="如:A-001-B">
      <p class="hint">格式:大写字母-3位数字-大写字母</p>
    </div>

    <!-- 车牌号(简单示例) -->
    <div class="form-group">
      <label for="plate">车牌号:</label>
      <input type="text"
             id="plate"
             name="plate"
             pattern="^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤川青藏琼宁][A-Z][A-Z0-9]{5}$"
             title="请输入正确的车牌号"
             placeholder="如:京A12345">
      <p class="hint">如:京A12345</p>
    </div>

    <button type="submit">提交</button>
  </form>
</body>
</html>

pattern 需要配合 title

pattern 只定义验证规则,但浏览器内置的验证提示不会自动显示具体的格式说明。title 属性的值会作为验证失败时的补充提示。同时,title 也会在鼠标悬停时显示。

readonly 与 disabled 的区别

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>readonly 与 disabled</title>
</head>
<body>
  <form action="/submit" method="post">
    <h3>readonly:只读,可提交</h3>
    <label for="userId">用户ID(不可修改):</label>
    <input type="text" id="userId" name="user_id" value="10086" readonly>
    <!-- 用户可以看到值,但不能编辑。提交时 user_id=10086 会发送到服务器 -->

    <h3>disabled:禁用,不提交</h3>
    <label for="referral">推荐人(已禁用):</label>
    <input type="text" id="referral" name="referral" value="张三" disabled>
    <!-- 用户无法编辑,且提交时 referral 字段不会包含在表单数据中 -->

    <button type="submit">提交</button>
  </form>

  <script>
    const readonlyInput = document.getElementById('userId');
    const disabledInput = document.getElementById('referral');

    // readonly 的元素仍然可以获得焦点
    readonlyInput.focus(); // 成功

    // disabled 的元素不能获得焦点
    // disabledInput.focus(); // 无效

    // 可以通过 JS 修改 readonly 的值
    readonlyInput.value = '10087';

    // disabled 的元素通过 JS 修改值有效,但提交时仍不发送
    disabledInput.value = '李四';
  </script>
</body>
</html>
对比维度readonlydisabled
外观正常显示,略有不同灰色显示
可编辑
可获得焦点
Tab 可达
值随表单提交
JavaScript 可修改值
事件响应正常响应(如 click、focus)不响应

size 属性

size 属性控制输入框的可见宽度,以字符数为单位。它只影响外观,不影响实际可输入的字符数。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>size 属性</title>
</head>
<body>
  <form>
    <!-- size 不同,宽度不同 -->
    <div>
      <label>小输入框(size="10"):</label>
      <input type="text" name="short" size="10">
    </div>

    <div>
      <label>中输入框(size="20",默认):</label>
      <input type="text" name="medium" size="20">
    </div>

    <div>
      <label>大输入框(size="40"):</label>
      <input type="text" name="long" size="40">
    </div>

    <!--
      注意:size 只影响可见宽度,不影响 maxlength
      size="10" 的输入框也可以输入100个字符(如果没有 maxlength 限制)
      实际开发中通常使用 CSS 控制宽度,而非 size 属性
    -->
  </form>
</body>
</html>

建议

在现代开发中,推荐使用 CSS(如 widthmax-width)控制输入框宽度,而非 size 属性。size 属性在不同字体和浏览器下宽度不一致。

实战示例

带实时字符计数的输入框

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>字符计数输入框</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      max-width: 500px;
      margin: 40px auto;
      padding: 20px;
    }

    .form-group {
      margin-bottom: 20px;
    }

    label {
      display: block;
      font-weight: 500;
      margin-bottom: 6px;
    }

    input {
      width: 100%;
      padding: 10px 12px;
      border: 1px solid #ddd;
      border-radius: 6px;
      box-sizing: border-box;
      font-size: 14px;
    }

    .char-counter {
      text-align: right;
      font-size: 12px;
      color: #999;
      margin-top: 4px;
    }

    .char-counter.warning {
      color: #f39c12;
    }

    .char-counter.error {
      color: #e74c3c;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <h2>发布动态</h2>
  <form action="/post" method="post">
    <div class="form-group">
      <label for="title">标题</label>
      <input type="text"
             id="title"
             name="title"
             maxlength="50"
             placeholder="输入标题(最多50字)"
             required>
      <div class="char-counter" id="titleCounter">0 / 50</div>
    </div>

    <div class="form-group">
      <label for="nickname">昵称</label>
      <input type="text"
             id="nickname"
             name="nickname"
             maxlength="20"
             minlength="2"
             placeholder="2~20个字符"
             required>
      <div class="char-counter" id="nicknameCounter">0 / 20</div>
    </div>

    <button type="submit">发布</button>
  </form>

  <script>
    // 通用字符计数器
    function setupCounter(inputId, counterId) {
      const input = document.getElementById(inputId);
      const counter = document.getElementById(counterId);

      input.addEventListener('input', function() {
        const current = this.value.length;
        const max = this.maxLength;

        counter.textContent = `${current} / ${max}`;

        // 根据使用比例改变颜色
        const ratio = current / max;
        counter.classList.remove('warning', 'error');

        if (ratio > 0.9) {
          counter.classList.add('error');
        } else if (ratio > 0.7) {
          counter.classList.add('warning');
        }
      });
    }

    setupCounter('title', 'titleCounter');
    setupCounter('nickname', 'nicknameCounter');
  </script>
</body>
</html>

注意事项

  1. text 不适合多行文本:如果需要多行输入,使用 <textarea> 而非 type="text"<input type="text"> 始终是单行。

  2. maxlength 是硬限制maxlength 会实时阻止用户输入超过限制的字符。如果需要"软限制"(允许输入但提示超限),应使用 JavaScript。

  3. pattern 验证空值时通过:如果输入框为空且未设置 requiredpattern 验证会自动通过。pattern 只验证非空值。

  4. size 与 CSS width 冲突:如果同时设置了 size 和 CSS width,CSS 优先。

  5. placeholder 不是 label 的替代品placeholder 消失后用户无法知道输入框的用途。始终提供 <label>

最佳实践

  1. 为 text 输入设置合理的 maxlength:防止用户输入过长文本,也减轻服务器验证负担。

  2. 使用 pattern 补充验证:对于有固定格式的文本(如编号、车牌号、用户名格式),使用 pattern 进行客户端验证。

  3. 配合 list + datalist 提升体验:对于有固定选项但也有自定义输入需求的场景,list 关联 datalist 是最佳选择。

  4. 用 CSS 控制宽度,不用 size:使用 width: 100% 配合 box-sizing: border-box 确保响应式布局。

  5. 使用 autocomplete token:为文本输入指定正确的 autocomplete 值(如 nameusernamestreet-address),帮助浏览器更好地填充数据。

下一节

继续学习:password 密码输入

参考链接