1

I have a page to fill some values. I'm trying to use CSS to break the lines of the texts correctly without the need of <br> elements.

It's suppost to work like this:

  • The content is suppost to completely fill (horizontally) the top <div> container but not overflow it.
  • <select> and <input> elements stretch to fill the available space and have a minimum width.
  • The width of the <span> elements should be the shortest possible while avoiding breaking lines unless needed.
  • <span> elements should break line only when in case they don't the other elements in the same line (<select> or <input>) can't have the minimum width and not overflow.
  • When a <span> element is broken into more than one line it should distribute the text evenly so that it has the shortest width (while still not recurring to breaking more lines unnecessarily). Example:

Correct:

One two
three

Incorrect:

One
two three

One
two
three

Code:

body {
  background-color: rgb(33, 38, 45);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
  font-size: 20px;
  font-weight: bold;
  margin: 0;
}

body > div {
  background-color: rgb(32, 32, 32);
  margin: 0 auto;
  white-space: nowrap;
  width: 400px;
}

div > div {
  align-items: center;
  display: flex;
  margin-top: 10px;
}

span {
  text-align: center;
}

span.green {
  color: rgb(0, 128, 0);
}

span.red {
  color: rgb(196, 0, 0);
}

span.blue {
  color: rgb(64, 64, 255);
}

span.yellow {
  color: rgb(255, 128, 0);
}

select {
  background-color: rgba(0, 0, 0, 0.2);
  border: 2px solid rgb(196, 196, 196);
  border-radius: 5px;
  color: rgb(228, 167, 105);
  font-size: 20px;
  margin-left: 10px;
  min-width: 200px;
  outline: none;
  padding: 10px;
  width: 100%;
}

option {
  color: rgb(0, 0, 0);
}

option:first-child {
  display: none;
}

input {
  background-color: rgba(0, 0, 0, 0.2);
  border: 2px solid rgb(196, 196, 196);
  border-radius: 5px;
  color: rgb(228, 167, 105);
  font-size: 20px;
  margin-left: 10px;
  min-width: 200px;
  outline: none;
  padding: 10px;
  width: 100%;
}
<body>
  <div>
    <div>
      <span class="green">Short text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Slightly longer text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="red">Text suppost to break into three lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="blue">Text broken into<br>two lines manually:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">This text is<br>corretly broken<br>into three lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="yellow">Text<br>incorrectly<br>broken:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Remarks:</span><input type="text">
    </div>
    <div>
      <span class="red">No no no no no<br>no:</span><input type="text">
    </div>
    <div>
      <span class="green">Yes yes yes<br>yes yes:</span><input type="text">
    </div>
  </div>
</body>

I'm using Chrome and it looks like this:

Visual result

This is how it's suppost to look:

Visual representation

I thought the first red one would fit in two lines but it doesn't (it overflows) so I edited it to three:

Visual overflow

user7393973
  • 2,270
  • 1
  • 20
  • 58

3 Answers3

0

As you label are so long so you cant manage to make them inline so best possible solution i am proposing below please have a look

Solution: removed white-space from main div and use some flex properties along with max-width attribute on input/select

body {
  background-color: rgb(33, 38, 45);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
  font-size: 20px;
  font-weight: bold;
  margin: 0;
}

body > div {
  background-color: rgb(32, 32, 32);
  margin: 0 auto;
  width: 400px;
}

div > div {
    align-items: center;
    display: flex;
    margin-top: 10px;
    justify-content: space-between;
}

span {
  text-align: center;
      min-width: 37%;
}

span.green {
  color: rgb(0, 128, 0);
}

span.red {
  color: rgb(196, 0, 0);
}

span.blue {
  color: rgb(64, 64, 255);
}

span.yellow {
  color: rgb(255, 128, 0);
}

select {
  background-color: rgba(0, 0, 0, 0.2);
  border: 2px solid rgb(196, 196, 196);
  border-radius: 5px;
  color: rgb(228, 167, 105);
  font-size: 20px;
  min-width: 200px;
  outline: none;
  padding: 10px;
  width: 100%;
}

option {
  color: rgb(0, 0, 0);
}

option:first-child {
  display: none;
}

input {
  background-color: rgba(0, 0, 0, 0.2);
  border: 2px solid rgb(196, 196, 196);
  border-radius: 5px;
  color: rgb(228, 167, 105);
  font-size: 20px;
  min-width: 177px;
  outline: none;
  padding: 10px;
  width: 100%;
}
<body>
  <div>
    <div>
      <span class="green">Short text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Slightly longer text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="red">Text suppost to break into two lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="blue">Text broken into two lines manually:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">This text is corretly broken into three lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="yellow">Text incorrectly broken:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Remarks:</span><input type="text">
    </div>
    <div>
      <span class="red">No no no no no no:</span><input type="text">
    </div>
    <div>
      <span class="green">Yes yes yes yes yes:</span><input type="text">
    </div>
  </div>
</body>
Awais
  • 4,752
  • 4
  • 17
  • 40
  • Oh. I do know how to do that. It's good as a different approach but I'm still eager to know if what I asked in the question is possible. – user7393973 Feb 04 '20 at 10:33
  • @user7393973 if i was not wrong you need to get exactly same structure as you mention above like text and input/select in same line with text to break if it exceeds? I just ask that bec its not clear from your question what actually you want – Awais Feb 04 '20 at 10:37
  • I do want them in the same line. In the question's example the green text is correct, the blue is too but it uses a `
    ` element, the yellow one should fit in two lines as the `
    – user7393973 Feb 04 '20 at 10:41
  • @user7393973 update my ans with solution 2 hope that i get that what you need – Awais Feb 04 '20 at 10:50
  • Sorry I think I wasn't clear. "`` elements stretch to fill the available space". I have edited the question with a visual representation of how it's suppost to break and look like so that it's easier to understand. – user7393973 Feb 04 '20 at 10:58
  • Well above solution is generic how ever you set different `width` to text `span` to achieve the desire layout more precisely – Awais Feb 04 '20 at 11:14
  • Unfortunately that attempt does not solve the way I intend and explained in the question. – user7393973 Feb 04 '20 at 11:30
  • Well then you need to use JS for that – Awais Feb 04 '20 at 12:26
0

I have absolutely no idea what the criteria are for making the text break into two lines instead of three. I couldn't figure it out from the post, but i'll give this a shot.

Maybe this could be something you want:

body {
  background-color: rgb(33, 38, 45);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
  font-size: 20px;
  font-weight: bold;
  margin: 0;
}

body > div {
  background-color: rgb(32, 32, 32);
  margin: 0 auto;
 /* white-space: nowrap; remove, fix it with flex since you're already using it */
  width: 400px;
}

div > div {
  align-items: center;
  display: flex;
  margin-top: 10px;
  
}

span {
  text-align: center;
}

span.green {
  color: rgb(0, 128, 0);
}

span.red {
  color: rgb(196, 0, 0);
}

span.blue {
  color: rgb(64, 64, 255);
}

span.yellow {
  color: rgb(255, 128, 0);
}

select {
  background-color: rgba(0, 0, 0, 0.2);
  border: 2px solid rgb(196, 196, 196);
  border-radius: 5px;
  color: rgb(228, 167, 105);
  font-size: 20px;
  margin-left: 10px;
  min-width: 200px;
  outline: none;
  padding: 10px;
  width: 100%;
  flex:1; /* add this */
}

option {
  color: rgb(0, 0, 0);
}

option:first-child {
  display: none;
}

input {
     background-color: rgba(0, 0, 0, 0.2);
    border: 2px solid rgb(196, 196, 196);
    border-radius: 5px;
    color: rgb(228, 167, 105);
    font-size: 20px;
    margin-left: 10px;
    /* min-width: 200px; remove it, unecessary since body has fixed width */
    outline: none;
    padding: 10px;
    /* width: 100%; remove, unecessary with using flex*/
    flex: 1; /* add this */
}
<body>
  <div>
    <div>
      <span class="green">Short text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Slightly longer text:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="red">Text supposed to break into two lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="blue">Text broken into two lines manually:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">This text is corretly broken into three lines:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="yellow">Text incorrectly broken:</span><select><option>Select an option</option><option>Yes</option><option>No</option></select>
    </div>
    <div>
      <span class="green">Remarks:</span><input type="text">
    </div>
    <div>
      <span class="red">No no no no no no:</span><input type="text">
    </div>
    <div>
      <span class="green">Yes yes yes yes yes:</span><input type="text">
    </div>
  </div>
</body>

You might also want to consider these points: 1) aligning the text to the left, it will look clearer. 2) playing with the width of ' body > div ' 3) maybe not use px for the width (not responsive! use em, vw or worst case % ).

p.s. I found 410px to make the text look better as well, but consider making the width a bit more responsive with values according to the width of the screen. Use media queries for different screen sizes.

p.s.2 Just a minor typo : it's supposed not suppost. In case you wanted it :)

Helpful guide to flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Marina M
  • 101
  • 3
0

While trying to find a solution I searched for "css wrap text evenly" in the hopes to first of all figure out how to get text that looks like this:

This text is wrongly distributed in the first example but correctly distributed in the
second example.

To be evenly distributed like this:

This text is wrongly distributed in the first example
but correctly distributed in the second example.

And I found the old question Balanced text wrapping in HTML which indicates that it is currently not possible to do so using CSS though there's a proposal for text-wrap: balance (which has to go through a long process to possibly be accepted, added and supported).

It is possible to use JavaScript to automatically add line breaks accordingly in the correct places.

Using white-space: normal; in the top container (body > div) wraps the text but not with the desired amount of lines as the property's logic to break a line is different than of the intended behavior explained in the question.

user7393973
  • 2,270
  • 1
  • 20
  • 58