2

This is the kind of placement I would like to achieve with display:flex. I want the text1 to appear at the top, text3 at the bottom and text2 in the middle.

enter image description here

However the end result I got is this:

enter image description here

I am expecting align-self to be able to pull the top and the bottom div toward each end.

What did I miss?

Here is my html mark-up and css stylesheet

HTML:

<div class=container>

  <div class='logo-container hidden-xs'>
    <span>LOGO on the side</span>
  </div>
  <div class='text-container' > 
    <div class='visible-xs'>
      <span>LOGO</span>
    </div>
    <div class=text1>
      Text1
    </div>
    <div class=text2>
      Text 2
    </div>
    <div class=text3>
      Text 3
    </div>
  </div>  

</div>

css:

.container {
  display: flex;
  /* flex-direction: row;  no effect */
  border: 1px;
  border-style: solid;
  height: 300px;
}

.container span {
  padding: 5px;
  border: 1px;
  border-style: solid;
  border-color: blue;
}

.text-container {
  flex-direction: column;
  border: 1px;
  border-style: solid;
  border-color: red;
}

.do-i-need-this {
  display: flex;
  flex-direction: row;
} 

.text1 {
  align-self: flex-start;  
  border: 1px;
  border-style: solid;
  border-color: green;

}

.text2 {

  border: 1px;
  border-style: solid;
  border-color: green;

}


.text3 {
  align-self: flex-end;
  border: 1px;
  border-style: solid;
  border-color: green;
}
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Anthony Kong
  • 37,791
  • 46
  • 172
  • 304

2 Answers2

4

Add these to your text-container class

display: flex;
justify-content: space-between;

You can get rid of align-self

Ed Dogan
  • 255
  • 2
  • 8
4

The answer by @EdDogan is correct. My answer expands on his solution with an explanation.

The primary obstacle you're facing to achieving your layout is the lack of a flex container for the text elements. In other words, .text-container must have display: flex applied in order for flex properties to work on child elements.

Then, to align the flex items on opposite edges, with one in the middle, use justify-content: space-between, which is perfect for this requirement (and works along the vertical axis because flex-direction is column).

.text-container {
    display: flex; /* new */
    justify-content: space-between; /* new */
    flex-direction: column;
}

Revised Codepen

Few more notes:

  • If the middle item simply needs to exist between the other two, then justify-content: space-between (or space-around) works fine.

    If, however, the middle item needs to be centered in the container, then the justify-content method works only when all items are the same height. If any of the items have a different height (or width, in flex-direction: row), this will cause an imbalance, and centering will be off.

    For more details, a demo and a workaround, see Box #76 here: https://stackoverflow.com/a/33856609/3597276

  • With regard to:

    .container {   /* flex-direction: row;  no effect */ }
    

    When you establish a flex container (by applying display: flex or display: inline-flex to an element), several default rules go into effect. One of these rules is flex-direction: row. Hence, your own declaration of this rule is redundant and will have no effect.

  • With regard to:

    .text1 { align-self: flex-start; }
    
    .text3 { align-self: flex-end; }
    

    The first reason this doesn't work is because the parent of these elements is not a flex container. .text-container doesn't have display: flex applied, so any flex properties on the child elements are ignored.

    The second reason it doesn't work is because, even with display: flex applied, you are in flex-direction: column. This means that the cross-axis is horizontal, and the align- properties control flex items left/right, not up/down.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701