20

I can't quite find a clear answer on this, and excuse me if there is one I've missed.

I want my text input widths to automatically adjust to the size of the content within them. First with placeholder text than the actual text someone inputs.

I've created the below as an example. Currently, the boxes are far bigger than my placeholder text, causing huge amounts of white space, and it's obviously the same thing when I type in something.

I've tried width auto, some jQuery, and twine and bubble gum I found on the internet. But nothing has worked yet. Any thoughts? Thanks!

HTML:

<span><p>Hello, my name is </p></span>

<span><input type="text" id="input" class="form" placeholder="name"></span>

<span><p>. I am </p></span>

<span><input type="text" id="input" class="form" placeholder="age"></span>

    <span><p> years old.</p></span>

CSS:

.form {
    border: 0;
    text-align: center;
    outline: none;
}

span {
    display: inline-block;
}

p {
    font-family: arial;
}

Fiddle

ObbyOss
  • 357
  • 1
  • 2
  • 14
  • 1
    There is no good way to do this. You would have to write a javascript function to check the length of your string on input change, then adjust the width of the input based on # of chars * character width. It looks like the code is already here: http://stackoverflow.com/questions/3392493/adjust-width-of-input-field-to-its-input. Just adjust the logic for when input === '', then make the width based on placeholder – Kevin F May 29 '15 at 03:58
  • 2
    Observation: Your name and age input should not have same id. – JGV May 29 '15 at 04:00
  • Possible solution is already discussed here: http://stackoverflow.com/questions/9328682/jquery-resizing-form-input-based-on-values-width – JGV May 29 '15 at 04:22
  • @vimala he want one more thing i.e at load input will take size of placeholder then it will work on value as you said in above discussed question he asked for only input value not for placeholder – Keval Bhatt May 29 '15 at 04:29
  • please check this answer regarding input resizing https://stackoverflow.com/a/62881524/12164315 – akim lyubchenko Jul 14 '20 at 08:28

5 Answers5

19

One possible way:

[contenteditable=true]:empty:before {
  content: attr(placeholder);
  color:gray;
}
/* found this online --- it prevents the user from being able to make a (visible) newline */
[contenteditable=true] br{
  display:none;
}
<p>Hello, my name is <span id="name" contenteditable="true" placeholder="name"></span>. I am <span id="age" contenteditable="true" placeholder="age"></span> years old.</p>

Source for CSS: http://codepen.io/flesler/pen/AEIFc.

You'll have to do some trickery to pick up the values if you need the values for a form.

sudo rm -rf slash
  • 1,156
  • 2
  • 16
  • 27
  • I actually like this approach! +1 – Rey Libutan May 29 '15 at 04:12
  • well you could always give it a class thats form related and then just cycle through all those values basically a seralize in manual form, then you should be set. – Daemedeor May 29 '15 at 04:18
  • Interesting solution. +1 from me. – JGV May 29 '15 at 04:19
  • 1
    While this looks like a nice approach, this allows the user to do markup in the text field. You can make italics for example by selecting the text and pressing ctrl/cmd i. If you paste text from other sites it'll even paste its entire markup. You can resolve this using javascript `ageElem.innerHTML = ageElem.textContent `. The trick is to call this at the right moments. Not just at key presses, also when the user pastes text. – Jespertheend Jul 07 '17 at 20:15
8

Use onkeypress even

see this example :http://jsfiddle.net/kevalbhatt18/yug04jau/7/

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

And for placeholder on load use jquery and apply placeholder size in to input

$('input').css('width',((input.getAttribute('placeholder').length + 1) * 8) + 'px');

Even you can use id instead of input this is just an example so that I used $(input)

And in css provide min-width

.form {
    border: 1px solid black;
    text-align: center;
    outline: none;
    min-width:4px;
}


EDIT:


If you remove all text from input box then it will take placeholder value using focusout

Example: http://jsfiddle.net/kevalbhatt18/yug04jau/8/

$("input").focusout(function(){

    if(this.value.length>0){
        this.style.width = ((this.value.length + 1) * 8) + 'px';
    }else{
      this.style.width = ((this.getAttribute('placeholder').length + 1) * 8) + 'px';
    }

});

Keval Bhatt
  • 6,224
  • 2
  • 24
  • 40
  • 1
    Observation: With this code, the textbox width is not returning back to normal once the text is cleared. – JGV May 29 '15 at 05:17
  • @vimala now check this updated code if anything goes wrong let me know :D – Keval Bhatt May 29 '15 at 05:40
  • 3
    This dynamic calculation will highly depend on font size and this is not gonna work always . –  Apr 26 '16 at 11:28
2
input.addEventListener('input', event => event.target.style.width = event.target.scrollWidth + 'px');

Unfortunately this will only increase the size of the input. If you delete characters the size will not decrease. For some use cases this is perfectly fine.

niklhs
  • 166
  • 9
Vlad
  • 385
  • 2
  • 13
  • 3
    I like your solution, pretty clean and elegant. Additionally, you can handle decreasing width like this: `input.style.width = '0'; // or any other default min-width you need` before changing width according to scrollWidth – Lerek Dec 15 '19 at 13:09
1

Kevin F is right, there is no native way to do it.

Here is a one way to do it if you really want it to happen.

In the code, there is an invisible span where the text is placed. Then we retrieve the width of the span.

https://jsfiddle.net/r02ma1n0/1/

var testdiv = $("#testdiv");
$("input").keydown( function(){
    var ME = $(this);
    //Manual Way
    //var px = 6.5;
    //var txtlength = ME.val().length;
    //$(this).css({width: txtlength * px });

   testdiv.html( ME.val() + "--");
   var txtlength = testdiv.width();
   ME.css({width: txtlength  }); 
});
  • Worth noting that the div has to have very similar style to the input otherwise that's not going to work well. Think font-size for example – Daniel Zohar Nov 09 '17 at 13:52
1

Try with 'size' attribute. This will work even when you clear the text . Need jQuery to work this

<div>
    <input id="txt" type="text" style="max-width: 100%;" placeholder="name">
</div>
<script>
    $(document).ready(function() {
        var placeholderLen = $('#txt').attr('placeholder').length;
        // keep some default lenght
        placeholderLen = Math.max(5, placeholderLen);
        $('#txt').attr('size', placeholderLen);

        $('#txt').keydown(function() {
            var size = $(this).val().length;
            $(this).attr('size', Math.max(placeholderLen, size));
        });
    });
</script>
pradeep
  • 550
  • 4
  • 10