3

On my search results page I have 2 posts per row (col-md-6). The grid works fine and everything is aligned correctly, except when the excerpt or the post title is longer than the other excerpts or post titles. On my test site I have all of the titles and excerpts of my posts 1 line, and than I have 1 post that has a post title of one line and an excerpt of two lines. Since the excerpt is two lines it messes with the alignment of the rest of the posts. How could I fix this issue so that all posts no matter the length of the excerpt are aligned correctly?

When the excerpts and post titles are the same length everything is aligned enter image description here

When the excerpt is longer it screws up the alignment enter image description here

I'm attaching all my php files that go along with my search page. However, the main file is list-search-template.php (the last one)

search.php

<?php get_header(); ?>
<div class="content-holder clearfix">
    <div class="container">
    <div class="search-results-search">
<form role="search" method="get" class="search-form-search form-inline-search" action="">
            <div class="input-group-search">
                <input type="search" value="" name="s" class="input-sm-search search-field-search form-control-search" placeholder="<?php echo $s ?>">
            </div>
        </form>
    </div>
                <div class="row">
                    <div class="col-md-12" >
                        <div class="grid js-masonry ajax-container row">
                         <?php 
      get_template_part("loop/loop-search"); ?>
                    </div>
                        <?php get_template_part('post-template/post-nav'); ?>

                </div>
    </div>
</div>
<footer class="footer">
<?php get_template_part('wrapper/wrapper-footer'); ?>
</footer>
<?php get_footer(); ?>

loop-search.php

<?php /* Loop Name: Loop list-posts blog */ ?>
<?php 
  if (have_posts()) : 
  while (have_posts()) : the_post();
  ?>
<div id="post-<?php the_ID(); ?>" class="post-list_h ajax-post-wrapper block col-xs-12 col-sm-6 col-md-6" > 
<?php 
   get_template_part('post-template/list-search-template'); 
?>
</div>

<?php 
  endwhile; wp_reset_postdata(); ?>

  <?php else: ?>
  
<?php get_template_part( 'content', 'none' ); ?>

<?php endif; ?>

list-search-template.php

<?php 
/**
* Grid post template
*/
?>
<?php 

?> 
<div class="post_content">

 
<div class="post_content grid-block <?php echo esc_attr(); ?>">
    
<?php  if(has_post_thumbnail()) { ?>

    <?php

if(has_post_format('video')){
$embed = get_post_meta(get_the_ID(), 'novablog_video_embed', true);
$vimeo = strpos($embed, "vimeo");
   $youtube = strpos($embed, "youtu");
if($youtube !== false){
$video_id = str_replace( 'http://', '', $embed );
    $video_id = str_replace( 'https://', '', $video_id );
       $video_id = str_replace( 'www.youtube.com/watch?v=', '', $video_id );
       $video_id = str_replace( 'youtube.com/watch?v=', '', $video_id );
       $video_id = str_replace( 'youtu.be/', '', $video_id );
       $video_id = str_replace( '&feature=channel', '', $video_id );
$link = '//www.youtube.com/embed/'.esc_attr($video_id);
}
if($vimeo !== false){

       //Get ID from video url
       $video_id = str_replace( 'http://vimeo.com/', '', $embed );
       $video_id = str_replace( 'http://www.vimeo.com/', '', $video_id );
$video_id = str_replace( 'https://vimeo.com/', '', $video_id );
$link = '//player.vimeo.com/video/'.esc_attr($video_id);
}
}

?>
    
<?php if(has_post_format('video')){ ?>
<a class="popup-youtube" href="<?php echo esc_attr($link); ?>" title="<?php the_title_attribute(); ?>">
<?php if(has_post_format('video')){
echo '<div class="cover-video"></div>';
 }  ?>

<?php } ?>
    
                    <div class="two-front-container">
                        <a title="<?php the_title_attribute(); ?>" href="<?php the_permalink(); ?>"><?php the_post_thumbnail('full', array('class' => 'medium-front-thumbnail')); ?></a>
                    </div>

<?php } ?>
</div>
                        <div>
                    <div class="front-page-date"><?php echo human_time_diff( get_the_time('U'), current_time('timestamp') ) . ' ago'; ?></div>
                    <div class="front-page-post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></div>
                            <div class="post_content"><p class="front-page-post-excerpt"><?php echo get_the_excerpt(); ?></p><div class="clear"></div></div>
                    <div class="front-page-post-info">
                        <a class="moretext" href="<?php the_permalink(); ?>">Read more</a>
                        <?php get_template_part( 'includes/front-shop-the-post' ); ?>
                        <?php get_template_part( 'includes/share-buttons' ); ?>
                        <div class="front-comments"><?php comments_popup_link ('0', '1', '%', 'comment-count', 'none'); ?></div>
                    </div>
                                                        
     </div>
</div>
user6738171
  • 1,009
  • 2
  • 15
  • 50
  • If possible do not show the excerpt, or set a min height which will cover the 2 line excerpt. – Simon Gomes Oct 30 '17 at 11:01
  • I think easier solution is limit excerpt character count into one line, if you want to keep full excerpt you can find highest height from all divs(col-md-6) then set default height of all "col-md-6" from using jquery – Casper Nov 01 '17 at 09:38

7 Answers7

1

The simplest way I've found to solve this is using a clearfix, but using Bootstrap's responsive utilities to only use the clearfix at the viewport sizes you want. You don't need to worry about opening and closing rows.

Here's a screenshot of a JSFiddle demonstration:

enter image description here

Note the JSFiddle uses http://lorempixel.com/ for images, and they can be slow to load sometimes - give it time.

To implement this in your code, simply add a $count in loop-search.php, and include the clearfix every 2nd post:

<?php /* Loop Name: Loop list-posts blog */

$count = 0;

if (have_posts()) : 
    while (have_posts()) : the_post(); 
        $count++; 
        ?>
        <div id="post-<?php the_ID(); ?>" class="post-list_h ajax-post-wrapper block col-xs-12 col-sm-6 col-md-6" > 
            <?php get_template_part('post-template/list-search-template'); ?>
        </div>

        <?php if ($count%2 === 0) { ?>
            <div class="clearfix hidden-xs hidden-sm"></div>
        <?php }
    <?php endwhile; wp_reset_postdata(); ?>

<?php else: ?>
    <?php get_template_part( 'content', 'none' ); ?>
<?php endif; ?>

The clearfix is not applied for xs and sm viewports, so only becomes effective at md and larger - which is what you want.

Note - you have js-masonry classes in your code, if you're really using Masonry.js that will probably mess things up. Maybe you were experimenting with it instead of trying to get this horizontal alignment working? If you're not using it now make sure you've removed the JS links and remove the classes to avoid confusion.

Don't Panic
  • 13,965
  • 5
  • 32
  • 51
  • Would you mind placing the rest of my code into the loop-serach.php? I tried, and I got an error, so I might have added it in wrong. – user6738171 Nov 05 '17 at 14:48
  • @user6738171 OK, done. I reformatted a bit for readability. Let me know the error if it persists. – Don't Panic Nov 05 '17 at 14:55
  • There still is an error, none of the posts appear on the page, and my nav bar is a bit messed up. The pre-made theme I'm using must use masonry.js, and it's messing things up. Thanks for your help anyways. – user6738171 Nov 05 '17 at 14:58
  • @user6738171 The code I've added won't cause that - comment it out to confirm. But if Masonry.js is involved, none of this will work - Masonry's whole point is to realign things counter to what we're trying to do here. – Don't Panic Nov 05 '17 at 15:02
0

Since you're keeping them all in the same row, there's no clearfix. Since you have widths of either 12 or 6 (full or half) you could close (and reopen) a new row every other post. In the cases where it's a small screen, the side by side height won't matter since each post will be on its own line anyway.

    <?php /* Loop Name: Loop list-posts blog */ ?>
    <?php 
         if (have_posts()) : 
         $postCount = 0; // Initialize counter
         while (have_posts()) : the_post();
         $postCount++; // Increment counter
         ?>
    <div id="post-<?php the_ID(); ?>" class="post-list_h ajax-post-wrapper block col-xs-12 col-sm-6 col-md-6" > 
    <?php 
       get_template_part('post-template/list-search-template'); 
    ?>
    </div>

    <?php 
     // Print row if needed
     if($postCount % 2 == 0):
?>
     </div><div class="grid js-masonry ajax-container row">
<?php
      endif;
            endwhile; wp_reset_postdata(); ?>

            <?php else: ?>

    <?php get_template_part( 'content', 'none' ); ?>

    <?php endif; ?>

<!-- end snippet -->
kchason
  • 2,836
  • 19
  • 25
  • This code is producing an error. Between each row of 2 posts about 30 load more buttons appear (so theres about 100 load more buttons on my page). Do you have any idea why this is happening? – user6738171 Oct 26 '17 at 17:44
  • I don't, especially without having a copy of the entire theme to work through, perhaps there's logic for one of the classes that adds those buttons. You could try just a simple `
    ` and see what that does, but I suspect the styles will be inconsistent with the first row.
    – kchason Oct 26 '17 at 17:46
0

The following code will help you to properly add row after every 2 columns.

    <?php /* Loop Name: Loop list-posts blog */ ?>
<?php 
if (have_posts()) : 
    $counter  = 0;
    while (have_posts()) : the_post();
        $post_count = $GLOBALS['wp_query']->post_count;

?>
<?php if($counter++%2==0){ ?>
<div class="row">
<?php } ?>
    <div id="post-<?php the_ID(); ?>" class="post-list_h ajax-post-wrapper block col-xs-12 col-sm-6 col-md-6" >
    <?php
        get_template_part('post-template/list-search-template'); 
    ?>
    </div>
<?php if($counter%2==0 || $counter == $post_count){ ?>
</div>
<?php } ?>
<?php
    endwhile; wp_reset_postdata(); ?>

<?php else: ?>

<?php get_template_part( 'content', 'none' ); ?>

<?php endif; ?>

I think the issue with load more button will be because of lack of div closing tag.

Rijo
  • 2,568
  • 1
  • 22
  • 30
0

There is a very easy solution. You need to follow 2 steps.

  1. Remove <div class="grid js-masonry ajax-container row"> from "search.php".

  2. Edit "loop-search.php" with the below code:

    <?php /* Loop Name: Loop list-posts blog */ ?>
    <?php 
    if (have_posts()) : 
    $cnt = 1;
    $endRow = false;
    while (have_posts()) : the_post();
    ?>
    <?php 
    if($cnt%2 != 0){
    $endRow = true; 
    ?>
    <div class="grid js-masonry ajax-container row">
    <?php } ?>
    <div id="post-<?php the_ID(); ?>" class="post-list_h ajax-post-wrapper block col-xs-12 col-sm-6 col-md-6" > 
    <?php get_template_part('post-template/list-search-template');  ?>
    </div>
    <?php 
    if($cnt%2 == 0){        
    $endRow = false;
    ?>
    </div>
    <?php } ?>
    <?php 
    $cnt++; 
    endwhile; wp_reset_postdata(); ?>
    <?php else: ?>
    <?php get_template_part( 'content', 'none' ); ?>
    <?php endif; ?>
    
0

The proper workaround for this issue is to use css property display:flex see fiddle

But in your case you are using bootstrap i think, what you can do is to get the highest height of the div and apply it to all div using jquery eg:

jQuery(document).ready(function($){
    var $divs = $('.row > div');
    var highest = [];

  $.each($divs, function($index, $item) {
    highest.push($($item).height()); // Push all divs height into array
  })

  function compareNumbers(a, b) {
     return b - a;
  }

  //console.log();
  highest = highest.sort(compareNumbers); // sort Array

  $('.row > div').height(highest[0]) // Apply the highest height to all divs

});

See live demo here

Touqeer Shafi
  • 5,084
  • 3
  • 28
  • 45
0

Perhaps you could force having 1 line titles and excerpts. Check the example below.

.caption h3, .caption p {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="row">
    <div class="col-md-6">
      <div class="thumbnail">
        <img src="http://i68.tinypic.com/161z3fc.jpg" alt="" width="" height="">
        <div class="caption">
          <h3 title="Card 1 is not like the rest cards. It's title is longer than the others.">Card 1 is not like the rest cards. It's title is longer than the others.</h3>
          <p>Short excerpt</p>
        </div>
      </div>
    </div>

    <div class="col-md-6">
      <div class="thumbnail">
        <img src="http://i68.tinypic.com/161z3fc.jpg" alt="" width="" height="">
        <div class="caption">
          <h3 title="Card 2">Card 2</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure dolor in reprehenderit in voluptate velit esse</p>
        </div>
      </div>
    </div>


    <div class="col-md-6">
      <div class="thumbnail">
        <img src="http://i68.tinypic.com/161z3fc.jpg" alt="" width="" height="">
        <div class="caption">
          <h3 title="Card 3">Card 3</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </div>
      </div>
    </div>

    <div class="col-md-6">
      <div class="thumbnail">
        <img src="http://i68.tinypic.com/161z3fc.jpg" alt="" width="" height="">
        <div class="caption">
          <h3 title="Card 4">Card 4</h3>
          <p>Another short excerpt</p>
        </div>
      </div>
    </div>
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

EDIT If you choose to force having one line only, card Titles and excerpts, then try adding also title attribute in card titles. For example.

<h3 title="Card 1 is not like the rest cards. It's title is longer than the others.">Card 1 is not like the rest cards. It's title is longer than the others.</h3>
0

Give excerpt a fixed height using css. Then if the text is available or not. It would take that height.

Aaqib Mehran
  • 41
  • 1
  • 6