web-dev-qa-db-fra.com

Ajuster la largeur du champ d'entrée à son entrée

<html>
  <head>
  </head>
  <body>
    <input type="text" value="1" style="min-width:1px;" />
  </body>
</html>

Ceci est mon code et il ne fonctionne pas. Existe-t-il un autre moyen d'utiliser HTML, JavaScript, PHP ou CSS pour définir la largeur minimale?

Je veux un champ de saisie de texte avec une largeur qui change de façon dynamique, de sorte que le champ de saisie s’écoule autour de son contenu. Chaque entrée a un padding intégré de 2em, c'est le problème et le deuxième problème est que min-width ne fonctionne pas du tout sur l'entrée.

Si je règle la largeur plus que nécessaire, le programme tout entier est en désordre, il me faut une largeur de 1px, plus que si c'est nécessaire.

125
Kerc

Il semble que vous attendiez que le style soit appliqué dynamiquement à la largeur de la zone de texte en fonction du contenu de la zone de texte. Si oui, vous aurez besoin de js pour fonctionner sur le contenu de la zone de texte changeant, quelque chose comme this :

<input id="txt" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Remarque: cette solution ne fonctionne que lorsque tous les caractères ont exactement 8px de large.

73
Tahbaza

Pour calculer la largeur de l'entrée actuelle, vous devez l'incorporer dans un élément temporaire span, attachez-la au DOM, obtenez la largeur calculée (en pixels) à l'aide de la propriété scrollWidth et supprimez à nouveau la span. Bien entendu, vous devez vous assurer que la même famille de polices, la même taille, etc. sont utilisées dans les éléments input et span. Par conséquent, je leur ai assigné la même classe.

J'ai attaché la fonction à l'événement keyup, car sur keypress, le caractère en entrée n'est pas encore ajouté à l'entrée value, ce qui entraînerait une largeur incorrecte. Malheureusement, je ne sais pas comment me débarrasser du défilement du champ de saisie (lors de l'ajout de caractères à la fin du champ); il défile, car le caractère est ajouté et affiché avant l'appel de adjustWidthOfInput(). Et, comme je l'ai dit, je ne peux pas faire cela à l'inverse car vous aurez alors la valeur du champ de saisie avant le caractère saisi est inséré. Je vais essayer de résoudre ce problème plus tard.

Au fait, je n’ai testé cela que dans Firefox (3.6.8), mais vous comprendrez ce que j’espère.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Get/set width of &lt;input&gt;</title>
    <style>
      body {
        background: #666;
      }

      .input-element {
        border: 0;
        padding: 2px;
        background: #fff;
        font: 12pt sans-serif;
      }

      .tmp-element {
        visibility: hidden;
        white-space: pre;
      }
    </style>
  </head>
  <body>
    <input id="theInput" type="text" class="input-element" value="1">
    <script>
      var inputEl = document.getElementById("theInput");

      function getWidthOfInput() {
        var tmp = document.createElement("span");
        tmp.className = "input-element tmp-element";
        tmp.innerHTML = inputEl.value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        document.body.appendChild(tmp);
        var theWidth = tmp.getBoundingClientRect().width;
        document.body.removeChild(tmp);
        return theWidth;
      }

      function adjustWidthOfInput() {
        inputEl.style.width = getWidthOfInput() + "px";
      }

      adjustWidthOfInput();
      inputEl.onkeyup = adjustWidthOfInput;
    </script>
  </body>
</html>
58
Marcel Korpel

Dans les versions de navigateur modernes, l'unité CSS ch est également disponible. Si je comprends bien, il s'agit d'une unité indépendante de la police, où 1ch est égal à la largeur du caractère 0 (zéro) dans une police donnée.

Ainsi, quelque chose d'aussi simple que ce qui suit pourrait être utilisé comme fonction de redimensionnement:

var input = document.querySelector('input'); // get the input element
input.addEventListener('input', resizeInput); // bind the "resizeInput" callback on "input" event
resizeInput.call(input); // immediately call the function

function resizeInput() {
  this.style.width = this.value.length + "ch";
}
input{ font-size:1.3em; padding:.5em; }
<input>

Cet exemple redimensionnerait "elem" à la longueur de la valeur + 2 caractères supplémentaires.

47
Jani Jalkala

Voici une modification de la réponse de Lyth qui prend en compte:

  • Effacement 
  • Initialisation
  • Placeholders

Il permet également un nombre quelconque de champs de saisie! Pour le voir en action: http://jsfiddle.net/4Qsa8/

Script:

$(document).ready(function () {
    var $inputs = $('.resizing-input');

    // Resize based on text if text.length > 0
    // Otherwise resize based on the placeholder
    function resizeForText(text) {
        var $this = $(this);
        if (!text.trim()) {
            text = $this.attr('placeholder').trim();
        }
        var $span = $this.parent().find('span');
        $span.text(text);
        var $inputSize = $span.width();
        $this.css("width", $inputSize);
    }

    $inputs.find('input').keypress(function (e) {
        if (e.which && e.charCode) {
            var c = String.fromCharCode(e.keyCode | e.charCode);
            var $this = $(this);
            resizeForText.call($this, $this.val() + c);
        }
    });

    // Backspace event only fires for keyup
    $inputs.find('input').keyup(function (e) { 
        if (e.keyCode === 8 || e.keyCode === 46) {
            resizeForText.call($(this), $(this).val());
        }
    });

    $inputs.find('input').each(function () {
        var $this = $(this);
        resizeForText.call($this, $this.val())
    });
});

Style: 

.resizing-input input, .resizing-input span {
    font-size: 12px;
    font-family: Sans-serif;
    white-space: pre;
    padding: 5px;
}

HTML:

<div class="resizing-input">
    <input type="text" placeholder="placeholder"/>
    <span  style="display:none"></span>
</div>

$(document).ready(function() {
  var $inputs = $('.resizing-input');

  // Resize based on text if text.length > 0
  // Otherwise resize based on the placeholder
  function resizeForText(text) {
    var $this = $(this);
    if (!text.trim()) {
      text = $this.attr('placeholder').trim();
    }
    var $span = $this.parent().find('span');
    $span.text(text);
    var $inputSize = $span.width();
    $this.css("width", $inputSize);
  }

  $inputs.find('input').keypress(function(e) {
    if (e.which && e.charCode) {
      var c = String.fromCharCode(e.keyCode | e.charCode);
      var $this = $(this);
      resizeForText.call($this, $this.val() + c);
    }
  });

  // Backspace event only fires for keyup
  $inputs.find('input').keyup(function(e) {
    if (e.keyCode === 8 || e.keyCode === 46) {
      resizeForText.call($(this), $(this).val());
    }
  });

  $inputs.find('input').each(function() {
    var $this = $(this);
    resizeForText.call($this, $this.val())
  });
});
.resizing-input input,
.resizing-input span {
  font-size: 12px;
  font-family: Sans-serif;
  white-space: pre;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="resizing-input">
  First:
  <input type="text" placeholder="placeholder" />
  <span style="display:none"></span>
</div>
<br>

25
Michael

POUR UN REGARD NICER & FEEL

Vous devez utiliser l'événement jQuery keypress () en combinaison avec String.fromCharCode (e.which) pour obtenir le caractère saisi. Par conséquent, vous pouvez calculer votre largeur sera. Pourquoi? Parce que ça aura l'air beaucoup plus sexy :)

Voici un jsfiddle qui entraîne un comportement agréable comparé aux solutions utilisant l'événement keyup: http://jsfiddle.net/G4FKW/3/

Ci-dessous est un JS Vanilla qui écoute l'événement input d'un élément <input> et définit un frère span pour qu'il ait la même valeur de texte afin de le mesurer.

document.querySelector('input').addEventListener('input', onInput)

function onInput(){
    var spanElm = this.nextElementSibling;
    spanElm.textContent = this.value; // the hidden span takes the value of the input; 
    this.style.width = spanElm.offsetWidth + 'px'; // apply width of the span to the input
};
/* it's important the input and its span have same styling */
input, .measure {
    padding: 5px;
    font-size: 2.3rem;
    font-family: Sans-serif;
    white-space: pre; /* white-spaces will work effectively */
}

.measure{  
  position: absolute;
  left: -9999px;
  top: -9999px;
}
<input type="text" />
<span class='measure'></span>

15
Lyth

Voici une solution sans police à espacement fixe nécessaire, avec seulement un très petit code javascript , ne nécessite pas de calcul des styles calculés , et même support ime , support textes RTL .

// copy the text from input to the span
    $(function () {
      $('.input').on('input', function () { $('.text').text($('.input').val()); });
    });
    * {
      box-sizing: border-box;
    }
    
    .container {
      display: inline-block;
      position: relative;
    }
    
    .input,
    .text {
      margin: 0;
      padding: 2px 10px;
      font-size: 24px;
      line-height: 32px;
      border: 1px solid #ccc;
      box-radius: 3px;
      height: 36px;
      font: 20px/20px sans-serif;
      /* font: they should use same font; */
    }

    .text {
      padding-right: 20px;
      display: inline-block;
      visibility: hidden;
      white-space: pre;
    }
    
    .input {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
    }
    
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>

<div class="container">
  <span class="text">
    some text
  </span>
  <input class="input" value="some text" />
</div>

Utilisez le span.text pour ajuster la largeur du texte et laissez l'entrée avoir la même taille que position: absolute dans le conteneur. Copiez la valeur de l'entrée dans span chaque fois qu'elle a été modifiée (vous pouvez facilement changer ce code en Vanilla js). Donc, l'entrée va juste "s'adapter" à la taille de son contenu.

11
tsh

Vous pouvez également définir la largeur d'une entrée à l'aide de l'attribut size. La taille d'une entrée détermine sa largeur en caractères.

Une entrée peut ajuster sa taille de manière dynamique en écoutant les événements clés.

Par exemple

$("input[type='text']").bind('keyup', function () {
    $(this).attr("size", $(this).val().length );
});

JsFiddle ici

8
brendan

Voici un autre moyen de résoudre ce problème en utilisant une DIV et la propriété 'contenteditable':

HTML:

<div contenteditable = "true" class = "fluidInput" data-placeholder = ""></div>

CSS: (pour donner quelques dimensions au DIV et le rendre plus facile à voir)

.fluidInput {

    display         : inline-block;
    vertical-align  : top;

    min-width       : 1em;
    height          : 1.5em;

    font-family     : Arial, Helvetica, sans-serif;
    font-size       : 0.8em;
    line-height     : 1.5em;

    padding         : 0px 2px 0px 2px;
    border          : 1px solid #aaa;
    cursor          : text;
}


.fluidInput * {

    display         : inline;

}


.fluidInput br  {

    display         : none;

}


.fluidInput:empty:before {

    content         : attr(data-placeholder);
    color           : #ccc;

}

Remarque: Si vous envisagez d'utiliser cet élément à l'intérieur d'un élément FORM que vous prévoyez de soumettre, vous devrez utiliser Javascript/jQuery pour capturer l'événement submit afin que vous puissiez analyser la 'valeur' ​​(respectivement .innerHTML ou .html() DIV.

7
logic8

Vous pourriez faire quelque chose comme ceci

// HTML
<input id="input" type="text" style="width:3px" />
// jQuery
$(function(){
  $('#input').keyup(function(){
    $('<span id="width">').append( $(this).val() ).appendTo('body');
    $(this).width( $('#width').width() + 2 );
    $('#width').remove();
  });
});

Le plus grand centre commercial

Le plus grand centre commercial

7
Ties

Voici un fichier JS simple et un plugin jQuery que j'ai écrit qui gèrent le redimensionnement d'un élément d'entrée à l'aide d'un canevas et de la taille de la police/famille afin de déterminer la longueur réelle de la chaîne lors du rendu. (ne fonctionne que dans> IE9, Chrome, Safari, Firefox, Opera et la plupart des autres navigateurs principaux qui ont implémenté l’élément canvas).

PlainJS:

function autoSize(input, o) {
    o || (o = {});
    o.on || (o.on = 'keyup');

    var canvas = document.createElement('canvas');
    canvas.setAttribute('style', 'position: absolute; left: -9999px');
    document.body.appendChild(canvas);

    var ctx = canvas.getContext('2d');

    input.addEventListener(o.on, function () {
        ctx.font = getComputedStyle(this,null).getPropertyValue('font');
        this.style.width = ctx.measureText(this.value + '  ').width + 'px';
    });
}

//Usage
autoSize(document.getElementById('my-input'));

plugin jQuery:

$.fn.autoSize = function(o) {
  o = $.extend({}, {
    on: 'keyup'
  }, o);

  var $canvas = $('<canvas/>').css({position: 'absolute', left: -9999});
  $('body').append($canvas);

  var ctx = $canvas[0].getContext('2d');

  return this.on(o.on, function(){
    var $this = $(this);
    ctx.font = $this.css('font');
    $this.width(ctx.measureText($this.val()).width + 'px');
  })
}

//Usage:
$('#my-input').autoSize();

Remarque: cela ne gérera pas les transformations de texte, les espacements de lignes et les lettres, et probablement d'autres propriétés modifiant la taille du texte. Pour gérer le jeu de propriétés text-transform et ajuster la valeur text pour correspondre à cette propriété. Les autres sont probablement assez simples. Je vais mettre en œuvre si cela commence à gagner de la traction ...

4
newms87

Ceci est une réponse spécifique à Angular, mais cela a fonctionné pour moi et a été très satisfaisant en termes de simplicité et de facilité d'utilisation:

<input [style.width.ch]="value.length" [(ngModel)]="value" />

Il se met automatiquement à jour via les unités de caractères dans La réponse de Jani .

4
Chris Vandevelde

Vous pouvez le faire encore plus simplement dans angularjs en utilisant la directive intégrée ng-style .

Dans votre html:

  <input ng-style="inputStyle(testdata)" ng-model="testdata" />

Dans votre contrôleur:

 $scope.testdata = "whatever";

 $scope.inputStyle = function(str) {
    var charWidth = 7;
    return  {"width": (str.length +1) * charWidth + "px" };
    };

Dans votre css:

input { font-family:monospace; font-size:12px; }

Ajustez la largeur de caractères pour qu'elle corresponde à la largeur de votre police. Il semble être 7 à une taille de police de 12px;

2
michieljoris

Il est intéressant de noter qu'un joli redimensionnement peut être effectué lorsque la police est mono-espacée. Nous pouvons donc redimensionner parfaitement l'élément input à l'aide de l'unité ch.

Cette approche permet également de mettre à jour la largeur du champ en mettant simplement à jour une variable CSS (propriété personnalisée}) sur l'événement input. Nous devrions également prendre en charge les entrées déjà préremplies de l'événement DOMContentLoaded.

Démo Codepen


Balisage

<input type="text" value="space mono font" class="selfadapt" />

CSS

:root { --size: 0; }

.selfadapt {
   padding: 5px;
   min-width: 10ch;
   font-family: "space mono";
   font-size: 1.5rem;
   width: calc(var(--size) * 1ch);
}

En tant que variable racine, nous définissons --size: 0: cette variable contiendra la longueur de l'entrée et sera multipliée par 1ch dans l'expression calc(). Par défaut, nous pourrions également définir une largeur minimale, par exemple. 10ch

La partie Javascript lit la longueur de la valeur insérée et met à jour la variable --size:

JS

let input = document.querySelector('.selfadapt');
let root  = document.documentElement.style;

/* on input event auto resize the field */
input.addEventListener('input', function() {
   root.setProperty('--size', this.value.length );
});

/* resize the field if it is pre-populated */
document.addEventListener("DOMContentLoaded", function() {
   root.setProperty('--size', input.value.length);
});

bien sûr, cela fonctionne toujours même si vous n'utilisez pas de police à espacement fixe, mais dans ce cas, vous devrez modifier la formule calc() en multipliant la variable --size par une autre valeur (qui dépend strictement de font-family et font-size) différente de 1ch.

2
fcalderan

Si vous utilisez Bootstrap, cela pourrait se faire très facilement:

<div contenteditable="true" class="form-control" style="display: inline"></div>

Vous aurez juste besoin d'extraire le contenu de div et de le mettre dans une entrée masquée avant de soumettre le formulaire.

1
Alexey Kosov

Je pense que vous interprétez mal la propriété CSS min-width . min-width est généralement utilisé pour définir une largeur minimale de DOM dans une mise en page fluide, comme:

input {
  width: 30%;
  min-width: 200px;
}

Cela définirait l'élément d'entrée sur une largeur minimale de 200 pixels. Dans ce contexte, "px" signifie "pixels".

Maintenant, si vous essayez de vérifier que le champ de saisie contient au moins un caractère lorsqu'un utilisateur le soumet, vous devrez procéder à une validation du formulaire avec JavaScript et PHP. Si c'est effectivement ce que vous essayez de faire, je vais modifier cette réponse et faire de mon mieux pour vous aider.

1
peterjmag

J'ai beaucoup aimé la réponse de Lyth mais je voulais aussi:

  1. Gérer le retour arrière et supprimer
  2. Vous n'avez pas besoin d'ajouter manuellement une balise adjacente.
  3. Appliquer une largeur minimale.
  4. Être automatiquement appliqué aux éléments avec une classe spécifique

J'ai adapté son JSFiddle et suis venu avec this . Une amélioration non présente dans ce violon serait d'utiliser quelque chose comme analyseur CSS jQuery pour lire la largeur initiale de la règle input.textbox-autosize et l'utiliser comme minWidth. D'accord, j'utilise simplement un attribut sur le, ce qui en fait une démo compacte mais qui n'est pas idéale. car il nécessite un attribut supplémentaire sur chaque entrée. Vous voudrez peut-être aussi mettre minWidth à 100 dans le code JavaScript.

HTML:

<div id='applicationHost'>
<div>Name:   <input class='textbox-autosize' data-min-width='100' type="text" /></div>
<div>Email:  <input class='textbox-autosize' data-min-width='100' type="email" /></div>
<div>Points: <input class='textbox-autosize' data-min-width='100' type="number" /></div>
</div>

CSS:

#applicationHost {
    font-family: courier;
    white-space: pre;
}

input.textbox-autosize, span.invisible-autosize-helper {
    padding:0;
    font-size:12px;
    font-family:Sans-serif; 
    white-space:pre;
}
input.textbox-autosize {
    width: 100px; /* Initial width of textboxes */
}

/*
In order for the measurements to work out, your input and the invisible
span need to have the same styling.
*/

JavaScript:

$('#applicationHost').on('keyup', '.textbox-autosize', function(e) {
    // Add an arbitary buffer of 15 pixels.
    var whitespaceBuffer = 15;
    var je = $(this);
    var minWidth = parseInt(je.attr('data-min-width'));
    var newVal = je.val();
    var sizingSpanClass = 'invisible-autosize-helper';
    var $span = je.siblings('span.' + sizingSpanClass).first();
    // If this element hasn't been created yet, we'll create it now.
    if ($span.length === 0) {
        $span = $('<span/>', {
            'class': sizingSpanClass,
            'style': 'display: none;'
        });
        je.parent().append($span);
    }
    $span = je.siblings('span').first();
    $span.text(newVal) ; // the hidden span takes 
    // the value of the input
    $inputSize = $span.width();
    $inputSize += whitespaceBuffer;
    if($inputSize > minWidth)
        je.css("width", $inputSize) ; // apply width of the span to the input
    else
        je.css("width", minWidth) ; // Ensure we're at the min width
});
1
Josh

Il suffit d'ajouter d'autres réponses. 

J'ai remarqué que de nos jours, dans certains navigateurs, le champ de saisie a un scrollWidth. Ce qui signifie: 

this.style.width = this.scrollWidth + 'px';

devrait bien fonctionner. testé en chrome, firefox et safari. 

Pour la prise en charge de la suppression, vous pouvez d'abord ajouter '= 0' puis réajuster. 

this.style.width = 0; this.style.width = this.scrollWidth + 'px';
1
guy mograbi

Pourquoi ne pas utiliser que du CSS? 

<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

function keyup(e) {
	document.getElementById('ghost').innerText = e.target.value;
}
#wrapper {
  position: relative;
  min-width: 30px;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  border:1px solid blue;
  width: 100%;
}

#ghost {
  color: transparent;
}
<div id="wrapper">
  <input onkeyup="keyup(event)">
  <div id="ghost"></div>
</div>

wrapper {
  position: relative;
  min-width: 30px;
  border: 1px solid red;
  display: inline-block;
}

input {
  position: absolute;
  left:0;
  right:0;
  width: 100%;
}

#ghost {
  color: transparent;
}

ce code a été introduit par @Iain Todd et je pensais que je devrais le partager

0
Milad

Une solution générique à l'épreuve des balles doit:

  1. Prendre en compte tous les possibles styles de l'élément input mesuré 
  2. Être capable d'appliquer la mesure sur n'importe quelle entrée sans modifier le HTML ou 

Démo Codepen

var getInputValueWidth = (function(){
  // https://stackoverflow.com/a/49982135/104380
  function copyNodeStyle(sourceNode, targetNode) {
    var computedStyle = window.getComputedStyle(sourceNode);
    Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key)))
  }
  
  function createInputMeassureElm( inputelm ){
    // create a dummy input element for measurements
    var meassureElm = document.createElement('span');
    // copy the read input's styles to the dummy input
    copyNodeStyle(inputelm, meassureElm);
    
    // set hard-coded styles needed for propper meassuring 
    meassureElm.style.width = 'auto';
    meassureElm.style.position = 'absolute';
    meassureElm.style.left = '-9999px';
    meassureElm.style.top = '-9999px';
    meassureElm.style.whiteSpace = 'pre';
    
    meassureElm.textContent = inputelm.value || '';
    
    // add the meassure element to the body
    document.body.appendChild(meassureElm);
    
    return meassureElm;
  }
  
  return function(){
    return createInputMeassureElm(this).offsetWidth;
  }
})();


// delegated event binding
document.body.addEventListener('input', onInputDelegate)

function onInputDelegate(e){
  if( e.target.classList.contains('autoSize') )
    e.target.style.width = getInputValueWidth.call(e.target) + 'px';
}
input{ 
  font-size:1.3em; 
  padding:5px; 
  margin-bottom: 1em;
}

input.type2{
  font-size: 2.5em;
  letter-spacing: 4px;
  font-style: italic;
}
<input class='autoSize' value="type something">
<br>
<input class='autoSize type2' value="here too">

0
vsync

Basé sur la réponse de Michael, j'ai créé ma propre version de cela en utilisant jQuery. Je pense que c'est une version plus propre/plus courte de la plupart des réponses ici et cela semble faire le travail.

Je fais la même chose que la plupart des gens ici en utilisant une étendue pour écrire le texte d'entrée puis obtenir la largeur. Ensuite, je règle la largeur lorsque les actions keyup et blur sont appelées.

Voici un travail codepen . Ce codepen montre comment cela peut être utilisé avec plusieurs champs de saisie.

Structure HTML:

<input type="text" class="plain-field" placeholder="Full Name">
<span style="display: none;"></span>

jQuery:

function resizeInputs($text) {
    var text = $text.val().replace(/\s+/g, ' '),
        placeholder = $text.attr('placeholder'),
        span = $text.next('span');
        span.text(placeholder);
    var width = span.width();

    if(text !== '') {
        span.text(text);
    var width = span.width();
    }

    $text.css('width', width + 5);
};

La fonction ci-dessus obtient la valeur des entrées, réduit les espaces supplémentaires et définit le texte dans l'étendue pour obtenir la largeur. S'il n'y a pas de texte, il obtient à la place le paramètre fictif et l'inscrit dans la plage. Une fois que le texte est entré dans l'étendue, il définit ensuite la largeur de l'entrée. Le + 5 sur la largeur est dû au fait que sans cela, l'entrée est coupée dans le navigateur Edge.

$('.plain-field').each(function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('keyup blur', function() {
    var $text = $(this);
    resizeInputs($text);
});

$('.plain-field').on('blur', function() {
    var $text = $(this).val().replace(/\s+/g, ' ');
    $(this).val($text);
});

Si cela peut être amélioré, merci de me le faire savoir car c'est la solution la plus propre que je pourrais trouver.

0
Matthew

Mieux vaut onvalue:

<input id="txt" type="text" onvalue="this.style.width = ((this.value.length + 1) * 8) + 'px';">

Cela implique également de coller, glisser-déposer, etc.

0
Łukasz Polowczyk

Je passe juste un peu de temps à comprendre comment le faire.
En fait, le moyen le plus simple que j'ai trouvé est de déplacer la valeur d'entrée sur une plage juste avant l'entrée, en conservant la largeur du symbole 1. Bien que je ne puisse pas être sûr que cela convienne à votre besoin initial.
Peut-être un peu de code supplémentaire, mais dans l’application react + flux, c’est une solution tout à fait naturelle. 

0
freele

Cette réponse fournit l’une des méthodes les plus précises pour récupérer la largeur de texte disponible dans le navigateur et est plus précise que la réponse acceptée. Il utilise l'élément canvas html5 et, contrairement aux autres réponses, n'ajoute pas l'élément dans le DOM et évite ainsi tout problème de redistribution causé par l'ajout excessif d'éléments au DOM.

En savoir plus sur l'élément Canvas ici en relation avec la largeur du texte.

REMARQUE: Selon MDN , les versions abrégées de la méthode getPropertyValue() telles que la police peuvent ne pas être fiables. Je recommanderais d'obtenir les valeurs individuellement pour améliorer la compatibilité. Je ne l'ai utilisé ici que pour la vitesse.

/**
 * returns the width of child text of any DOM node as a float
 */
function getTextWidth(el) {
  // uses a cached canvas if available
  var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
  var context = canvas.getContext("2d");
  // get the full font style property
  var font = window.getComputedStyle(el, null).getPropertyValue('font');
  var text = el.value;
  // set the font attr for the canvas text
  context.font = font;
  var textMeasurement = context.measureText(text);
  return textMeasurement.width;
}

var input = document.getElementById('myInput');
// listen for any input on the input field
input.addEventListener('input', function(e) {
  var width = Math.floor(getTextWidth(e.target));
  // add 10 px to pad the input.
  var widthInPx = (width + 10) + "px";
  e.target.style.width = widthInPx;
}, false);
#myInput {
  font: normal normal 400 normal 18px / normal Roboto, sans-serif;
  min-width: 40px;
}
<input id="myInput" />

0
Matthew Brent

Voici mes 2 cents . Créer un div invisible invisible. Remplissez-le avec le contenu saisi et retournez la largeur dans le champ de saisie. Faites correspondre les styles de texte entre chaque case.

$(".answers_number").keyup(function(){
    $( "#number_box" ).html( $( this ).val() );
    $( this ).animate({
        width: $( "#number_box" ).width()+20
        }, 300, function() {
    });
});
#number_box {
   position: absolute;
   visibility: hidden;
   height: auto;
   width: auto;
   white-space: nowrap;
   padding:0 4px;
   /*Your font styles to match input*/
   font-family:Arial;
   font-size: 30px; 
}
    
.answers_number {
   font-size: 30px; 
   font-family:Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="answers_number" />
<div id="number_box">
</div>

0
Thomas Byy