user6738171
user6738171

Reputation: 1017

Bootstrap grid is not correctly aligning

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>

Upvotes: 3

Views: 1322

Answers (7)

Don&#39;t Panic
Don&#39;t Panic

Reputation: 14520

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.

Upvotes: 1

user2560539
user2560539

Reputation:

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>

Upvotes: 0

Aaqib Mehran
Aaqib Mehran

Reputation: 41

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

Upvotes: 0

Touqeer Shafi
Touqeer Shafi

Reputation: 5284

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

Upvotes: 0

MD. Shafayatul Haque
MD. Shafayatul Haque

Reputation: 998

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; ?>
    

Upvotes: 0

Rijo
Rijo

Reputation: 2718

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.

Upvotes: 0

kchason
kchason

Reputation: 2885

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 -->

Upvotes: 0

Related Questions