DD1229
DD1229

Reputation: 408

Align footer to bottom of flexbox

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>

Upvotes: 0

Views: 3491

Answers (5)

SirPilan
SirPilan

Reputation: 4847

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>

Upvotes: 0

Michael Benjamin
Michael Benjamin

Reputation: 371271

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>

Upvotes: 1

Nicholas Porter
Nicholas Porter

Reputation: 2951

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>

Upvotes: 0

Rumesh
Rumesh

Reputation: 402

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>

Upvotes: 0

Prabin Sapal
Prabin Sapal

Reputation: 346

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>

Upvotes: 0

Related Questions