3

I'm trying to get a content editable text box (div element) to grow as needed to fit the text typed into it, up to 80% of the width of the parent div.

Is there any way to do this with just CSS? If not, I'm open to Javascript solutions, but I am using React, which complicates things in that regard


This is NOT a duplicate of any other question I'm aware of, as it requires a solution which is:

  1. Independent of viewport size
  2. Supports a parent div with a max-width
  3. Works on contentEditable
  4. Works when the text content changes
Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
Slbox
  • 10,957
  • 15
  • 54
  • 106
  • 1
    Possible duplicate of http://stackoverflow.com/q/8100770/483779 – Stickers Apr 23 '17 at 15:45
  • None of the solutions there are relevant in React unfortunately, except possibly `` as `contentEditable` but I am using the input in a form. – Slbox Apr 23 '17 at 16:17
  • 2
    You want an `input` to grow vertical, multi line, with its content? ... If yes, you can't (well it appears Chrome allows it if one use `word-break: break-word;`), the `input` is a single line form element, `textarea` a multiline form element – Asons Apr 23 '17 at 17:41
  • Possible duplicate of [Font scaling based on width of container](https://stackoverflow.com/questions/16056591/font-scaling-based-on-width-of-container) – RJFalconer Oct 05 '18 at 10:08

4 Answers4

0

May be you could have a div inside parent div which is 80% of the parent div. And then set width : auto for the text box. Might sound a bit tricky.

Franklin Pious
  • 3,670
  • 3
  • 26
  • 30
  • Width auto on the textbox will just make it fill to be the full 80% all the time I think, no? – Slbox Apr 23 '17 at 16:20
0

I'm trying to get a text box to grow as needed to fit the text typed into it, up to 80% of the width of the parent div.

I'm fairly certain this won't be possible via CSS alone, because there is no way for CSS to determine the length of the text-content of the textarea.

With javascript, on every keypress, you can check the length of the text-content and if:

  • the text-content is above a certain number of keypresses; and
  • the width of the textarea is still narrower than the maximum allowed width

then the textarea can incrementally expand.

Working Example:

var myTextArea = document.getElementsByTagName('textarea')[0];
var myTextLength = myTextArea.value.length
var myTextWidth = parseInt(window.getComputedStyle(myTextArea).width);
var myTextMinLength = 20;
var myTextMaxWidth = ((parseInt(window.getComputedStyle(document.body).width) / 100) * 80);

function checkTextLength() {
    myTextLength = myTextArea.value.length;
    
    if ((myTextLength > myTextMinLength) && (myTextWidth < (myTextMaxWidth))) {
            myTextWidth += 8;
        }
    
    myTextArea.style.width = myTextWidth + 'px';
}

myTextArea.addEventListener('keypress', checkTextLength, false);
textarea {
width: 180px;
height: 40px;
}
<form>
<textarea placeholder="Start typing..."></textarea>
</form>
Rounin
  • 27,134
  • 9
  • 83
  • 108
0

fore React Your code should resemble something similar with modified values, but should implement the same logic. I don't think this is possible via CSS alone.

export const WelcomeScreen = () => {
  const divWidth = 400;
  const minTextWidth = 40 ; 
  const [textWidth, setTextWidth] = useState(minTextWidth);
  const handleTextChange = (event) => {
    const { value } = event.target;
    

    if ( (minTextWidth <= value.length*5) && (textWidth < (divWidth / 100) * 80)) {
      setTextWidth(value.length*5);
    }
  };

  return (
    <>
      <div style={{ width: `${divWidth}px` }}>
        <textarea
          style={{ width: `${textWidth}px`, fontSize: "10px" }}
          onChange={handleTextChange}
        />
      </div>
    </>
  );
};
abdulrhman
  • 56
  • 6
-1

hm... try this:

display: inline-block;

I am not sure tho. Let me know if it works.