Flexbox items do not shrink when screen gets smaller?

JSFiddle: https://jsfiddle.net/85v9df74/

I have a textbox (input type=text) that I cannot get to resize smaller with flexbox-grow, even though I want it to. In my example, it is the textbox labeled “Model #”, and it (along with the other textbox labeled “Description”) has a flexbox-grow property attached to it, while being contained inside of an outer flex container. This textbox is one of four fields that all display next to each other on a large screen, but on smaller screens they wrap into two columns. The problem is, when the screen size gets small enough, instead of shrinking the textbox sizes like I want them to, the textboxes stay a static width and then just get cut off the screen:
image
You can test this for yourself in the JSFiddle by resizing the width of the output display. The elements stay adjacent (correctly), then form into columns (correctly), but then when they get too small they just cut off the left textbox. They also currently don’t grow like they are supposed to when the screen is wide enough, though interestingly if the label tags are removed from Description and Model #, then they do grow correctly (but still don’t shrink right). I’ve tried adding the flex-shrink property to the textboxes as well and don’t seem to get any different results. Nor do I if I move the flexbox-grow properties to the labels. How do I make these textboxes dynamically shrink smaller when the screen size gets too small for them? Thanks very much!

It sounds like your flex-wrap is still set to it’s default value of nowrap on your flex container.

flex-wrap: nowrap; /* Default value */

Try letting it wrap


flex-flow: row wrap;

I see no link to your fiddle so you may want to try again on that

Oh I’m sorry, it looks like Sitepoint reverted to an earlier version of my question before posting (the site failed right as I clicked to post the topic, so I had to re-open the site and submit a draft it saved). The link should be there now, along with some clarifications in the question.

flex-flow: row wrap doesn’t seem to change anything when I add it.

You have three divs with the class of flex-parent
Let the main container div wrap too


<body>
    <div class="flex-parent" style="flex-wrap:wrap;">

Ah, okay. Unfortunately, when I add that property to the outer-most div, that makes it so that the fields start stacking on top of each other as the space gets too small, which is not what I want. What I’m looking for is for the fields to compress into two columns (like they do without the extra flex-wrap: wrap) and then if the space is even smaller, have the textboxes start shrinking in width, instead of partially disappearing off the edge of the screen like they do in the picture above.

An example of what I am thinking of for the textboxes’ widths getting smaller as the screen size gets smaller:

Thank you a bunch!

Hi, I’ve come up with something that seems to be close to what you are wanting.

Here’s the code, you can adjust it to your liking.
The size attributes on your inputs had to be removed from the html in order for flex to work.

<!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.wrap {
  display:flex;
}
.flex-parent {
  flex:1 1 50%;
  display:flex;
  flex-wrap:wrap;
  align-items:flex-start;
  margin:.25em;
}
.flex-parent label {
  flex:1 1 50%;
  display:flex;
  align-items:center;
  white-space:nowrap;
}
.flex-parent label:nth-child(2) {  /*label with input type="number"*/
  flex:0 0 10%;
}
input[type="text"] {
  flex:1 1 auto;
  width:5em;
  padding:.25em .5em;
}
input[type="number"] {
  width:3.5em;
  padding:.25em 0 .25em .25em;
}
select {
  max-width:6em;
  padding:.25em;
}
</style>
</head>
<body>
    <div class="wrap">
      <div class="flex-parent">
        <label>Description:<input type="text" name="description" required></label>
        <label>Qty:<input type="number" maxlength="3" name="quantity" required></label>
      </div>
      <div class="flex-parent">
        <label>Model #:<input type="text"  name="model" required> </label>
        <select name="technician" required>
          <option value="" selected disabled hidden>Type</option>
          <option>Roll</option>
          <option>Box</option>
          <option>Each</option>
        </select>
      </div>
    </div>
    <hr>
</body>
</html>
2 Likes

Sorry for the late response, I was spending time implementing your code and trying some other things out. Anyway…

That is great! That’s exactly the kind of thing I’m looking for! The only problem is, it looks fine on a laptop web browser, but when I pull it up on a mobile device with a smaller screen (which is why I was hoping to make it be dynamically re-sizable) it looks like this:


The horizontal rule doesn’t go all the way across and the textbox for “Model #” just baaaarely makes it before getting cut off (though its small grey border on the left side gets cut off, too).

I believe this is because the div is not actually stretching all the way across the screen, though I don’t know why that is. I’m especially convinced of that because when I color the flex-parent div it looks like this:

Any suggestions on what I should do to make sure the div stretches the entire screen so things don’t smash and get cut off a bit?

I really, really, appreciate all your help!

Have you edited your fiddle since it was originally posted? I ask because it work great for me at this time.
I would throw a bunch of rocks at your outdated code, but if you will delete the non-standard zoom property, I think you will be fine. You could improve your code tremendously my identifying the standards used by @Ray.H and implementing them in your code.

Hi,
I see all the issues you are describing in your screenshots. However, I am unable to test on mobiles. I suspect that something has changed with the code on your end. I set a background color on the flex-parent divs and I do not see it stopping short.

I suspect the <hr> not extending fully is showing where the main parent div begins overflowing at.

You’ll need to post the code your working with that produces the errors you see.

Keep in mind, the white-space:nowrap; I set on the labels keep the inputs from dropping to a new line. At some point you will simply run out of room to get everything on one line. Even if you did it could break when a users zooms text size.

You need to do one of the two:

  1. Set the main .wrap div to flex-wrap:wrap;
    Or
  2. Remove the white-space:nowrap; from the labels so the inputs can drop to a new line. The words: “Description” and “Model #” are taking up a lot of room along with the inputs.

A horizontal scrollbar is kicking in at 314px for me, I did add some borders though.
responsive-view

<!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.wrap {
  display:flex;
  /*flex-wrap:wrap;/* you should be using this */
}
.flex-parent {
  flex:1 1 50%;
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  padding:0 .25em;
  background:yellow;
  border:1px solid;
}
.flex-parent label {
  flex:1 1 50%;
  display:flex;
  align-items:center;
  white-space:nowrap; /*consider removing this*/
}
.flex-parent label,
.flex-parent select {margin:.25em 0;}

.flex-parent label:first-child {margin-right:.25em;}

.flex-parent label:nth-child(2) {  /*label with input type="number"*/
  flex:0 0 10%;
}
input[type="text"] {
  flex:1 1 auto;
  width:5em;
  padding:.25em .5em;
}
input[type="number"] {
  width:3.5em;
  padding:.25em 0 .25em .25em;
}
select {
  max-width:6em;
  padding:.25em 0;
}
</style>
</head>
<body>
    <div class="wrap">
      <div class="flex-parent">
        <label>Description:<input type="text" name="description" required></label>
        <label>Qty:<input type="number" maxlength="3" name="quantity" required></label>
      </div>
      <div class="flex-parent">
        <label>Model #:<input type="text"  name="model" required></label>
        <select name="technician" required>
          <option value="" selected disabled hidden>Type</option>
          <option>Roll</option>
          <option>Box</option>
          <option>Each</option>
        </select>
      </div>
    </div>
    <hr>
</body>
</html>
2 Likes

Alright, I was able to change some things I was doing and implement your code in a way that it works very well now and looks great! Your solution was super helpful, thanks so much for all the assistance! I really, really appreciate it, it helped a lot!

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.