skip to Main Content

I need to align two <textarea> elements side by side, so that each text area should take the whole height of the window and the half of its width.

The following works fine, but …

body {
  display: flex;
}

textarea {
  width: 50%;
}
<textarea></textarea>
<textarea readonly></textarea>

but I don’t understand why 50% is fine if I use display: flex, but is too much without it.

And this rises another question: is it really a "proper" way to achieve this task? Looks as a "quick-and-dirty" solution. Is there a more "proper" way to align them?

2

Answers


  1. The default flex value is 0 1 auto, which is equivalent to:

    flex-grow: 0;
    flex-shrink: 1;
    flex-basis: auto;
    

    So when you give your textareas a flex parent, but don’t apply any specific flex rules on them, they will automatically have flex-shrink: 1; applied. When you then give them width: 50%;, they will both try to expand to 50% of their parent’s width but also will understand that they should shrink as necessary in order to fit.

    Since there’s no reason for one textarea to be wider than the other, they end up being equal widths. But you could actually end up with the same behaviour if you gave them an even larger width like 100%;, as you can see in this example:

    body {
      display: flex;
    }
    
    textarea {
      width: 100%;
    }
    <textarea></textarea>
    <textarea readonly></textarea>

    My personal favourite way to have a number of items in a flex container all take up equal widths, regardless of their content, is to use this combination of rules:

    .flex {
      display: flex;
    }
    
    .flex-child {
      outline: 2px solid red;
      
      width: 0;
      flex: 1 1 auto;
    }
    <div class="flex">
      <div class="flex-child">One</div>
      <div class="flex-child">Two</div>
      <div class="flex-child">Three</div>
      <div class="flex-child">Four</div>
    </div>

    Setting an element’s width to 0 basically tells flexbox not to consider its content when considering how wide it should be relative to its siblings, which helps ensure equal column widths. Then, flex: 1 1 auto; tells each item to expand and collapse as necessary, and they will try to fill the same amount of space along the flex axis.

    You might find this article on CSS Tricks helpful when it comes to understanding how flexbox is working in cases like these: Equal Columns With Flexbox: It’s More Complicated Than You Might Think


    For alternative approaches that can achieve similar results, you might be interested in reading more about how the fr ("fraction") unit can be used in constructing layouts using CSS grid, which can be used to define columns with equal widths and a gap in between them. CSS Tricks has a useful cheat sheet for working with grid.

    Here’s an example using this approach:

    .grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-gap: 1rem;
    }
    
    .grid textarea {
      /* Disallow horizontal resizing */
      resize: vertical;
      /* This isn't ideal for how it affects vertical resizing,
      but it does ensure both textareas stay the same height */
      min-height: 100%;
    }
    <div class="grid">
      <textarea></textarea>
      <textarea readonly></textarea>
    </div>
    Login or Signup to reply.
  2. A more appropriate way is: try display: inline-block; while making sure there’s no margin or space between them. To confirm, try width: 45% on each to confirm they can get next to one another without anything unexpected happening.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search