Try Tuts+ Premium, Get Cash Back!
Quick Tip: A Workaround for Hard Cropping Featured Images

Quick Tip: A Workaround for Hard Cropping Featured Images

This quick tip explains how to add a Custom Column in the Manage Screens of your WordPress blog.


Recently, I found myself needing to start using featured images instead of timthumb.php for the first time. Everything was great except that I found it really annoying that I was unable to specify exactly what size an image should be (hard-crop).

After looking around for a while, I found that most people’s solution was to use a plugin which ended up having an excessive amount of code in it.

Additionally, I wanted to be able to serve a responsive layout using the Skeleton grid system class of “scale-with-grid” – the original reason for using featured images which doesn’t require a front end width and height attribute.

Here’s the workaround that I came up with given the requirements of the project.


Step 1 Apply an Arbitrary Class to Your Featured Post Images

We need to be able to have control over the image using our stylesheet so we need to apply a class that only affects the image itself. I chose just to wrap my image in a figure/div called ‘headline‘. That was in addition to a custom post thumbnail size that I had already set in the functions.php file called ‘huge‘ – this thumbnail size had a maximum width of 940 while the height was 900.

That’s fine assuming you want an image with a height of 900px – but let’s face it: you probably don’t because it looks like this:

Here’s the code I wrote for the template:

	<figure id="headline">
		<?php the_post_thumbnail('huge', array('class' => 'scale-with-grid')); ?>
	</figure>

Step 2 A Little Bit of CSS Hackery

	#headline {
		max-height: 400px;
		overflow: hidden;
	}

And after we’ve added that code we get the following result which is much more manageable:


Why It Works

This works because we only set a maximum-height and not a maximum-width. WordPress defaults to the maximum width which we set via our function:

	add_action( 'init', 'my_register_image_sizes' );

	function my_register_image_sizes() {
		add_image_size( 'huge', 940,900, true );
	}

The image is technically still all there in its full size but we caused the browser to hide anything over the height of 400px by using the overflow: hidden attribute.

It works!


Just One Problem Though…

While it looks good, we’re actually hacking wildly at our browser here. Remember that the image only looks as if it has resized – as we’ve already said the image is still there in full.

That means that despite it looking great all the way down to mobile, it’s actually taking up kind of a lot of space.

Does anyone have a better solution? Leave your ideas in the comments below!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://omgcarlos.com OMGCarlos

    Nice tip Marc! I usually like to go a step further with this and compensate for images that are too small. The easiest way to do this would be auto-center images and add a class .fill-headline to the image, which

    #headline { text-align: center; }
    .fill-headline{ max-width: 100%; }

    When you apply .fill-headline to the image, it will automatically stretch the image to fill in the header. If you want to get jiggy with it – or you’re coding for the unpredictable client, you can take it a step further and only apply this class only if the image is AT LEAST a certain width. This will prevent really tiny images from stretching up and looking crazy pixelated:

    <?php
    /*===============================================
    | Compensate for smaller images (stretch or center)
    =================================================*/
    $thumbData = wp_get_attachment_image_src( get_post_thumbnail_id(), 'thumbnail' );
    $thumbWidth = $thumbData[1]; //Thumbnails Width. [0] = url, [2] = height

    if($thumbWidth ‘scale-with-grid’)); //Only apply image centering
    } else { the_post_thumbnail(‘huge’, array(‘class’ => ‘scale-with-grid fill-headline’)); } //Center and stretch
    ?>

    (I typed this inside the browser, so it might not work as is. But you get the idea)

  • http://www.davidhill.ie David Hill

    I don’t understand why you’re doing this..

    specifying a value of true to the add_image_size() function makes WordPress crop the image..

    add_image_size( $name, $width, $height, true );

  • Mike McLin

    Maybe I don’t get it? Why don’t you create another custom thumbnail size called ‘headline’ or something, and use that image? Then you don’t need to do any fake cropping with CSS, plus you only load the pixels of the image that you actually use, instead of loading a huge image, and hiding half of it with CSS.

    Everything you did on the client side with CSS, could’ve been done on the server side with WordPress, and been more efficient for page load times, etc.

    • Marc Thomas
      Author

      Mike,

      WordPress doesn’t actually allow you to do that. It will go with whichever dimension fits the space first. For example, for the featured post image to fill a 940px space (as above) the landscape height needs to be about 900ish (I’m guessing that figure).

      That’s obviously no good. Unfortunately, WordPress doesn’t have the same cropping functionality as timthumb.php which is why I came up with this instead.

      Like I said, “While it looks good, we’re actually hacking wildly at our browser here. Remember that the image only looks as if it has resized – as we’ve already said the image is still there in full.
      That means that despite it looking great all the way down to mobile, it’s actually taking up kind of a lot of space.”

      Cheers,
      Marc

      • http://prop-14.com Randy

        “WordPress doesn’t actually allow you to do that. It will go with whichever dimension fits the space first.”

        I do not follow that at all? WordPress uses the image size that you code it to use. It makes no assumptions?

        Also, you don’t need add_image_size as an init function. I have to agree with Mike, why not just make the correct crop size for the space? I must be missing something as well. Sorry.

      • http://www.blackpenpress.co.uk Tom

        I think you’ve missed something Marc, you can create as many new thumbnail sizes as you need and set to zoom crop, then just echo out the thumbnail size. I use this all the time. It’s all easily doable with WordPress.

      • http://www.cirkut.net/ Josh Allen

        I think what Mike means is that you can just hardcode a size like you did with ‘huge’. Create a size called ‘headline’ and change that to 940×400. I’ll agree on your half with what you’re trying to accomplish.

        Mike, Marc is trying to say if you create a size like that, it will create an image that is proportional to 940×400. Lets say you resized the page down to 470px wide. More of the image would show in this case because the max-height of the container is 400px.

        940×900 is equivalent to 470×450. Therefore, Marc’s example image would only have 50px cut off from the bottom using the example here, while Mike’s example would have dimensions equaling 470×200 (and therefore reducing the entire height of the containing element to 200px).

        So while this is a hack-ish solution instead of using timthumb, it’s not as graceful, but a bit more efficient with a few downfalls.

        Great tip Marc!

      • Mike McLin

        So no matter what you always want the max height to be 400px. Now, I understand.

        However, the main reason the 400px max height was put in place was because we didn’t want the picture to take up the full screen. Now, that is exactly what we get when viewing on a mobile device (400px will take up almost all if not all of the screen in both landscape and portrait modes of nearly every single phone).

        If the goal is to be responsive, why deem something undesirable for desktop, but allow it for mobile?

      • http://www.blackpenpress.co.uk Tom

        I still don’t see why you can’t use add_image_size( ‘theme-custom-size’, 900, 400, true ); the true sets the image to crop

    • Erik

      I agree with the above. This ‘works’ if the focal point of the image is in the upper 500px of the image. If its in the middle of the image or the lower half, it no longer ‘works’ and the result will not look very good. You would then have to manually crop the image (I find this is usually the case), so then you might as well specify and additional image size for your headline image and let WordPress handle it.

    • http://sarahtebo.com Sarah

      I agree. I’ve done several themes that use multiple custom thumbnail sizes, all cropped to specific dimensions. It works great, and I never have to use timthumb.

  • http://maorchasen.com Maor Chasen

    Great write-up, Marc! There’s a plugin/library I ran into lately, which is an alternative for WordPress’ native thumbnail API. It’s called WPThumb.

    An on-demand image generation replacement for WordPress’ image resizing.

    You might want to check it out.

    • El garch

      Why you didn’t host it in wordpress.org ?

      • http://wpconsult.net PauldeWouters

        it’s not a plugin, it’s a library.

  • http://www.wordpressguru.com.au Wordpress Developer

    I would prefer to customize the image in the photoshop and upload that as a featured image. What if the portion of the image you want to show gets hidden by overflow:hidden property. And also loading the bigger image will take more time.

    Saying so, the above tip is quiet helpful too.

  • http://www.radiumthemes.com frank

    Awesome tip, personally I use https://github.com/sy4mil/Aqua-Resizer. I’ve found it to be very flexible and easy to use. The only thing lacking as far as I can tell is image caching. It uses the built-in WordPress resizer which is a huge plus.

  • http://surefirewebservices.com Jonathan

    Well I can definitely relate to the frustration. As a designer, sometimes I want my images to be a certain fixed size throughout the theme.

    I haven’t found a good solution except for timthumb BUT I’ll definitely be looking into wpthumb and aqua to see how those work.