Stewart
Stewart

Reputation: 1899

Why isn't align-self aligning my div to the bottom of my flexbox?

I have two equal-height columns and I am trying to get the "Read More" link in each column to sit at the bottom of the column, no matter how much content is in the adjacent column. I am using align-self: flex-end, which I think is supposed to selectively align this single child, but it isn't working. It is also important that the div heights are not stretched in any way. That is why I have specified align-items: flex-start; and align-content: flex-start;.

https://jsfiddle.net/stewx/b2aoksgf/2/

h3,
p {
  width: 100%;
  border: 1px solid blue;
}

div {
  padding: 5px;
}

.outer-container {
  display: flex;
  border: 1px solid black;
  padding: 5px;
}

.column {
  border: 1px solid red;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  width: 50%;
  align-content: flex-start;
}

.more {
  border: 1px dashed green;
  font-weight: bold;
  text-align: right;
  align-self: flex-end; /* Has no effect. I would have expected this to move to the bottom. */
}
<div class="outer-container">
  <div class="column">
    <h3>
  Foo
  </h3>
    <p>
      The top of this paragraph should be aligned with the top of the paragraph in the other column.</p>
    <p>

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet ullamcorper urna. Donec convallis lorem ut semper ultrices. Integer feugiat sodales leo. Sed non lacus sed nisi semper eleifend. Maecenas ultricies condimentum tempor. Fusce vel aliquet
      magna, nec sollicitudin nunc. Fusce ut facilisis lorem. Vestibulum porttitor vehicula mi, in bibendum ante ultrices sit amet. Nulla at dui tempor, ornare risus eu, lobortis lorem.
    </p>
    <p class="more"><a href="#">Read More (I should be at the bottom of this div!)</a></p>
  </div>
  <div class="column">
    <h3>
  Bar
  </h3>
    <p>
      The top of this paragraph should be aligned with the top of the paragraph in the other column.</p>
    <p>
      Vivamus porttitor pharetra eros quis maximus. Sed non blandit justo. Phasellus viverra tellus eu diam tempor pretium. Nam iaculis odio non quam iaculis, sit amet vehicula ipsum scelerisque. Nunc ornare augue quis congue finibus. Curabitur efficitur magna
      a fringilla convallis. Nulla nunc mauris, dignissim sit amet arcu sit amet, pellentesque condimentum sapien.
    </p>

    <p>
      Donec tellus purus, sodales non pellentesque a, accumsan ut orci. Vivamus a tincidunt odio, nec fringilla nulla. Nulla eu metus felis. Vivamus dictum accumsan ante pellentesque dapibus. Donec neque orci, congue pretium leo quis, tempor aliquam justo.
      Sed elementum cursus mauris vel consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam varius, ante in fermentum condimentum, lorem urna vulputate justo, nec maximus lectus leo sodales lectus. In nec orci mollis, varius ante
      id, faucibus ipsum. Etiam auctor a mi semper egestas. Morbi tincidunt at nunc non semper. Sed mattis tellus ex, in consequat leo facilisis id. Vivamus eleifend pellentesque tempus.
    </p>
    <p class="more"> <a href="#">Read More</a>
    </p>
  </div>
</div>

Upvotes: 2

Views: 1003

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 371889

The align-self property is closely related to align-items. One is designed to override the other. Hence, they both function together.

However, align-self and align-items work primarily in single-line flex containers.

When there are multiple rows of flex items in the cross-axis – like in the question – the property to use is align-content.

But when align-content is in effect, both align-items and align-self are limited. Remove align-content from .column and align-self works fine.

The most efficient way to achieve your layout (if wrapping rows aren't absolutely necessary) is to switch to flex-direction: column and use an auto margin on .more.

For more details on auto margins see here: https://stackoverflow.com/a/33856609/3597276


From the spec:

8.3. Cross-axis Alignment: the align-items and align-self properties

align-items sets the default alignment for all of the flex container’s items, including anonymous flex items. align-self allows this default alignment to be overridden for individual flex items.

8.4. Packing Flex Lines: the align-content property

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. Note, this property has no effect on a single-line flex container.

Upvotes: 1

Nenad Vracar
Nenad Vracar

Reputation: 122087

You can use flex-direction: column and margin-top: auto on .more

h3,
p {
  width: 100%;
  border: 1px solid blue;
}

div {
  padding: 5px;
}

.outer-container {
  display: flex;
  border: 1px solid black;
  padding: 5px;
}

.column {
  border: 1px solid red;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  width: 50%;
  align-items: flex-start;
}

.more {
  border: 1px dashed green;
  font-weight: bold;
  text-align: right;
  margin-top: auto;
  /* Has no effect. I would have expected this to move to the bottom. */
}
<div class="outer-container">
  <div class="column">
    <h3>
  Foo
  </h3>
    <p>
      The top of this paragraph should be aligned with the top of the paragraph in the other column.</p>
    <p>

      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet ullamcorper urna. Donec convallis lorem ut semper ultrices. Integer feugiat sodales leo. Sed non lacus sed nisi semper eleifend. Maecenas ultricies condimentum tempor. Fusce vel aliquet
      magna, nec sollicitudin nunc. Fusce ut facilisis lorem. Vestibulum porttitor vehicula mi, in bibendum ante ultrices sit amet. Nulla at dui tempor, ornare risus eu, lobortis lorem.
    </p>
    <p class="more"><a href="#">Read More (I should be at the bottom of this div!)</a></p>
  </div>
  <div class="column">
    <h3>
  Bar
  </h3>
    <p>
      The top of this paragraph should be aligned with the top of the paragraph in the other column.</p>
    <p>
      Vivamus porttitor pharetra eros quis maximus. Sed non blandit justo. Phasellus viverra tellus eu diam tempor pretium. Nam iaculis odio non quam iaculis, sit amet vehicula ipsum scelerisque. Nunc ornare augue quis congue finibus. Curabitur efficitur magna
      a fringilla convallis. Nulla nunc mauris, dignissim sit amet arcu sit amet, pellentesque condimentum sapien.
    </p>

    <p>
      Donec tellus purus, sodales non pellentesque a, accumsan ut orci. Vivamus a tincidunt odio, nec fringilla nulla. Nulla eu metus felis. Vivamus dictum accumsan ante pellentesque dapibus. Donec neque orci, congue pretium leo quis, tempor aliquam justo.
      Sed elementum cursus mauris vel consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam varius, ante in fermentum condimentum, lorem urna vulputate justo, nec maximus lectus leo sodales lectus. In nec orci mollis, varius ante
      id, faucibus ipsum. Etiam auctor a mi semper egestas. Morbi tincidunt at nunc non semper. Sed mattis tellus ex, in consequat leo facilisis id. Vivamus eleifend pellentesque tempus.
    </p>
    <p class="more"> <a href="#">Read More</a>
    </p>
  </div>
</div>

Upvotes: 2

Related Questions