Search code examples
cssreactjsflexbox

Centering the horizontal on the column right so that the text is in the middle of the screen


<div className={css.title} >
        <div className={css.row}>
            <div className={css.columnLeft}>
              <div className={css.header}>Images</div>
            </div>
            <div className={css.columnRight}>
              <strong>Image 1 of 2</strong>
            </div>
        </div>
        <Icon />
      </div>

css

.row {
  width: 100%;
  display: flex;
  align-items: center;
}

.columnLeft {
  flex: 1 0 25%;
  text-align: left;
}

.columnRight {
  flex: 1 0 75%;
}

enter image description here

Currently does

I would like it to be aligned horizontally more so in between left and center.


Solution

  • To keep "Image 1 of 2" (center column) in the middle of the screen:

    • give left and right 1 columns flex: 1 1 50%
    • give center column flex: 0 0 auto

    This will make the left and right columns start flex calculation from a base of 50% (which gives them equal weight, regardless of unequal content width). The center column will push back against both left and right columns and take an equal amount of empty space from each, to render its contents 2.

    If you want the center column to start wrapping at a particular width, give it a max-width and text-align: center.

    That's about it.

    <div className={css.title}>
      <div className={css.row}>
        <div className={css.columnLeft}>
          <div className={css.header}>Images</div>
        </div>
        <div className={css.columnCenter}>
          <strong>Image 1 of 2</strong>
        </div>
        <div className={css.columnRight}>
          <Icon />
        </div>
      </div>
    </div>
    

    CSS:

    .row {
      display: flex;
    }
    .columnLeft,
    .columnRight {
      flex: 1 1 50%;
    }
    .columnCenter {
      flex: 0 0 auto;
      display: flex;
      justify-content: center;
    }
    .columnRight {
      display: flex;
      flex-direction: row-reverse;
    }
    

    HTML demo:

    .row {
      display: flex;
      justify-content: center;
    }
    
    .columnLeft, .columnRight {
      flex: 0 1 50%;
      border: 1px solid red;
    }
    
    .columnCenter {
      flex: 0 0 auto;
      display: flex;
      justify-content: center;
    }
    .columnRight {
      display: flex;
      flex-direction: row-reverse;
    }
    .middle {
      width: 1px;
      height: 2rem;
      background-color: red;
    }
    <div class="row">
      <div class="columnLeft">
        <div class="header">More content on left side</div>
      </div>
      <div class="columnCenter">
        <strong>I am centered</strong>
      </div>
      <div class="columnRight">Icon</div>
    </div>
    <div class="row">
      <div class="middle" />
    </div>


    Notes:

    1 - I gave middle flex element columnCenter class and placed a .columnRight wrapper around the <Icon />, because in your example the center element had the class of columnRight, which was confusing (e.g: improper naming), IMHO.
    2 - Keep in mind flex is flexible (hence the name). If one of the columns has significantly more content than the other, the equal pushing of center column against the sides won't be so equal anymore. Sides only concede an equal amount of space as long as they have more room than needed to render their contents. If you want to keep the center text centered no matter what, place max-width on the side columns.