Bootstrap 4 Cards - Preserve image positions within the card while maintaining image responsiveness

Viewed 27

I have a row of Bootstrap cards that I have added an additional image to (indicated by the red arrow). I wish to maintain the position of the additional image against the .card-img-top while keeping all images responsive. When the browser is resized the additional image ends up covering the .card-img.top image, which I don't want. Here are the image positions I wish to maintain:

bootstrap 4 cards

Can this be done either using Bootstrap's utility classes or additional CSS? Any guidance much appreciated.

The link to the Codepen is: here Snippet below:

/* Cards */

.card {
  border-radius: 1% !important;
  border: 1px solid rgba(0, 0, 0, .150);
}

.card-title {
  color: #000;
  font-weight: 700;
}

.card-date {
  font-size: 1.2rem;
  font-weight: 700;
  color: #000;
}

.prod-img {
  margin-top: -150px;
  margin-bottom: 10px;
}

.product-img .prod-img img {
  width: 250px;
  height: 250px;
  -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
  border-radius: 10%;
}

.card-text {
  font-size: 1.2rem;
}

.card-footer {
  padding: .75rem 1.25rem;
  background-color: rgba(0, 0, 0, .001);
  border-top: 1px solid rgba(0, 0, 0, .125);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" rel="stylesheet"/>
 <section class="card-list mb-3">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-4 d-flex align-items-stretch pb-3">
                <div class="card shadow bg-white">
                    <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>
                    <div class="card-body product-img">
                      <div class="product-profile-img">
                      <div class="prod-img"><img src="https://placebear.com/400/456" class="d-block mx-auto img-fluid img-thumbnail" alt=""></div>
                      </div>
                      <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
                      <h5 class="card-date">Lorem ipsum dolor sit.</h5>
                      <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
                      <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
                  </div>
                 <div class="card-footer">
                    <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a> 
                 </div>
                </div>
            </div>
            <div class="col-md-4 d-flex align-items-stretch pb-3">
                <div class="card shadow bg-white">
                    <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>
                    <div class="card-body product-img">
                      <div class="product-profile-img">
                      <div class="prod-img"><img src="https://placebear.com/400/456" class="d-block mx-auto img-fluid img-thumbnail" alt=""></div>
                      </div>
                      <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
                      <h5 class="card-date">Lorem ipsum dolor sit.</h5>
                      <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
                      <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
                  </div>
                 <div class="card-footer">
                    <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a> 
                 </div>
                </div>
            </div>
            <div class="col-md-4 d-flex align-items-stretch pb-3">
                <div class="card shadow bg-white">
                    <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>
                    <div class="card-body product-img">
                      <div class="product-profile-img">
                      <div class="prod-img"><img src="https://placebear.com/400/456" class="d-block mx-auto img-fluid img-thumbnail" alt=""></div>
                      </div>
                      <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
                      <h5 class="card-date">Lorem ipsum dolor sit.</h5>
                      <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
                      <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
                  </div>
                 <div class="card-footer">
                    <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a> 
                 </div>
                </div>
            </div>
        </div>
    </div>
   </section>

1 Answers

I think we have to do a couple things here. You'll probably need to tweak it and possibly apply media queries for sizing and position in edge cases.

First, get the inset images square. Consistency is critical. We can do that using the padding-bottom trick (with an aspect ratio of 100%) and object-fit. Notice that I've moved the img-thumbnail class out to the parent element to allow that.

Then, the sizing needs to be done with a combination of percentage and the fixed spacing that exists elsewhere in the cards. We can use the calc() function for that. I've applied it to an absolutely-positioned wrapper created in the previous step.

The major drawback to this layout is that it relies on the primary card images. While they're loading (or if they fail to load) everything collapses. This wouldn't normally be a problem, but here it is. You might look into forcing size on the card image container using the same padding-bottom technique.

Note that I've messed up your columns for demonstration.

.product-profile-img {
  margin-top: calc(-50% - 1.25rem);
  height: 0;
  padding-bottom: 100%;
  position: relative;
}

.prod-img {
  position: absolute;
  top: calc(10% + 1.25rem);
  right: calc(10% + 1.25rem);
  bottom: calc(10% + 1.25rem);
  left: calc(10% + 1.25rem);
}

.prod-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card {
  border-radius: 1% !important;
  border: 1px solid rgba(0, 0, 0, .150);
}

.card-title {
  color: #000;
  font-weight: 700;
}

.card-date {
  font-size: 1.2rem;
  font-weight: 700;
  color: #000;
}

.card-text {
  font-size: 1.2rem;
}

.card-footer {
  padding: .75rem 1.25rem;
  background-color: rgba(0, 0, 0, .001);
  border-top: 1px solid rgba(0, 0, 0, .125);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" rel="stylesheet" />

<section class="card-list my-3">
  <div class="container-fluid">
    <div class="row">
      <div class="col-6 col-md-4 d-flex align-items-stretch pb-3">
        <div class="card shadow bg-white">
          <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>

          <div class="card-body product-img">
            <div class="product-profile-img">
              <div class="prod-img img-thumbnail">
                <img src="https://placebear.com/400/456" alt="">
              </div>
            </div>

            <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
            <h5 class="card-date">Lorem ipsum dolor sit.</h5>

            <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
            <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
          </div>

          <div class="card-footer">
            <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a>
          </div>
        </div>
      </div>

      <div class="col-6 col-md-4 d-flex align-items-stretch pb-3">
        <div class="card shadow bg-white">
          <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>

          <div class="card-body product-img">
            <div class="product-profile-img">
              <div class="prod-img img-thumbnail">
                <img src="https://placebear.com/400/456" alt="">
              </div>
            </div>

            <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
            <h5 class="card-date">Lorem ipsum dolor sit.</h5>

            <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
            <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
          </div>

          <div class="card-footer">
            <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a>
          </div>
        </div>
      </div>

      <div class="col-6 col-md-4 d-flex align-items-stretch pb-3">
        <div class="card shadow bg-white">
          <div class="card-img-top"><img src="https://placebear.com/960/540" class="d-block mx-auto card-img img-fluid" alt=""></div>

          <div class="card-body product-img">
            <div class="product-profile-img">
              <div class="prod-img img-thumbnail">
                <img src="https://placebear.com/400/456" alt="">
              </div>
            </div>

            <h4 class="card-title">Lorem ipsum dolor sit amet.</h4>
            <h5 class="card-date">Lorem ipsum dolor sit.</h5>

            <p class="card-text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem quis sequi ab cum a in ea, voluptas, itaque distinctio doloremque eum. Provident mollitia eveniet minima?</p>
            <p class="card-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus dignissimos recusandae asperiores sequi nihil?</p>
          </div>

          <div class="card-footer">
            <a href="#" target="_blank" rel="noopener" class="btn btn-primary">Learn More</a>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

Related