Moderní tvorba webových aplikací
O webu

Jak udělat input s automatickou šířkou podle obsahu

Několik způsobů, jak dosáhnout toho, aby se textové pole rozšiřovalo a zužovalo podle délky zadaného textu.

9 minut

Běžný <input>pevnou šířku. Někdy je ale potřeba, aby se pole přizpůsobilo délce textu, který obsahuje – například v inline editoru, při úpravě tagů nebo v dynamických formulářích.

CSS řešení: field-sizing

Od roku 2024 prohlížeče podporují novou CSS vlastnost field-sizing, která tento problém řeší elegantně a bez JavaScriptu.

input {
  field-sizing: content;
  min-width: 50px;
  max-width: 300px;
}

Vlastnost field-sizing: content způsobí, že se input automaticky rozšíří podle obsahu. Je vhodné přidat min-widthmax-width pro rozumné limity.

Toto řešení funguje i pro <textarea><select>.

Podpora v prohlížečích

Vlastnost field-sizing podporují všechny moderní prohlížeče: Chrome 123+, Edge 123+, Firefox 132+Safari 18+.

Textarea

U <textarea> funguje field-sizing: content ještě lépe – element se automaticky zvětšuje jak na šířku, tak na výšku podle obsahu.

textarea {
  field-sizing: content;
  min-height: 1lh;
  max-height: 10lh;
}

Jednotka lh odpovídá výšce řádku, takže max-height: 10lh omezí textarea na maximálně 10 řádků.

Tailwind CSS

V Tailwind CSS lze použít třídu field-sizing-content:

<input type="text" class="field-sizing-content min-w-12 max-w-xs" />

JavaScript řešení

Pro starší prohlížeče je potřeba použít JavaScript. Princip spočívá v měření šířky textu a nastavení šířky inputu.

Měření pomocí canvas

Nejpřesnější způsob je měřit text pomocí canvas:

function adjustInputWidth(input) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const style = getComputedStyle(input);
  ctx.font = style.font;

  const textWidth = ctx.measureText(input.value || input.placeholder).width;
  const padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
  const border = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);

  input.style.width = Math.ceil(textWidth + padding + border + 2) + 'px';
}

// Použití
const input = document.querySelector('input');
input.addEventListener('input', () => adjustInputWidth(input));
adjustInputWidth(input);

Měření pomocí skrytého elementu

Alternativní způsob využívá skrytý <span> se stejným stylem:

function adjustInputWidth(input) {
  const span = document.createElement('span');
  span.style.cssText = `
    position: absolute;
    visibility: hidden;
    white-space: pre;
    font: ${getComputedStyle(input).font};
  `;
  span.textContent = input.value || input.placeholder || 'M';
  document.body.appendChild(span);

  input.style.width = span.offsetWidth + 'px';
  span.remove();
}

const input = document.querySelector('input');
input.addEventListener('input', () => adjustInputWidth(input));
adjustInputWidth(input);

CSS jednotka ch

Pro jednoduché případy s monospace fontem lze využít CSS jednotku ch, která odpovídá šířce znaku „0”.

input {
  font-family: monospace;
  width: 10ch; /* šířka 10 znaků */
}

V kombinaci s JavaScriptem:

input.style.width = (input.value.length || 1) + 'ch';

Toto řešení nefunguje spolehlivě s proporcionálními fonty, kde mají znaky různou šířku („i” vs ”m").

Alternativa: contenteditable

Místo <input> lze použít element s atributem contenteditable, který se automaticky rozšiřuje:

<span contenteditable="true" role="textbox"></span>
[contenteditable] {
  display: inline-block;
  min-width: 50px;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

Nevýhodou je, že contenteditable nepodporuje některé vlastnosti inputu jako placeholder, maxlength nebo validaci formuláře.

Zkus psát…

HTML atribut size

Nejjednodušší způsob je použít HTML atribut size, který určuje šířku v počtu znaků:

<input type="text" size="10">

V kombinaci s JavaScriptem:

input.addEventListener('input', () => {
  input.size = Math.max(1, input.value.length);
});

Atribut size funguje podobně jako jednotka ch – počítá průměrnou šířku znaku. U proporcionálních fontů tak nebude kvůli různé šířce výsledek přesný.

CSS Grid trik

Čistě CSS řešení využívající display: griddata-value atribut:

<label class="auto-input">
  <input type="text" oninput="this.parentNode.dataset.value = this.value">
</label>
.auto-input {
  display: inline-grid;
}

.auto-input::after,
.auto-input > input {
  grid-area: 1 / 1;
}

.auto-input::after {
  content: attr(data-value) ' ';
  visibility: hidden;
  white-space: pre;
}

.auto-input > input {
  width: auto;
  min-width: 1em;
}

Input a pseudo-element ::after sdílejí stejnou grid buňku. Pseudo-element je neviditelný, ale roztahuje kontejner podle obsahu.

Wrapper s absolutní posicí

Podobný princip – input překrývá span se stejným obsahem:

<span class="input-wrapper">
  <span class="input-sizer"></span>
  <input type="text">
</span>
.input-wrapper {
  display: inline-block;
  position: relative;
}

.input-sizer {
  visibility: hidden;
  white-space: pre;
  padding: 0 2px;
}

.input-wrapper input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}
const input = document.querySelector('input');
const sizer = document.querySelector('.input-sizer');

input.addEventListener('input', () => {
  sizer.textContent = input.value || input.placeholder || 'M';
});

Výhodou je, že span používá přesně stejný font a velikost jako input, takže měření je přesné.

Zkus psát…

Doporučení

  1. Moderní prohlížeče – použijte field-sizing: content (funguje ve všech).
  2. Bez JavaScriptu – CSS Grid trik s data-value.
  3. Starší prohlížeče – přidejte JavaScript fallback (canvas nebo wrapper).
  4. Monospace fonty – stačí jednotka ch nebo atribut size.
  5. Komplexní případy – zvažte contenteditable.
/* Progresivní vylepšení */
input {
  width: 150px; /* fallback */
}

@supports (field-sizing: content) {
  input {
    field-sizing: content;
    min-width: 50px;
    max-width: 300px;
  }
}

Související články

HTTP metody GET a POST

Kdy použít metodu GET a kdy POST. Rozdíly mezi metodami, datové limity a doporučení pro správné použití.

7 minut

Možnosti stylování <iframe>

Co lze a nelze u <iframe> ovlivnit pomocí CSS a jak na změnu textu nebo barev.

10 minut

HTML značka <keygen>

K čemu sloužila HTML značka <keygen>.

7 minut

Vložení CSS do stránky

Jakými všemi způsoby připojit CSS do stránky.

9 minut

Novinky e-mailem

Když budu mít něco opravdu zajímavého, můžu vám to poslat e-mailem

Přidej se k 500+ čtenářům
Jen kvalitní obsah
Žádný spam

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků
2013–2026