Issue with consistency in the height of product card titles across rows

Looking for suggestions on achieving consistent card title height per row to ensure image alignment at the bottom. The solution should be responsive. Any CSS tips or jQuery plugins are welcome! I've searched online but haven't found a similar solution yet.

Keep in mind that setting an absolute height for the title won't work because titles may break into multiple lines when the browser is resized, requiring calculations again. Thanks!

Desired end result: https://drive.google.com/file/d/1IeQ6X7R9utZzKTn8UdNFruInezJpX1V_/view?usp=sharing

Check it out on Codepen

https://codepen.io/edvardsniedre/pen/ymBdwg

Answer №1

@user2713970 Check out this code snippet that I believe will be helpful for you.

           <style>
            * { box-sizing: border-box; }

            .card_image { width:100%; height:150px; }
            body { 
              max-width: 960px; margin: 0 auto; padding: 40px 10px;
            }

            .cards 
            {  display: flex; justify-content: space-between; flex-wrap: wrap; }

            .card {
                width: 24%; border: 1px solid black;
                margin-top: 10px; text-align: center;    
            }

            img { width: 100%; }

            .title { padding: 10px 0; }



            @media only screen and (max-width: 700px) {
              .cards {
                .card {
                  width: 49%;
                }
              }
            }



            <body>
                <div class="cards">
                  <div class="card">
                    <img class="card_image" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRfwXs8u99aFJFdhPx7oIgK1dLCkqQ14U7Yn4n1nvEwi_rgiWeYfg" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQKa0uIGrJO2QhidOcpE15BSVHK5uK3NNpH0ooXliy89IjeyK-bg" alt="">
                    <div class="title">Title Title Title </div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://envato-shoebox-0.imgix.net/4646/3935-85f4-41a0-b940-708875ee0a15/tajak+019.jpg?w=500&h=278&fit=crop&crop=edges&auto=compress%2Cformat&s=c45335aca948555287bc4229b1632950" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="http://3v6x691yvn532gp2411ezrib-wpengine.netdna-ssl.com/wp-content/uploads/2019/05/imagetext01.jpg" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://images.unsplash.com/photo-1535498730771-e735b998cd64?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://i.kinja-img.com/gawker-media/image/upload/s--PnSCSSFQ--/c_scale,f_auto,fl_progressive,pg_1,q_80,w_800/z7jcryloxjedsztssw39.jpg" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://cdn.pixabay.com/photo/2018/05/28/22/11/message-in-a-bottle-3437294__340.jpg" alt="">
                    <div class="title">Title Title Title Title Title Title Title Title</div>
                    <div>$20</div>
                  </div>
                  <div class="card">
                    <img class="card_image" src="https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2018/03/italy_and_mediterranean/17402074-1-eng-GB/Italy_and_Mediterranean_node_full_image_2.jpg" alt="">
                    <div class="title">Title</div>
                    <div>$20</div>
                  </div>
                </div>
            </body>

Answer №2

If you want to customize the height of the title within the .title class, you can do so by adding a specific height value. Keep in mind that this customization may not automatically adjust for titles of different sizes. The example code below provides a fixed height suitable for the current content:

  .title {
    padding: 10px 0;
    height: 120px;
  }

Answer №3

@user2713970, it seems like your current CSS is only setting padding to the title, causing it to wrap text and leading to uneven height.

Your Current CSS:

.title {
    padding: 10px 0;
}

To ensure consistent height for all rows and automatically align the image to the top of the title without using jQuery, consider updating your CSS as follows:

Updated CSS:

.title {
     padding: 10px 0;
     height: 150px;
 }

You can refer to this Codepen link for a better understanding. Additionally, in the second line of cards in the demo, there is a vertically aligned title to help with the alignment visualization.

Answer №4

To maintain image alignment while accommodating variable-length title content, you can utilize the Webkit's -webkit-line-clamp property with specific styles to truncate overflowing text that does not fit within the defined clamped lines. Keep in mind that this solution may not be fully supported across all browsers due to the evolving nature of the CSS specification.

If truncating the title text is acceptable for your layout, consider exploring alternative options like Clamp.js for a more cross-browser compatible approach.

For additional strategies on truncating overflow text, refer to this informative article on CSS Tricks.

Furthermore, setting height constraints on images and utilizing object-fit:cover can help maintain alignment while maximizing available space. This technique enhances visual consistency within the layout while ensuring a polished presentation.

Answer №5

I struggled to find a solution for this problem without using JavaScript, although I believe there is potential for optimization and tidying up.

¯\_(ツ)_/¯

Wishing you the best of luck!

<html>

<head>
  <style>
    body {
      max-width: 960px;
      margin: 0 auto;
      padding: 40px 10px;
      background-color: #f1f1f1;
    }

    * {
      box-sizing: border-box;
    }

    .cards {
      display: flex;
      flex-wrap: wrap;
    }

    .card {
      flex: 0 0 100%;
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
      padding-left: 10px;
      padding-right: 10px;
      margin-bottom: 20px;
    }

    .img-wrapper {
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
    }

    .details {
      background-color: white;
      padding: 20px;
    }

    img {
      position: relative;
      display: block;
      width: 100%;
      height: auto;
      margin-top: auto;
    }

    .price {
      margin-top: 10px;
    }

    @media screen and (min-width: 560px) {
      .card {
        flex: 0 0 50%;
      }
    }

    @media screen and (min-width: 960px) {
      .card {
        flex: 0 0 25%;
      }
    }
  </style>
</head>

<body>
  <div class="cards">
    <div class="card">
      <div class="img-wrapper">
        <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRfwXs8u99aFJFdhPx7oIgK1dLCkqQ14U7Yn4n1nvEwi_rgiWeYfg" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQKa0uIGrJO2QhidOcpE15BSVHK5uK3NNpH0ooXliy89IjeyK-bg" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title </div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://envato-shoebox-0.imgix.net/4646/3935-85f4-41a0-b940-708875ee0a15/tajak+019.jpg?w=500&h=278&fit=crop&crop=edges&auto=compress%2Cformat&s=c45335aca948555287bc4229b1632950" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="http://3v6x691yvn532gp2411ezrib-wpengine.netdna-ssl.com/wp-content/uploads/2019/05/imagetext01.jpg" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://images.unsplash.com/photo-1535498730771-e735b998cd64?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://i.kinja-img.com/gawker-media/image/upload/s--PnSCSSFQ--/c_scale,f_auto,fl_progressive,pg_1,q_80,w_800/z7jcryloxjedsztssw39.jpg" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://cdn.pixabay.com/photo/2018/05/28/22/11/message-in-a-bottle-3437294__340.jpg" alt="">
      </div>
      <div class="details">
        <div class="title">Title Title Title Title Title Title Title Title</div>
        <div class="price">$20</div>
      </div>
    </div>
    <div class="card">
      <div class="img-wrapper">
        <img src="https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2018/03/italy_and_mediterranean/17402074-1-eng-GB/Italy_and_Mediterranean_node_full_image_2.jpg" alt="">
      </div>
      <div class="details">
        <div class="title">Title</div>
        <div class="price">$20</div>
      </div>
    </div>
  </div>
  <script>
    document.addEventListener('DOMContentLoaded', function () {


      function setImageHeight() {
        var imageWrapper = document.querySelectorAll('.img-wrapper');
        var elems = [].slice.call(imageWrapper);
        var tallest = Math.max.apply(Math, elems.map(function (elem, index) {
          elem.style.minHeight = '';
          return elem.offsetHeight;
        }));

        elems.forEach(function (elem, index, arr) {
          elem.style.minHeight = tallest + 'px';
        });
      }

      function setTitleHeight() {
        var title = document.querySelectorAll('.title');
        var elems = [].slice.call(title);
        var tallest = Math.max.apply(Math, elems.map(function (elem, index) {
          elem.style.minHeight = '';
          return elem.offsetHeight;
        }));

        elems.forEach(function (elem, index, arr) {
          elem.style.minHeight = tallest + 'px';
        });
      }
      setTimeout(function () {
        setImageHeight();
        setTitleHeight();
      }, 250);
      var resized = true;
      var timeout = null;
      var refresh = function () {
        if (resized) {
          requestAnimationFrame(setImageHeight);
          requestAnimationFrame(setTitleHeight);
        }
        clearTimeout(timeout);
        timeout = setTimeout(refresh, 100);
        resized = false;
      };
      window.addEventListener('resize', function () {
        resized = true;
      });
      refresh();
    });

  </script>
</body>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery Slideshow Plugin to Create Personalized Slide Durations

I have implemented a plugin from the following source: The time interval between slides is configured as follows: interval = setInterval(function() { auto_number = slider_control.children(controlTabString+".active").prevAll(controlTabString).length ...

What could be causing the issue with position: fixed not functioning properly?

Why isn't the position: fixed; property functioning in this CSS code? body { text-align : center ; min-width : 770px ; } div.wrapper { width : 770px ; text-align : left ; margin-left : auto ; margin-right : auto ; } div.heade ...

Tips for adjusting the size of an image in both the vertical and horizontal axes using CSS

As a beginner in HTML, I am currently facing an issue while trying to display a set of pictures. My goal is to resize the pictures based on the current window size while maintaining the aspect ratio. Despite experimenting with various methods like using wi ...

Troubleshooting: Why is PHP/HTML Code Displaying as Text in Email?

I have made numerous attempts to modify the header without success. Could it possibly be an issue with the email server? Or is there a crucial aspect that I'm overlooking? I would appreciate if more than just the code appears as plain text in the fi ...

Discovering Ajax-powered websites Here are some tips on identifying websites

My goal is to determine if a webpage makes AJAX calls. If the webpage is AJAX-based, I will wait for a few seconds to retrieve the content. If it's not AJAX-based, then I won't wait. I attempted the code below, but it didn't yield any resul ...

How can I add opening quotation marks to every line of text using HTML and CSS?

Is it possible to display a quotation mark at the beginning of each line in a quote using HTML and CSS? In traditional typography, quotes were often marked at every linebreak in addition to the opening and closing of the quote. I want to replicate this on ...

The angular content is not scrolling

I have a basic angular content window that contains an adjustable group of settings values. When the window is collapsed, the fxLayout collapses properly, but I am having difficulty scrolling vertically. I have attempted to use overflow-y and just overflow ...

Insert a line break above and below every <h1> tag

Hey there, I'm just starting out with CSS and I might have some beginner questions. I want to add a line break at the top of my post before and after my h1 tags. I may be going about this the wrong way. It's possible that I need some padding at t ...

"The HTML5 feature that triggers an event when a selection is changed is known as

Is there a universal HTML5 event that functions similarly to the IE legacy onselectionchange, triggering when the current selection is altered? UPDATED, I am interested in monitoring changes to the Selection object. ...

Is it possible to customize the default styling options in Tailwind?

I am currently working on a blog using NextJS, and I have encountered an issue with Tailwind's list style type. It seems that the default styling for list style type is set to list-none, resulting in my <ul> <li> elements not being styled ...

Automatically updating the JavaScript content on a webpage without having to refresh the entire HTML page, based on the changing

Is there a way to adjust the opacity change rate of my nav bar automatically without the need to refresh the page? The current opacity change rate is based on the width of the window, but once the page is loaded, adjusting the width does not affect the rat ...

Issue occurs when Form does not pass field input to email when utilizing jQuery AJAX PHP

I am currently working on a contact form that utilizes jQuery/AJAX and PHP to send field input values via email. The issue I am facing is that the email being sent only contains the $to and $subject of the PHP mail() function, without any of the actual fie ...

How can I create a custom elevation for a Vuetify v-menu?

I'm currently working with vuetify and v-menu as outlined in the official documentation here https://vuetifyjs.com/en/components/menus/ I'm struggling to figure out how to apply elevation only on the bottom left and right corners. When I add a ...

Is there a way to display the # symbol instead of characters in the input text field?

I have a text input field in a PHP page with a maxlength attribute set to 11. This input field is specifically used for entering phone numbers. The requirement is that when the user types a phone number, it should display as "#" symbols for all 11 characte ...

Convert entity to JSON object using JavaScriptSerializer

These are the entities in my system: class Location { public string Country { get; set; } public string City { get; set; } public string Street { get; set; } } class Individual { public string Name { get; set; } public int Age { ...

"Utilizing jQuery to achieve vertical center alignment within a div

Attempting to vertically center a div within another div that has 100% dimensions is proving to be a bit challenging. The code I have written seems to work but occasionally triggers an odd bug. This is the snippet of code in question: var window_height = ...

How can I modify certain attributes within an array of objects?

https://i.sstatic.net/TKkcV.jpgI need help with updating properties within an object array. Below is my code for reference. I have an object array consisting of two arrays, where the first one contains attribute "first" and the second one contains "last". ...

Displaying or hiding table columns in Vue.js Element-UI el-table based on screen width: a step-by-step guide

Here is my code snippet for generating a table: <el-table :data="tableData" empty-text="No data to display :( " v-if="window.width > 855"> <el-table-column v-for="column in tableColumnsMd" :key=&q ...

How can you create a basic slideshow without relying on jQuery to cycle through images?

Imagine you have a div containing 3 images. Is there a way to build a basic slideshow that smoothly transitions between the images, showing each one for 5 seconds before moving on to the next one and eventually looping back to the first image without rely ...

Notifying users with a jQuery or Javascript alert when they click the back

I am trying to create an alert or redirection for users when they press the back button, but so far, all the solutions I have attempted only trigger the alert after a form is submitted. Here is the current ineffective code I am using: $(function() { i ...