Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling text input width and making it responsive

Tags:

html

css

input

I'm working on my unit conversion solo project from the Scrimba Front-End developer course, and I'm struggling hard to make my text input squarish yet responsive.

I managed to make it somewhat like the Figma design, but the issue is that if the number exceeds the width it gets hidden behind the input dimensions. So my goal is to create a squarish input field that extends depending on the text width.

Does anyone have an idea on how to do it? I tried working with AI and it didn't help this time, so I'd really appreciate an advice from an experienced fellow coder. Thanks!

Here is my code: https://github.com/Loud-Environment/unit-converter. I'm struggling on the /* Styling the header */ part witch the input rules.

Pasting the code excerpt below:

with input

without input

/* Styling the header */

body {
  background-color: var(--background--);
  color: var(--main-text--);
  font-family: "Inter", sans-serif;
}

enter image description here header {
  background-color: var(--accent-background--);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5em;
}

h1 {
  font-size: calc(1.5rem + 1vh);
  margin: 1em 1em 0;
}

input {
  background-color: var(--accent-background--);
  border: 2px solid var(--border-color--);
  border-radius: 5px;
  font-size: calc(3rem + 1vh);
  font-weight: bold;
  text-align: center;
  flex: 1 auto auto;
  width: 25vw;
  text-wrap: wrap;
  max-width: max-content;
  display: block;
}

button {
  background-color: #ffffff;
  color: #3d3d3d;
  font-size: calc(1rem + 1vh);
  margin-bottom: 2em;
  padding: 0.4em 1.5em;
  border: 1px solid #ffffff;
  border-radius: 5px;
}
<header>
  <h1>Metric/Imperial Unit Conversion</h1>
  <input type="text" />
  <button>Convert</button>
</header>
like image 259
Fedor Trishkin Avatar asked Sep 15 '26 07:09

Fedor Trishkin


1 Answers

You would need JavaScript. Here I use a hidden mirror to calculate the width precisely

I added CSS to grow smoothly

const input = document.getElementById('autoGrowInput');

const mirror = document.createElement('span');
mirror.style.position = 'absolute';
mirror.style.visibility = 'hidden';
mirror.style.whiteSpace = 'pre';
mirror.style.fontSize = getComputedStyle(input).fontSize;
mirror.style.fontFamily = getComputedStyle(input).fontFamily;
document.body.appendChild(mirror);

const updateWidth = () => {
  const text = input.value || input.placeholder || '';
  mirror.textContent = text;
  const newWidth = mirror.offsetWidth + 30; // padding
  input.style.width = newWidth + 'px';
};

input.addEventListener('input', updateWidth);
updateWidth();
/* Styling the header */

body {
  background-color: var(--background--);
  color: var(--main-text--);
  font-family: "Inter", sans-serif;
}

header {
  background-color: var(--accent-background--);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5em;
}

h1 {
  font-size: calc(1.5rem + 1vh);
  margin: 1em 1em 0;
}

input {
  background-color: var(--accent-background--);
  border: 2px solid var(--border-color--);
  border-radius: 5px;
  font-size: calc(3rem + 1vh);
  font-weight: bold;
  text-align: center;
  flex: 1 auto auto;
  width: 25vw;
  text-wrap: wrap;
  max-width: max-content;
  display: block;
  transition: width .2s ease;
  /* smooth growth */
}

button {
  background-color: #ffffff;
  color: #3d3d3d;
  font-size: calc(1rem + 1vh);
  margin-bottom: 2em;
  padding: 0.4em 1.5em;
  border: 1px solid #ffffff;
  border-radius: 5px;
}
<header>
  <h1>Metric/Imperial Unit Conversion</h1>
  <input type="text" id="autoGrowInput" />
  <button>Convert</button>
</header>

Here is one that just counts characters

const input = document.getElementById('autoGrowInput');

// how many characters before we start growing
const maxCharsNoGrow = 6;

// remember the starting width in pixels
const baseWidth = input.offsetWidth;
const fontSize = parseFloat(getComputedStyle(input).fontSize);

// tune this factor if it grows too quickly or too slowly
const charWidthFactor = 0.6; // fraction of font-size per extra character

const updateWidth = () => {
  const len = input.value.length;

  if (len <= maxCharsNoGrow) {
    input.style.width = baseWidth + 'px';
    return;
  }

  const extraChars = len - maxCharsNoGrow;
  const extraPx = extraChars * fontSize * charWidthFactor;
  input.style.width = baseWidth + extraPx + 'px';
};

input.addEventListener('input', updateWidth);
updateWidth();
/* Styling the header */

body {
  background-color: var(--background--);
  color: var(--main-text--);
  font-family: "Inter", sans-serif;
}

header {
  background-color: var(--accent-background--);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5em;
}

h1 {
  font-size: calc(1.5rem + 1vh);
  margin: 1em 1em 0;
}

input {
  background-color: var(--accent-background--);
  border: 2px solid var(--border-color--);
  border-radius: 5px;
  font-size: calc(3rem + 1vh);
  font-weight: bold;
  text-align: center;
  flex: 1 auto auto;
  width: 25vw;
  text-wrap: wrap;
  max-width: max-content;
  display: block;
  transition: width .2s ease; /* smooth growth */
}

button {
  background-color: #ffffff;
  color: #3d3d3d;
  font-size: calc(1rem + 1vh);
  margin-bottom: 2em;
  padding: 0.4em 1.5em;
  border: 1px solid #ffffff;
  border-radius: 5px;
}
<header>
  <h1>Metric/Imperial Unit Conversion</h1>
  <input type="text" id="autoGrowInput" />
  <button>Convert</button>
</header>
like image 143
mplungjan Avatar answered Sep 16 '26 19:09

mplungjan