0

I have some flexboxes where I'd like to include some footer information in each. I'm trying to get the footer to align to the bottom of the flexbox no matter how short or long the content actually is. I've tried playing with auto margins and the flexbox settings, but can't seem to find a way to do it.

This is my original setup:

.card-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
}

.card {
  flex: 0 1 100%;
  margin: 0 10px 10px 0;
  border: 1px solid grey;
  border-top: 10px solid black;
  box-shadow: 1px 1px 3px #888;
}

.card-content {
  padding: 10px;
}

@media all and (min-width: 30em) {
  .card {
    flex: 0 1 30%;
  }
<div class="card-wrapper">
  <a href="#" class="card">
    <div class="card-content">
      <h2>Title</h2>
      <p>Content</p>
      <p>This should be the footer.</p>
    </div>
  </a>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
DD1229
  • 396
  • 5
  • 16
  • What do you mean by "the bottom" specifically? In your demo it looks like it is already at the bottom. – TylerH Jul 03 '18 at 18:13
  • Don't you need any white space after the footer? – Prabin Sapal Jul 03 '18 at 18:13
  • So across all boxes the footer is pinned to the bottom. Something like [in this post](https://stackoverflow.com/questions/31000885/align-an-element-to-bottom-with-flexbox), but I've tried the suggestions there without any luck. – DD1229 Jul 03 '18 at 18:20

5 Answers5

1

Keep in mind that flex properties work only between parent and child elements. Your flex container (.card-wrapper) is a far away ancestor (great grandparent) of the content elements, so the footer is out of scope.

Make the parent (.card-content) a flex container, so you can apply flex properties (including auto margins) to the children.

.card-wrapper {
  display: flex;
}

.card {
  flex: 0 1 100%;
  margin: 0 10px 10px 0;
  border: 1px solid grey;
  border-top: 10px solid black;
  box-shadow: 1px 1px 3px #888;
}

.card-content {
  padding: 10px;
  display: flex;           /* new */
  flex-direction: column;  /* new */
  height: 150px;           /* demo only */
}

.card-content > :last-child {
  margin-top: auto;        /* new */
}

.card-content > * {
  margin: 0;               /* demo only */
}
<div class="card-wrapper">
  <a href="#" class="card">
    <div class="card-content">
      <h2>Title</h2>
      <p>Content</p>
      <p>This should be the footer.</p>
    </div>
  </a>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Actually I'm confused what your requirement is but if you don't need any white space after the footer then check out the following code and output.

.card-wrapper {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
}

.card {
    flex: 0 1 100%;
    margin: 0 10px 10px 0;
    border: 1px solid grey;
    border-top: 10px solid black;
    box-shadow: 1px 1px 3px #888;
}

.card-content {
    padding: 10px 10px 0;
}
.no-margin {
    margin: 0;
}

@media all and (min-width: 30em) {
    .card {
        flex: 0 1 30%
    }
}
<div class="card-wrapper">
    <a href="#" class="card">
        <div class="card-content">
            <h2>Title</h2>
            <p>Content</p>
            <p class="no-margin">This should be the footer.</p>
        </div>
    </a>
</div>
Prabin Sapal
  • 346
  • 1
  • 9
  • So when I have a series of boxes next to each other, I want the footer to always be at the bottom no matter what the box length. For example, if I have two boxes and box #1 has one line of text and box #2 (next to it) has multiple lines of text, I want box #1 footer to pin to the bottom of its box given the length of all the boxes. [This post](https://stackoverflow.com/questions/31000885/align-an-element-to-bottom-with-flexbox) does a better job of explaining it, but I've tried the suggestions there without any luck. – DD1229 Jul 03 '18 at 18:24
0

I just changed footer "p" tag to "span" tag. It removed unnecessary margins.
Try below code

  .card-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
}

.card {
  flex: 0 1 100%;
  margin: 0 10px 10px 0;
  border: 1px solid grey;
  border-top: 10px solid black;
  box-shadow: 1px 1px 3px #888;
}

.card-footer{
text-align:center;
}

.card-content {
  padding: 10px;
}

@media all and (min-width: 30em) {
  .card {
    flex: 0 1 30%
  }
  ;
<div class="card-wrapper">
  <a href="#" class="card">
    <div class="card-content">
      <h2>Title</h2>
      <p>Content</p>
    </div>
    <div class="card-footer">
      <span>This is footer.</span>
    </div>
  </a>
</div>
Rumesh
  • 402
  • 4
  • 15
0

You can use auto margins

Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.

.card-wrapper {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
}

.card {
    flex: 0 1 100%;
    margin: 0 10px 10px 0;
    border: 1px solid grey;
    border-top: 10px solid black;
    box-shadow: 1px 1px 3px #888;
}
p { 
  flex-grow: 1; 
}

.card-content {
    padding: 10px;
}
.footer{ margin-top: auto; } 


@media all and (min-width: 30em) {
    .card {
        flex: 0 1 30%
    }
    ;
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div class="card-wrapper">
    <a href="#" class="card">
        <div class="card-content">
            <h2>Title</h2>
            <p>Content</p>
            <p class="footer">This should be the footer.</p>
        </div>
    </a>
</div>
</body>
</html>
Nicholas Porter
  • 2,588
  • 2
  • 23
  • 37
0

Do you actually mean multiple cards like this?

.cards {
  display: flex;
  flex-direction: row;
}

.card-wrapper {
  flex: 1 0 auto; /* ADDED */
  display: flex;
  /* flex-wrap: wrap; REMOVED */
  /* justify-content: flex-start; REMOVED*/
}

.card {
  display: flex; /* ADDED */
  flex: 1 0 auto; /* changed from 0 1 100% */
  flex-direction: column; /* ADDED */
  margin: 0 10px 10px 0;
  border: 1px solid grey;
  border-top: 10px solid black;
  box-shadow: 1px 1px 3px #888;
}

.card-content,
.card-footer { /* ADDED .card-footer */
  padding: 10px;
}

.card-content { /* ADDED */
  flex: 1 0 auto;
}

.card-footer { /* ADDED */
  flex: 0 0 auto;
}

@media all and (min-width: 30em) {
  .card {
    /* flex: 0 1 30% REMOVED */
  }
}
<div class="cards">
  <div class="card-wrapper">
    <a href="#" class="card">
      <div class="card-content">
        <h2>Title</h2>
        <p>Short Content</p>
      </div>
      <div class="card-footer">
        <p>This should be the footer.</p>
      </div>
    </a>
  </div>

  <div class="card-wrapper">
    <a href="#" class="card">
      <div class="card-content">
        <h2>Title</h2>
        <p>Even<br/>Longer<br/>Content<br/>Here</p>
      </div>
      <div class="card-footer">
        <p>This should be the footer.</p>
      </div>
    </a>
  </div>
  
  <div class="card-wrapper">
    <a href="#" class="card">
      <div class="card-content">
        <h2>Title</h2>
        <p>Very<br/>Long<br/>Content<br/></p>
      </div>
      <div class="card-footer">
        <p>This should be the footer.</p>
      </div>
    </a>
  </div>
</div>
SirPilan
  • 4,649
  • 2
  • 13
  • 26